]> Git Repo - VerusCoin.git/blob - src/main.cpp
mining performance boost
[VerusCoin.git] / src / main.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "main.h"
7
8 #include "sodium.h"
9
10 #include "addrman.h"
11 #include "alert.h"
12 #include "arith_uint256.h"
13 #include "chainparams.h"
14 #include "checkpoints.h"
15 #include "checkqueue.h"
16 #include "consensus/upgrades.h"
17 #include "consensus/validation.h"
18 #include "deprecation.h"
19 #include "init.h"
20 #include "merkleblock.h"
21 #include "metrics.h"
22 #include "net.h"
23 #include "pow.h"
24 #include "txdb.h"
25 #include "txmempool.h"
26 #include "ui_interface.h"
27 #include "undo.h"
28 #include "util.h"
29 #include "utilmoneystr.h"
30 #include "validationinterface.h"
31 #include "wallet/asyncrpcoperation_sendmany.h"
32 #include "wallet/asyncrpcoperation_shieldcoinbase.h"
33
34 #include <cstring>
35 #include <sstream>
36 #include <unordered_map>
37
38 #include <boost/algorithm/string/replace.hpp>
39 #include <boost/filesystem.hpp>
40 #include <boost/filesystem/fstream.hpp>
41 #include <boost/math/distributions/poisson.hpp>
42 #include <boost/thread.hpp>
43 #include <boost/static_assert.hpp>
44
45 using namespace std;
46
47 #if defined(NDEBUG)
48 # error "Zcash cannot be compiled without assertions."
49 #endif
50
51
52 /**
53  * Global state
54  */
55
56 CCriticalSection cs_main;
57 extern uint8_t NOTARY_PUBKEY33[33];
58 extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN;
59 int32_t KOMODO_NEWBLOCKS;
60 int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
61 void komodo_broadcast(CBlock *pblock,int32_t limit);
62
63 BlockMap mapBlockIndex;
64 CChain chainActive;
65 CBlockIndex *pindexBestHeader = NULL;
66 int64_t nTimeBestReceived = 0;
67 CWaitableCriticalSection csBestBlock;
68 CConditionVariable cvBlockChange;
69 int nScriptCheckThreads = 0;
70 bool fExperimentalMode = false;
71 bool fImporting = false;
72 bool fReindex = false;
73 bool fTxIndex = false;
74 bool fAddressIndex = false;
75 bool fTimestampIndex = false;
76 bool fSpentIndex = false;
77 bool fHavePruned = false;
78 bool fPruneMode = false;
79 bool fIsBareMultisigStd = true;
80 bool fCheckBlockIndex = false;
81 bool fCheckpointsEnabled = true;
82 bool fCoinbaseEnforcedProtectionEnabled = true;
83 size_t nCoinCacheUsage = 5000 * 300;
84 uint64_t nPruneTarget = 0;
85 bool fAlerts = DEFAULT_ALERTS;
86
87 unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
88
89 /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
90 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
91
92 CTxMemPool mempool(::minRelayTxFee);
93
94 struct COrphanTx {
95     CTransaction tx;
96     NodeId fromPeer;
97 };
98 map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
99 map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
100 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
101
102 /**
103  * Returns true if there are nRequired or more blocks of minVersion or above
104  * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
105  */
106 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
107 static void CheckBlockIndex();
108
109 /** Constant stuff for coinbase transactions we create: */
110 CScript COINBASE_FLAGS;
111
112 const string strMessageMagic = "Komodo Signed Message:\n";
113
114 // Internal stuff
115 namespace {
116     
117     struct CBlockIndexWorkComparator
118     {
119         bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
120             // First sort by most total work, ...
121             if (pa->nChainWork > pb->nChainWork) return false;
122             if (pa->nChainWork < pb->nChainWork) return true;
123             
124             // ... then by earliest time received, ...
125             if (pa->nSequenceId < pb->nSequenceId) return false;
126             if (pa->nSequenceId > pb->nSequenceId) return true;
127             
128             // Use pointer address as tie breaker (should only happen with blocks
129             // loaded from disk, as those all have id 0).
130             if (pa < pb) return false;
131             if (pa > pb) return true;
132             
133             // Identical blocks.
134             return false;
135         }
136     };
137     
138     CBlockIndex *pindexBestInvalid;
139     
140     /**
141      * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
142      * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
143      * missing the data for the block.
144      */
145     set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
146     /** Number of nodes with fSyncStarted. */
147     int nSyncStarted = 0;
148     /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
149      * Pruned nodes may have entries where B is missing data.
150      */
151     multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
152     
153     CCriticalSection cs_LastBlockFile;
154     std::vector<CBlockFileInfo> vinfoBlockFile;
155     int nLastBlockFile = 0;
156     /** Global flag to indicate we should check to see if there are
157      *  block/undo files that should be deleted.  Set on startup
158      *  or if we allocate more file space when we're in prune mode
159      */
160     bool fCheckForPruning = false;
161     
162     /**
163      * Every received block is assigned a unique and increasing identifier, so we
164      * know which one to give priority in case of a fork.
165      */
166     CCriticalSection cs_nBlockSequenceId;
167     /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
168     uint32_t nBlockSequenceId = 1;
169     
170     /**
171      * Sources of received blocks, saved to be able to send them reject
172      * messages or ban them when processing happens afterwards. Protected by
173      * cs_main.
174      */
175     map<uint256, NodeId> mapBlockSource;
176     
177     /**
178      * Filter for transactions that were recently rejected by
179      * AcceptToMemoryPool. These are not rerequested until the chain tip
180      * changes, at which point the entire filter is reset. Protected by
181      * cs_main.
182      *
183      * Without this filter we'd be re-requesting txs from each of our peers,
184      * increasing bandwidth consumption considerably. For instance, with 100
185      * peers, half of which relay a tx we don't accept, that might be a 50x
186      * bandwidth increase. A flooding attacker attempting to roll-over the
187      * filter using minimum-sized, 60byte, transactions might manage to send
188      * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
189      * two minute window to send invs to us.
190      *
191      * Decreasing the false positive rate is fairly cheap, so we pick one in a
192      * million to make it highly unlikely for users to have issues with this
193      * filter.
194      *
195      * Memory used: 1.7MB
196      */
197     boost::scoped_ptr<CRollingBloomFilter> recentRejects;
198     uint256 hashRecentRejectsChainTip;
199     
200     /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
201     struct QueuedBlock {
202         uint256 hash;
203         CBlockIndex *pindex;  //! Optional.
204         int64_t nTime;  //! Time of "getdata" request in microseconds.
205         bool fValidatedHeaders;  //! Whether this block has validated headers at the time of request.
206         int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
207     };
208     map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
209     
210     /** Number of blocks in flight with validated headers. */
211     int nQueuedValidatedHeaders = 0;
212     
213     /** Number of preferable block download peers. */
214     int nPreferredDownload = 0;
215     
216     /** Dirty block index entries. */
217     set<CBlockIndex*> setDirtyBlockIndex;
218     
219     /** Dirty block file entries. */
220     set<int> setDirtyFileInfo;
221 } // anon namespace
222
223 //////////////////////////////////////////////////////////////////////////////
224 //
225 // Registration of network node signals.
226 //
227
228 namespace {
229     
230     struct CBlockReject {
231         unsigned char chRejectCode;
232         string strRejectReason;
233         uint256 hashBlock;
234     };
235     
236     /**
237      * Maintain validation-specific state about nodes, protected by cs_main, instead
238      * by CNode's own locks. This simplifies asynchronous operation, where
239      * processing of incoming data is done after the ProcessMessage call returns,
240      * and we're no longer holding the node's locks.
241      */
242     struct CNodeState {
243         //! The peer's address
244         CService address;
245         //! Whether we have a fully established connection.
246         bool fCurrentlyConnected;
247         //! Accumulated misbehaviour score for this peer.
248         int nMisbehavior;
249         //! Whether this peer should be disconnected and banned (unless whitelisted).
250         bool fShouldBan;
251         //! String name of this peer (debugging/logging purposes).
252         std::string name;
253         //! List of asynchronously-determined block rejections to notify this peer about.
254         std::vector<CBlockReject> rejects;
255         //! The best known block we know this peer has announced.
256         CBlockIndex *pindexBestKnownBlock;
257         //! The hash of the last unknown block this peer has announced.
258         uint256 hashLastUnknownBlock;
259         //! The last full block we both have.
260         CBlockIndex *pindexLastCommonBlock;
261         //! Whether we've started headers synchronization with this peer.
262         bool fSyncStarted;
263         //! Since when we're stalling block download progress (in microseconds), or 0.
264         int64_t nStallingSince;
265         list<QueuedBlock> vBlocksInFlight;
266         int nBlocksInFlight;
267         int nBlocksInFlightValidHeaders;
268         //! Whether we consider this a preferred download peer.
269         bool fPreferredDownload;
270         
271         CNodeState() {
272             fCurrentlyConnected = false;
273             nMisbehavior = 0;
274             fShouldBan = false;
275             pindexBestKnownBlock = NULL;
276             hashLastUnknownBlock.SetNull();
277             pindexLastCommonBlock = NULL;
278             fSyncStarted = false;
279             nStallingSince = 0;
280             nBlocksInFlight = 0;
281             nBlocksInFlightValidHeaders = 0;
282             fPreferredDownload = false;
283         }
284     };
285     
286     /** Map maintaining per-node state. Requires cs_main. */
287     map<NodeId, CNodeState> mapNodeState;
288     
289     // Requires cs_main.
290     CNodeState *State(NodeId pnode) {
291         map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
292         if (it == mapNodeState.end())
293             return NULL;
294         return &it->second;
295     }
296     
297     int GetHeight()
298     {
299         LOCK(cs_main);
300         return chainActive.Height();
301     }
302     
303     void UpdatePreferredDownload(CNode* node, CNodeState* state)
304     {
305         nPreferredDownload -= state->fPreferredDownload;
306         
307         // Whether this node should be marked as a preferred download node.
308         state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
309         
310         nPreferredDownload += state->fPreferredDownload;
311     }
312     
313     // Returns time at which to timeout block request (nTime in microseconds)
314     int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
315     {
316         return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
317     }
318     
319     void InitializeNode(NodeId nodeid, const CNode *pnode) {
320         LOCK(cs_main);
321         CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
322         state.name = pnode->addrName;
323         state.address = pnode->addr;
324     }
325     
326     void FinalizeNode(NodeId nodeid) {
327         LOCK(cs_main);
328         CNodeState *state = State(nodeid);
329         
330         if (state->fSyncStarted)
331             nSyncStarted--;
332         
333         if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
334             AddressCurrentlyConnected(state->address);
335         }
336         
337         BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
338         mapBlocksInFlight.erase(entry.hash);
339         EraseOrphansFor(nodeid);
340         nPreferredDownload -= state->fPreferredDownload;
341         
342         mapNodeState.erase(nodeid);
343     }
344     
345     void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
346     {
347         /*    int expired = pool.Expire(GetTime() - age);
348          if (expired != 0)
349          LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
350          
351          std::vector<uint256> vNoSpendsRemaining;
352          pool.TrimToSize(limit, &vNoSpendsRemaining);
353          BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
354          pcoinsTip->Uncache(removed);*/
355     }
356     
357     // Requires cs_main.
358     // Returns a bool indicating whether we requested this block.
359     bool MarkBlockAsReceived(const uint256& hash) {
360         map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
361         if (itInFlight != mapBlocksInFlight.end()) {
362             CNodeState *state = State(itInFlight->second.first);
363             nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
364             state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
365             state->vBlocksInFlight.erase(itInFlight->second.second);
366             state->nBlocksInFlight--;
367             state->nStallingSince = 0;
368             mapBlocksInFlight.erase(itInFlight);
369             return true;
370         }
371         return false;
372     }
373     
374     // Requires cs_main.
375     void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
376         CNodeState *state = State(nodeid);
377         assert(state != NULL);
378         
379         // Make sure it's not listed somewhere already.
380         MarkBlockAsReceived(hash);
381         
382         int64_t nNow = GetTimeMicros();
383         QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
384         nQueuedValidatedHeaders += newentry.fValidatedHeaders;
385         list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
386         state->nBlocksInFlight++;
387         state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
388         mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
389     }
390     
391     /** Check whether the last unknown block a peer advertized is not yet known. */
392     void ProcessBlockAvailability(NodeId nodeid) {
393         CNodeState *state = State(nodeid);
394         assert(state != NULL);
395         
396         if (!state->hashLastUnknownBlock.IsNull()) {
397             BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
398             if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0)
399             {
400                 if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
401                     state->pindexBestKnownBlock = itOld->second;
402                 state->hashLastUnknownBlock.SetNull();
403             }
404         }
405     }
406     
407     /** Update tracking information about which blocks a peer is assumed to have. */
408     void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
409         CNodeState *state = State(nodeid);
410         assert(state != NULL);
411         
412         /*ProcessBlockAvailability(nodeid);
413          
414          BlockMap::iterator it = mapBlockIndex.find(hash);
415          if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
416          // An actually better block was announced.
417          if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
418          state->pindexBestKnownBlock = it->second;
419          } else*/
420         {
421             // An unknown block was announced; just assume that the latest one is the best one.
422             state->hashLastUnknownBlock = hash;
423         }
424     }
425     
426     /** Find the last common ancestor two blocks have.
427      *  Both pa and pb must be non-NULL. */
428     CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
429         if (pa->nHeight > pb->nHeight) {
430             pa = pa->GetAncestor(pb->nHeight);
431         } else if (pb->nHeight > pa->nHeight) {
432             pb = pb->GetAncestor(pa->nHeight);
433         }
434         
435         while (pa != pb && pa && pb) {
436             pa = pa->pprev;
437             pb = pb->pprev;
438         }
439         
440         // Eventually all chain branches meet at the genesis block.
441         assert(pa == pb);
442         return pa;
443     }
444     
445     /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
446      *  at most count entries. */
447     void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
448         if (count == 0)
449             return;
450         
451         vBlocks.reserve(vBlocks.size() + count);
452         CNodeState *state = State(nodeid);
453         assert(state != NULL);
454         
455         // Make sure pindexBestKnownBlock is up to date, we'll need it.
456         ProcessBlockAvailability(nodeid);
457         
458         if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
459             // This peer has nothing interesting.
460             return;
461         }
462         
463         if (state->pindexLastCommonBlock == NULL) {
464             // Bootstrap quickly by guessing a parent of our best tip is the forking point.
465             // Guessing wrong in either direction is not a problem.
466             state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
467         }
468         
469         // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
470         // of its current tip anymore. Go back enough to fix that.
471         state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
472         if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
473             return;
474         
475         std::vector<CBlockIndex*> vToFetch;
476         CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
477         // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
478         // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
479         // download that next block if the window were 1 larger.
480         int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
481         int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
482         NodeId waitingfor = -1;
483         while (pindexWalk->nHeight < nMaxHeight) {
484             // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
485             // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
486             // as iterating over ~100 CBlockIndex* entries anyway.
487             int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
488             vToFetch.resize(nToFetch);
489             pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
490             vToFetch[nToFetch - 1] = pindexWalk;
491             for (unsigned int i = nToFetch - 1; i > 0; i--) {
492                 vToFetch[i - 1] = vToFetch[i]->pprev;
493             }
494             
495             // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
496             // are not yet downloaded and not in flight to vBlocks. In the meantime, update
497             // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
498             // already part of our chain (and therefore don't need it even if pruned).
499             BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
500                 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
501                     // We consider the chain that this peer is on invalid.
502                     return;
503                 }
504                 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
505                     if (pindex->nChainTx)
506                         state->pindexLastCommonBlock = pindex;
507                 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
508                     // The block is not already downloaded, and not yet in flight.
509                     if (pindex->nHeight > nWindowEnd) {
510                         // We reached the end of the window.
511                         if (vBlocks.size() == 0 && waitingfor != nodeid) {
512                             // We aren't able to fetch anything, but we would be if the download window was one larger.
513                             nodeStaller = waitingfor;
514                         }
515                         return;
516                     }
517                     vBlocks.push_back(pindex);
518                     if (vBlocks.size() == count) {
519                         return;
520                     }
521                 } else if (waitingfor == -1) {
522                     // This is the first already-in-flight block.
523                     waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
524                 }
525             }
526         }
527     }
528     
529 } // anon namespace
530
531 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
532     LOCK(cs_main);
533     CNodeState *state = State(nodeid);
534     if (state == NULL)
535         return false;
536     stats.nMisbehavior = state->nMisbehavior;
537     stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
538     stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
539     BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
540         if (queue.pindex)
541             stats.vHeightInFlight.push_back(queue.pindex->nHeight);
542     }
543     return true;
544 }
545
546 void RegisterNodeSignals(CNodeSignals& nodeSignals)
547 {
548     nodeSignals.GetHeight.connect(&GetHeight);
549     nodeSignals.ProcessMessages.connect(&ProcessMessages);
550     nodeSignals.SendMessages.connect(&SendMessages);
551     nodeSignals.InitializeNode.connect(&InitializeNode);
552     nodeSignals.FinalizeNode.connect(&FinalizeNode);
553 }
554
555 void UnregisterNodeSignals(CNodeSignals& nodeSignals)
556 {
557     nodeSignals.GetHeight.disconnect(&GetHeight);
558     nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
559     nodeSignals.SendMessages.disconnect(&SendMessages);
560     nodeSignals.InitializeNode.disconnect(&InitializeNode);
561     nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
562 }
563
564 CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
565 {
566     // Find the first block the caller has in the main chain
567     BOOST_FOREACH(const uint256& hash, locator.vHave) {
568         BlockMap::iterator mi = mapBlockIndex.find(hash);
569         if (mi != mapBlockIndex.end())
570         {
571             CBlockIndex* pindex = (*mi).second;
572             if (pindex != 0 && chain.Contains(pindex))
573                 return pindex;
574             if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
575                 return chain.Tip();
576             }
577         }
578     }
579     return chain.Genesis();
580 }
581
582 CCoinsViewCache *pcoinsTip = NULL;
583 CBlockTreeDB *pblocktree = NULL;
584
585 // Komodo globals
586
587 #define KOMODO_ZCASH
588 #include "komodo.h"
589
590 //////////////////////////////////////////////////////////////////////////////
591 //
592 // mapOrphanTransactions
593 //
594
595 bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
596 {
597     uint256 hash = tx.GetHash();
598     if (mapOrphanTransactions.count(hash))
599         return false;
600     
601     // Ignore big transactions, to avoid a
602     // send-big-orphans memory exhaustion attack. If a peer has a legitimate
603     // large transaction with a missing parent then we assume
604     // it will rebroadcast it later, after the parent transaction(s)
605     // have been mined or received.
606     // 10,000 orphans, each of which is at most 5,000 bytes big is
607     // at most 500 megabytes of orphans:
608     unsigned int sz = tx.GetSerializeSize(SER_NETWORK, tx.nVersion);
609     if (sz > 5000)
610     {
611         LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
612         return false;
613     }
614     
615     mapOrphanTransactions[hash].tx = tx;
616     mapOrphanTransactions[hash].fromPeer = peer;
617     BOOST_FOREACH(const CTxIn& txin, tx.vin)
618     mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
619     
620     LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
621              mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
622     return true;
623 }
624
625 void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
626 {
627     map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
628     if (it == mapOrphanTransactions.end())
629         return;
630     BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
631     {
632         map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
633         if (itPrev == mapOrphanTransactionsByPrev.end())
634             continue;
635         itPrev->second.erase(hash);
636         if (itPrev->second.empty())
637             mapOrphanTransactionsByPrev.erase(itPrev);
638     }
639     mapOrphanTransactions.erase(it);
640 }
641
642 void EraseOrphansFor(NodeId peer)
643 {
644     int nErased = 0;
645     map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
646     while (iter != mapOrphanTransactions.end())
647     {
648         map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
649         if (maybeErase->second.fromPeer == peer)
650         {
651             EraseOrphanTx(maybeErase->second.tx.GetHash());
652             ++nErased;
653         }
654     }
655     if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
656 }
657
658
659 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
660 {
661     unsigned int nEvicted = 0;
662     while (mapOrphanTransactions.size() > nMaxOrphans)
663     {
664         // Evict a random orphan:
665         uint256 randomhash = GetRandHash();
666         map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
667         if (it == mapOrphanTransactions.end())
668             it = mapOrphanTransactions.begin();
669             EraseOrphanTx(it->first);
670             ++nEvicted;
671     }
672     return nEvicted;
673 }
674
675
676 bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
677 {
678     bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
679     
680     if (isOverwinter) {
681         // Overwinter standard rules apply
682         if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
683             reason = "overwinter-version";
684             return false;
685         }
686     } else {
687         // Sprout standard rules apply
688         if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
689             reason = "version";
690             return false;
691         }
692     }
693     
694     BOOST_FOREACH(const CTxIn& txin, tx.vin)
695     {
696         // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
697         // keys. (remember the 520 byte limit on redeemScript size) That works
698         // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
699         // bytes of scriptSig, which we round off to 1650 bytes for some minor
700         // future-proofing. That's also enough to spend a 20-of-20
701         // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
702         // considered standard)
703         if (txin.scriptSig.size() > 1650) {
704             reason = "scriptsig-size";
705             return false;
706         }
707         if (!txin.scriptSig.IsPushOnly()) {
708             reason = "scriptsig-not-pushonly";
709             return false;
710         }
711     }
712     
713     unsigned int v=0,nDataOut = 0;
714     txnouttype whichType;
715     BOOST_FOREACH(const CTxOut& txout, tx.vout)
716     {
717         if (!::IsStandard(txout.scriptPubKey, whichType))
718         {
719             reason = "scriptpubkey";
720             fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
721             return false;
722         }
723         
724         if (whichType == TX_NULL_DATA)
725         {
726             nDataOut++;
727             //fprintf(stderr,"is OP_RETURN\n");
728         }
729         else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
730             reason = "bare-multisig";
731             return false;
732         } else if (txout.IsDust(::minRelayTxFee)) {
733             reason = "dust";
734             return false;
735         }
736         v++;
737     }
738     
739     // only one OP_RETURN txout is permitted
740     if (nDataOut > 1) {
741         reason = "multi-op-return";
742         return false;
743     }
744     
745     return true;
746 }
747
748 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
749 {
750     int32_t i;
751     if (tx.nLockTime == 0)
752         return true;
753     if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
754         return true;
755     BOOST_FOREACH(const CTxIn& txin, tx.vin)
756     {
757         if ( txin.nSequence == 0xfffffffe && (((int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockTime) || ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockHeight)) )
758         {
759             
760         }
761         else if (!txin.IsFinal())
762         {
763             //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
764             return false;
765         }
766     }
767     return true;
768 }
769
770 bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
771 {
772     if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
773         return false;
774     }
775     return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
776 }
777
778 bool CheckFinalTx(const CTransaction &tx, int flags)
779 {
780     AssertLockHeld(cs_main);
781     
782     // By convention a negative value for flags indicates that the
783     // current network-enforced consensus rules should be used. In
784     // a future soft-fork scenario that would mean checking which
785     // rules would be enforced for the next block and setting the
786     // appropriate flags. At the present time no soft-forks are
787     // scheduled, so no flags are set.
788     flags = std::max(flags, 0);
789     
790     // CheckFinalTx() uses chainActive.Height()+1 to evaluate
791     // nLockTime because when IsFinalTx() is called within
792     // CBlock::AcceptBlock(), the height of the block *being*
793     // evaluated is what is used. Thus if we want to know if a
794     // transaction can be part of the *next* block, we need to call
795     // IsFinalTx() with one more than chainActive.Height().
796     const int nBlockHeight = chainActive.Height() + 1;
797     
798     // Timestamps on the other hand don't get any special treatment,
799     // because we can't know what timestamp the next block will have,
800     // and there aren't timestamp applications where it matters.
801     // However this changes once median past time-locks are enforced:
802     const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
803     ? chainActive.Tip()->GetMedianTimePast()
804     : GetAdjustedTime();
805     
806     return IsFinalTx(tx, nBlockHeight, nBlockTime);
807 }
808
809 /**
810  * Check transaction inputs to mitigate two
811  * potential denial-of-service attacks:
812  *
813  * 1. scriptSigs with extra data stuffed into them,
814  *    not consumed by scriptPubKey (or P2SH script)
815  * 2. P2SH scripts with a crazy number of expensive
816  *    CHECKSIG/CHECKMULTISIG operations
817  */
818 bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
819 {
820     if (tx.IsCoinBase())
821         return true; // Coinbases don't use vin normally
822     
823     for (unsigned int i = 0; i < tx.vin.size(); i++)
824     {
825         const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
826         
827         vector<vector<unsigned char> > vSolutions;
828         txnouttype whichType;
829         // get the scriptPubKey corresponding to this input:
830         const CScript& prevScript = prev.scriptPubKey;
831         if (!Solver(prevScript, whichType, vSolutions))
832             return false;
833         int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
834         if (nArgsExpected < 0)
835             return false;
836         
837         // Transactions with extra stuff in their scriptSigs are
838         // non-standard. Note that this EvalScript() call will
839         // be quick, because if there are any operations
840         // beside "push data" in the scriptSig
841         // IsStandardTx() will have already returned false
842         // and this method isn't called.
843         vector<vector<unsigned char> > stack;
844         if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
845             return false;
846         
847         if (whichType == TX_SCRIPTHASH)
848         {
849             if (stack.empty())
850                 return false;
851             CScript subscript(stack.back().begin(), stack.back().end());
852             vector<vector<unsigned char> > vSolutions2;
853             txnouttype whichType2;
854             if (Solver(subscript, whichType2, vSolutions2))
855             {
856                 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
857                 if (tmpExpected < 0)
858                     return false;
859                 nArgsExpected += tmpExpected;
860             }
861             else
862             {
863                 // Any other Script with less than 15 sigops OK:
864                 unsigned int sigops = subscript.GetSigOpCount(true);
865                 // ... extra data left on the stack after execution is OK, too:
866                 return (sigops <= MAX_P2SH_SIGOPS);
867             }
868         }
869         
870         if (stack.size() != (unsigned int)nArgsExpected)
871             return false;
872     }
873     
874     return true;
875 }
876
877 unsigned int GetLegacySigOpCount(const CTransaction& tx)
878 {
879     unsigned int nSigOps = 0;
880     BOOST_FOREACH(const CTxIn& txin, tx.vin)
881     {
882         nSigOps += txin.scriptSig.GetSigOpCount(false);
883     }
884     BOOST_FOREACH(const CTxOut& txout, tx.vout)
885     {
886         nSigOps += txout.scriptPubKey.GetSigOpCount(false);
887     }
888     return nSigOps;
889 }
890
891 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
892 {
893     if (tx.IsCoinBase())
894         return 0;
895     
896     unsigned int nSigOps = 0;
897     for (unsigned int i = 0; i < tx.vin.size(); i++)
898     {
899         const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
900         if (prevout.scriptPubKey.IsPayToScriptHash())
901             nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
902     }
903     return nSigOps;
904 }
905
906 /**
907  * Ensure that a coinbase transaction is structured according to the consensus rules of the
908  * chain
909  */
910 bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight)
911 {
912     // if time locks are on, ensure that this coin base is time locked exactly as it should be
913     if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) || (nHeight >= 31680) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE)
914     {
915         CScriptID scriptHash;
916
917         // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that 
918         // holds the full output script, which may include multisig, etc., but starts with 
919         // the time lock verify of the correct time lock for this block height
920         if (tx.vout.size() == 2 &&
921             CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) &&
922             tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
923             tx.vout[1].scriptPubKey.data()[0] == OP_RETURN)
924         {
925             opcodetype op;
926             std::vector<uint8_t> opretData = std::vector<uint8_t>();
927             CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
928             if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
929             {
930                 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
931                 {
932                     int64_t unlocktime;
933                     CScriptExt opretScript = CScriptExt(opretData.begin() + 1, opretData.end());
934
935                     if (CScriptID(opretScript) == scriptHash &&
936                         opretScript.IsCheckLockTimeVerify(&unlocktime) &&
937                         komodo_block_unlocktime(nHeight) == unlocktime)
938                     {
939                         return(true);
940                     }
941                 }
942             }
943         }
944         return(false);
945     }
946     return(true);
947 }
948
949 /**
950  * Check a transaction contextually against a set of consensus rules valid at a given block height.
951  *
952  * Notes:
953  * 1. AcceptToMemoryPool calls CheckTransaction and this function.
954  * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
955  *    and ContextualCheckBlock (which calls this function).
956  */
957 bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, const int nHeight, const int dosLevel)
958 {
959     bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
960     bool isSprout = !isOverwinter;
961     
962     // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
963     if (isSprout && tx.fOverwintered) {
964         return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter is not active yet"),
965                          REJECT_INVALID, "tx-overwinter-not-active");
966     }
967     
968     // If Overwinter rules apply:
969     if (isOverwinter) {
970         // Reject transactions with valid version but missing overwinter flag
971         if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
972             return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
973                              REJECT_INVALID, "tx-overwinter-flag-not-set");
974         }
975         
976         // Reject transactions with invalid version
977         if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
978             return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
979                              REJECT_INVALID, "bad-tx-overwinter-version-too-high");
980         }
981         
982         // Reject transactions intended for Sprout
983         if (!tx.fOverwintered) {
984             return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
985                              REJECT_INVALID, "tx-overwinter-active");
986         }
987         
988         // Check that all transactions are unexpired
989         if (IsExpiredTx(tx, nHeight)) {
990             return state.DoS(dosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
991         }
992     }
993     
994     if (!(tx.IsCoinBase() || tx.vjoinsplit.empty())) {
995         auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
996         // Empty output script.
997         CScript scriptCode;
998         uint256 dataToBeSigned;
999         try {
1000             dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1001         } catch (std::logic_error ex) {
1002             return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
1003                              REJECT_INVALID, "error-computing-signature-hash");
1004         }
1005         
1006         BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
1007         
1008         // We rely on libsodium to check that the signature is canonical.
1009         // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1010         if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1011                                         dataToBeSigned.begin(), 32,
1012                                         tx.joinSplitPubKey.begin()
1013                                         ) != 0) {
1014             return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"),
1015                              REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1016         }
1017     }
1018
1019     if (tx.IsCoinBase())
1020     {
1021         if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1022             return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1023                                 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
1024     }
1025     return true;
1026 }
1027
1028 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1029                       libzcash::ProofVerifier& verifier)
1030 {
1031     static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1032     if ( *(int32_t *)&array[0] == 0 )
1033         numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1034     n = tx.vin.size();
1035     for (j=0; j<n; j++)
1036     {
1037         for (k=0; k<numbanned; k++)
1038         {
1039             if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1040             {
1041                 static uint32_t counter;
1042                 if ( counter++ < 100 )
1043                     printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->nHeight,j);
1044                 return(false);
1045             }
1046         }
1047     }
1048     // Don't count coinbase transactions because mining skews the count
1049     if (!tx.IsCoinBase()) {
1050         transactionsValidated.increment();
1051     }
1052     
1053     if (!CheckTransactionWithoutProofVerification(tx, state)) {
1054         return false;
1055     } else {
1056         // Ensure that zk-SNARKs verify
1057         BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1058             if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1059                 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1060                                  REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1061             }
1062         }
1063         return true;
1064     }
1065 }
1066
1067 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1068 {
1069     // Basic checks that don't depend on any context
1070     
1071     /**
1072      * Previously:
1073      * 1. The consensus rule below was:
1074      *        if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1075      *    which checked if tx.nVersion fell within the range:
1076      *        INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1077      * 2. The parser allowed tx.nVersion to be negative
1078      *
1079      * Now:
1080      * 1. The consensus rule checks to see if tx.Version falls within the range:
1081      *        0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1082      * 2. The previous consensus rule checked for negative values within the range:
1083      *        INT32_MIN <= tx.nVersion < 0
1084      *    This is unnecessary for Overwinter transactions since the parser now
1085      *    interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1086      *    and when Overwinter is not active ContextualCheckTransaction rejects
1087      *    transactions with fOverwintered set.  When fOverwintered is set,
1088      *    this function and ContextualCheckTransaction will together check to
1089      *    ensure tx.nVersion avoids the following ranges:
1090      *        0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1091      *        OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1092      */
1093     if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1094         return state.DoS(100, error("CheckTransaction(): version too low"),
1095                          REJECT_INVALID, "bad-txns-version-too-low");
1096     }
1097     else if (tx.fOverwintered) {
1098         if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1099             return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1100                              REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1101         }
1102         if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1103             return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1104                              REJECT_INVALID, "bad-tx-version-group-id");
1105         }
1106         if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1107             return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1108                              REJECT_INVALID, "bad-tx-expiry-height-too-high");
1109         }
1110     }
1111     
1112     // Transactions can contain empty `vin` and `vout` so long as
1113     // `vjoinsplit` is non-empty.
1114     if (tx.vin.empty() && tx.vjoinsplit.empty())
1115         return state.DoS(10, error("CheckTransaction(): vin empty"),
1116                          REJECT_INVALID, "bad-txns-vin-empty");
1117     if (tx.vout.empty() && tx.vjoinsplit.empty())
1118         return state.DoS(10, error("CheckTransaction(): vout empty"),
1119                          REJECT_INVALID, "bad-txns-vout-empty");
1120     
1121     // Size limits
1122     BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE); // sanity
1123     if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE)
1124         return state.DoS(100, error("CheckTransaction(): size limits failed"),
1125                          REJECT_INVALID, "bad-txns-oversize");
1126     
1127     // Check for negative or overflow output values
1128     CAmount nValueOut = 0;
1129     BOOST_FOREACH(const CTxOut& txout, tx.vout)
1130     {
1131         if (txout.nValue < 0)
1132             return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1133                              REJECT_INVALID, "bad-txns-vout-negative");
1134         if (txout.nValue > MAX_MONEY)
1135         {
1136             fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1137             return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1138         }
1139         nValueOut += txout.nValue;
1140         if (!MoneyRange(nValueOut))
1141             return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1142                              REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1143     }
1144     
1145     // Ensure that joinsplit values are well-formed
1146     BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1147     {
1148         if (joinsplit.vpub_old < 0) {
1149             return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1150                              REJECT_INVALID, "bad-txns-vpub_old-negative");
1151         }
1152         
1153         if (joinsplit.vpub_new < 0) {
1154             return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1155                              REJECT_INVALID, "bad-txns-vpub_new-negative");
1156         }
1157         
1158         if (joinsplit.vpub_old > MAX_MONEY) {
1159             return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1160                              REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1161         }
1162         
1163         if (joinsplit.vpub_new > MAX_MONEY) {
1164             return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1165                              REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1166         }
1167         
1168         if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1169             return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1170                              REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1171         }
1172         
1173         nValueOut += joinsplit.vpub_old;
1174         if (!MoneyRange(nValueOut)) {
1175             return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1176                              REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1177         }
1178     }
1179     
1180     // Ensure input values do not exceed MAX_MONEY
1181     // We have not resolved the txin values at this stage,
1182     // but we do know what the joinsplits claim to add
1183     // to the value pool.
1184     {
1185         CAmount nValueIn = 0;
1186         for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1187         {
1188             nValueIn += it->vpub_new;
1189             
1190             if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1191                 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1192                                  REJECT_INVALID, "bad-txns-txintotal-toolarge");
1193             }
1194         }
1195     }
1196     
1197     
1198     // Check for duplicate inputs
1199     set<COutPoint> vInOutPoints;
1200     BOOST_FOREACH(const CTxIn& txin, tx.vin)
1201     {
1202         if (vInOutPoints.count(txin.prevout))
1203             return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1204                              REJECT_INVALID, "bad-txns-inputs-duplicate");
1205         vInOutPoints.insert(txin.prevout);
1206     }
1207     
1208     // Check for duplicate joinsplit nullifiers in this transaction
1209     set<uint256> vJoinSplitNullifiers;
1210     BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1211     {
1212         BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1213         {
1214             if (vJoinSplitNullifiers.count(nf))
1215                 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1216                                  REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1217             
1218             vJoinSplitNullifiers.insert(nf);
1219         }
1220     }
1221     
1222     if (tx.IsCoinBase())
1223     {
1224         // There should be no joinsplits in a coinbase transaction
1225         if (tx.vjoinsplit.size() > 0)
1226             return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1227                              REJECT_INVALID, "bad-cb-has-joinsplits");
1228         
1229         if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1230             return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1231                              REJECT_INVALID, "bad-cb-length");
1232     }
1233     else
1234     {
1235         BOOST_FOREACH(const CTxIn& txin, tx.vin)
1236         if (txin.prevout.IsNull())
1237             return state.DoS(10, error("CheckTransaction(): prevout is null"),
1238                              REJECT_INVALID, "bad-txns-prevout-null");
1239     }
1240     
1241     return true;
1242 }
1243
1244 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1245 {
1246     extern int32_t KOMODO_ON_DEMAND;
1247     {
1248         LOCK(mempool.cs);
1249         uint256 hash = tx.GetHash();
1250         double dPriorityDelta = 0;
1251         CAmount nFeeDelta = 0;
1252         mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1253         if (dPriorityDelta > 0 || nFeeDelta > 0)
1254             return 0;
1255     }
1256     
1257     CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1258     
1259     if (fAllowFree)
1260     {
1261         // There is a free transaction area in blocks created by most miners,
1262         // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1263         //   to be considered to fall into this category. We don't want to encourage sending
1264         //   multiple transactions instead of one big transaction to avoid fees.
1265         if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1266             nMinFee = 0;
1267     }
1268     
1269     if (!MoneyRange(nMinFee))
1270         nMinFee = MAX_MONEY;
1271     return nMinFee;
1272 }
1273
1274
1275 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
1276 {
1277     AssertLockHeld(cs_main);
1278     if (pfMissingInputs)
1279         *pfMissingInputs = false;
1280     
1281     int nextBlockHeight = chainActive.Height() + 1;
1282     auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1283     
1284     // Node operator can choose to reject tx by number of transparent inputs
1285     static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1286     size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1287     if (limit > 0) {
1288         size_t n = tx.vin.size();
1289         if (n > limit) {
1290             LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1291             return false;
1292         }
1293     }
1294     
1295     auto verifier = libzcash::ProofVerifier::Strict();
1296     if ( komodo_validate_interest(tx,chainActive.Tip()->nHeight+1,chainActive.Tip()->GetMedianTimePast() + 777,0) < 0 )
1297     {
1298         //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1299         return error("AcceptToMemoryPool: komodo_validate_interest failed");
1300     }
1301     if (!CheckTransaction(tx, state, verifier))
1302     {
1303         
1304         return error("AcceptToMemoryPool: CheckTransaction failed");
1305     }
1306     // DoS level set to 10 to be more forgiving.
1307     // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1308     if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10))
1309     {
1310         return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1311     }
1312     
1313     // Coinbase is only valid in a block, not as a loose transaction
1314     if (tx.IsCoinBase())
1315     {
1316         fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1317         return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1318     }
1319     // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1320     string reason;
1321     if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1322     {
1323         fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
1324         return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1325     }
1326     // Only accept nLockTime-using transactions that can be mined in the next
1327     // block; we don't want our mempool filled up with transactions that can't
1328     // be mined yet.
1329     if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1330     {
1331         //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1332         return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1333     }
1334     // is it already in the memory pool?
1335     uint256 hash = tx.GetHash();
1336     if (pool.exists(hash))
1337     {
1338         fprintf(stderr,"already in mempool\n");
1339         return false;
1340     }
1341     
1342     // Check for conflicts with in-memory transactions
1343     {
1344         LOCK(pool.cs); // protect pool.mapNextTx
1345         for (unsigned int i = 0; i < tx.vin.size(); i++)
1346         {
1347             COutPoint outpoint = tx.vin[i].prevout;
1348             if (pool.mapNextTx.count(outpoint))
1349             {
1350                 //static uint32_t counter;
1351                 // Disable replacement feature for now
1352                 //if ( counter++ < 100 )
1353                 //fprintf(stderr,"Disable replacement feature for now\n");
1354                 return false;
1355             }
1356         }
1357         BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
1358         {
1359             BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
1360             {
1361                 if (pool.mapNullifiers.count(nf))
1362                 {
1363                     fprintf(stderr,"pool.mapNullifiers.count\n");
1364                     return false;
1365                 }
1366             }
1367         }
1368     }
1369     
1370     {
1371         CCoinsView dummy;
1372         CCoinsViewCache view(&dummy);
1373         int64_t interest;
1374         CAmount nValueIn = 0;
1375         {
1376             LOCK(pool.cs);
1377             CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1378             view.SetBackend(viewMemPool);
1379             
1380             // do we already have it?
1381             if (view.HaveCoins(hash))
1382             {
1383                 fprintf(stderr,"view.HaveCoins(hash) error\n");
1384                 return false;
1385             }
1386             
1387             // do all inputs exist?
1388             // Note that this does not check for the presence of actual outputs (see the next check for that),
1389             // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1390             BOOST_FOREACH(const CTxIn txin, tx.vin)
1391             {
1392                 if (!view.HaveCoins(txin.prevout.hash))
1393                 {
1394                     if (pfMissingInputs)
1395                         *pfMissingInputs = true;
1396                     //fprintf(stderr,"missing inputs\n");
1397                     return false;
1398                 }
1399             }
1400             
1401             // are the actual inputs available?
1402             if (!view.HaveInputs(tx))
1403             {
1404                 //fprintf(stderr,"accept failure.1\n");
1405                 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1406             }
1407             // are the joinsplit's requirements met?
1408             if (!view.HaveJoinSplitRequirements(tx))
1409             {
1410                 //fprintf(stderr,"accept failure.2\n");
1411                 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1412             }
1413             
1414             // Bring the best block into scope
1415             view.GetBestBlock();
1416             
1417             nValueIn = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime);
1418             if ( 0 && interest != 0 )
1419                 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1420             // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1421             view.SetBackend(dummy);
1422         }
1423         
1424         // Check for non-standard pay-to-script-hash in inputs
1425         if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1426             return error("AcceptToMemoryPool: reject nonstandard transaction input");
1427         
1428         // Check that the transaction doesn't have an excessive number of
1429         // sigops, making it impossible to mine. Since the coinbase transaction
1430         // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1431         // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1432         // merely non-standard transaction.
1433         unsigned int nSigOps = GetLegacySigOpCount(tx);
1434         nSigOps += GetP2SHSigOpCount(tx, view);
1435         if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1436         {
1437             fprintf(stderr,"accept failure.4\n");
1438             return state.DoS(0, error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
1439         }
1440         
1441         CAmount nValueOut = tx.GetValueOut();
1442         CAmount nFees = nValueIn-nValueOut;
1443         double dPriority = view.GetPriority(tx, chainActive.Height());
1444         
1445         // Keep track of transactions that spend a coinbase, which we re-scan
1446         // during reorgs to ensure COINBASE_MATURITY is still met.
1447         bool fSpendsCoinbase = false;
1448         BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1449             const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1450             if (coins->IsCoinBase()) {
1451                 fSpendsCoinbase = true;
1452                 break;
1453             }
1454         }
1455         
1456         // Grab the branch ID we expect this transaction to commit to. We don't
1457         // yet know if it does, but if the entry gets added to the mempool, then
1458         // it has passed ContextualCheckInputs and therefore this is correct.
1459         auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1460         
1461         CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1462         unsigned int nSize = entry.GetTxSize();
1463         
1464         // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1465         if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1466             // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1467         } else {
1468             // Don't accept it if it can't get into a block
1469             CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1470             if (fLimitFree && nFees < txMinFee)
1471             {
1472                 //fprintf(stderr,"accept failure.5\n");
1473                 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1474             }
1475         }
1476         
1477         // Require that free transactions have sufficient priority to be mined in the next block.
1478         if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1479             fprintf(stderr,"accept failure.6\n");
1480             return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1481         }
1482         
1483         // Continuously rate-limit free (really, very-low-fee) transactions
1484         // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1485         // be annoying or make others' transactions take longer to confirm.
1486         if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1487         {
1488             static CCriticalSection csFreeLimiter;
1489             static double dFreeCount;
1490             static int64_t nLastTime;
1491             int64_t nNow = GetTime();
1492             
1493             LOCK(csFreeLimiter);
1494             
1495             // Use an exponentially decaying ~10-minute window:
1496             dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1497             nLastTime = nNow;
1498             // -limitfreerelay unit is thousand-bytes-per-minute
1499             // At default rate it would take over a month to fill 1GB
1500             if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1501             {
1502                 fprintf(stderr,"accept failure.7\n");
1503                 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1504             }
1505             LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1506             dFreeCount += nSize;
1507         }
1508         
1509         if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19 )
1510         {
1511             fprintf(stderr,"accept failure.8\n");
1512             return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1513         }
1514         
1515         // Check against previous transactions
1516         // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1517         PrecomputedTransactionData txdata(tx);
1518         if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1519         {
1520             //fprintf(stderr,"accept failure.9\n");
1521             return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1522         }
1523         
1524         // Check again against just the consensus-critical mandatory script
1525         // verification flags, in case of bugs in the standard flags that cause
1526         // transactions to pass as valid when they're actually invalid. For
1527         // instance the STRICTENC flag was incorrectly allowing certain
1528         // CHECKSIG NOT scripts to pass, even though they were invalid.
1529         //
1530         // There is a similar check in CreateNewBlock() to prevent creating
1531         // invalid blocks, however allowing such transactions into the mempool
1532         // can be exploited as a DoS attack.
1533         if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1534         {
1535             fprintf(stderr,"accept failure.10\n");
1536             return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1537         }
1538         
1539         // Store transaction in memory
1540         if ( komodo_is_notarytx(tx) == 0 )
1541             KOMODO_ON_DEMAND++;
1542         pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1543
1544         // Add memory address index
1545         if (fAddressIndex) {
1546             pool.addAddressIndex(entry, view);
1547         }
1548
1549         // Add memory spent index
1550         if (fSpentIndex) {
1551             pool.addSpentIndex(entry, view);
1552         }
1553     }
1554     
1555     SyncWithWallets(tx, NULL);
1556     
1557     return true;
1558 }
1559
1560 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1561 {
1562     if (!fTimestampIndex)
1563         return error("Timestamp index not enabled");
1564
1565     if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1566         return error("Unable to get hashes for timestamps");
1567
1568     return true;
1569 }
1570
1571 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1572 {
1573     if (!fSpentIndex)
1574         return false;
1575
1576     if (mempool.getSpentIndex(key, value))
1577         return true;
1578
1579     if (!pblocktree->ReadSpentIndex(key, value))
1580         return false;
1581
1582     return true;
1583 }
1584
1585 bool GetAddressIndex(uint160 addressHash, int type,
1586                      std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1587 {
1588     if (!fAddressIndex)
1589         return error("address index not enabled");
1590
1591     if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1592         return error("unable to get txids for address");
1593
1594     return true;
1595 }
1596
1597 bool GetAddressUnspent(uint160 addressHash, int type,
1598                        std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1599 {
1600     if (!fAddressIndex)
1601         return error("address index not enabled");
1602
1603     if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1604         return error("unable to get txids for address");
1605
1606     return true;
1607 }
1608
1609 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1610 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1611 {
1612     CBlockIndex *pindexSlow = NULL;
1613     
1614     LOCK(cs_main);
1615     
1616     if (mempool.lookup(hash, txOut))
1617     {
1618         return true;
1619     }
1620     
1621     if (fTxIndex) {
1622         CDiskTxPos postx;
1623         if (pblocktree->ReadTxIndex(hash, postx)) {
1624             CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1625             if (file.IsNull())
1626                 return error("%s: OpenBlockFile failed", __func__);
1627             CBlockHeader header;
1628             try {
1629                 file >> header;
1630                 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1631                 file >> txOut;
1632             } catch (const std::exception& e) {
1633                 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1634             }
1635             hashBlock = header.GetHash();
1636             if (txOut.GetHash() != hash)
1637                 return error("%s: txid mismatch", __func__);
1638             return true;
1639         }
1640     }
1641     
1642     if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1643         int nHeight = -1;
1644         {
1645             CCoinsViewCache &view = *pcoinsTip;
1646             const CCoins* coins = view.AccessCoins(hash);
1647             if (coins)
1648                 nHeight = coins->nHeight;
1649         }
1650         if (nHeight > 0)
1651             pindexSlow = chainActive[nHeight];
1652     }
1653     
1654     if (pindexSlow) {
1655         CBlock block;
1656         if (ReadBlockFromDisk(block, pindexSlow,1)) {
1657             BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1658                 if (tx.GetHash() == hash) {
1659                     txOut = tx;
1660                     hashBlock = pindexSlow->GetBlockHash();
1661                     return true;
1662                 }
1663             }
1664         }
1665     }
1666     
1667     return false;
1668 }
1669
1670 /*char *komodo_getspendscript(uint256 hash,int32_t n)
1671  {
1672  CTransaction tx; uint256 hashBlock;
1673  if ( !GetTransaction(hash,tx,hashBlock,true) )
1674  {
1675  printf("null GetTransaction\n");
1676  return(0);
1677  }
1678  if ( n >= 0 && n < tx.vout.size() )
1679  return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
1680  else printf("getspendscript illegal n.%d\n",n);
1681  return(0);
1682  }*/
1683
1684
1685 //////////////////////////////////////////////////////////////////////////////
1686 //
1687 // CBlock and CBlockIndex
1688 //
1689
1690 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
1691 {
1692     // Open history file to append
1693     CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
1694     if (fileout.IsNull())
1695         return error("WriteBlockToDisk: OpenBlockFile failed");
1696     
1697     // Write index header
1698     unsigned int nSize = fileout.GetSerializeSize(block);
1699     fileout << FLATDATA(messageStart) << nSize;
1700     
1701     // Write block
1702     long fileOutPos = ftell(fileout.Get());
1703     if (fileOutPos < 0)
1704         return error("WriteBlockToDisk: ftell failed");
1705     pos.nPos = (unsigned int)fileOutPos;
1706     fileout << block;
1707     
1708     return true;
1709 }
1710
1711 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
1712 {
1713     uint8_t pubkey33[33];
1714     block.SetNull();
1715     
1716     // Open history file to read
1717     CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
1718     if (filein.IsNull())
1719     {
1720         //fprintf(stderr,"readblockfromdisk err A\n");
1721         return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
1722     }
1723     
1724     // Read block
1725     try {
1726         filein >> block;
1727     }
1728     catch (const std::exception& e) {
1729         fprintf(stderr,"readblockfromdisk err B\n");
1730         return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
1731     }
1732     // Check the header
1733     if ( 0 && checkPOW != 0 )
1734     {
1735         komodo_block2pubkey33(pubkey33,(CBlock *)&block);
1736         if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
1737         {
1738             int32_t i; for (i=0; i<33; i++)
1739                 fprintf(stderr,"%02x",pubkey33[i]);
1740             fprintf(stderr," warning unexpected diff at ht.%d\n",height);
1741             
1742             return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
1743         }
1744     }
1745     return true;
1746 }
1747
1748 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
1749 {
1750     if ( pindex == 0 )
1751         return false;
1752     if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW))
1753         return false;
1754     if (block.GetHash() != pindex->GetBlockHash())
1755         return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
1756                      pindex->ToString(), pindex->GetBlockPos().ToString());
1757     return true;
1758 }
1759
1760 //uint64_t komodo_moneysupply(int32_t height);
1761 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
1762 extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
1763 extern uint32_t ASSETCHAINS_MAGIC;
1764 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
1765
1766 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
1767 {
1768     int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
1769     if ( ASSETCHAINS_SYMBOL[0] == 0 )
1770     {
1771         if ( nHeight == 1 )
1772             return(100000000 * COIN); // ICO allocation
1773         else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
1774             return(3 * COIN);
1775         else return(0);
1776     }
1777     else
1778     {
1779         return(komodo_ac_block_subsidy(nHeight));
1780     }
1781     /*
1782      // Mining slow start
1783      // The subsidy is ramped up linearly, skipping the middle payout of
1784      // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
1785      if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
1786      nSubsidy /= consensusParams.nSubsidySlowStartInterval;
1787      nSubsidy *= nHeight;
1788      return nSubsidy;
1789      } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
1790      nSubsidy /= consensusParams.nSubsidySlowStartInterval;
1791      nSubsidy *= (nHeight+1);
1792      return nSubsidy;
1793      }
1794      
1795      assert(nHeight > consensusParams.SubsidySlowStartShift());
1796      int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
1797     // Force block reward to zero when right shift is undefined.
1798     //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
1799     //if (halvings >= 64)
1800     //    return 0;
1801     
1802     // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
1803     //nSubsidy >>= halvings;
1804     //return nSubsidy;
1805 }
1806
1807 bool IsInitialBlockDownload()
1808 {
1809     const CChainParams& chainParams = Params();
1810     LOCK(cs_main);
1811     if (fImporting || fReindex)
1812     {
1813         //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
1814         return true;
1815     }
1816     if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
1817     {
1818         //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload\n");
1819         return true;
1820     }
1821     static bool lockIBDState = false;
1822     if (lockIBDState)
1823     {
1824         //fprintf(stderr,"lockIBDState true %d < %d\n",chainActive.Height(),pindexBestHeader->nHeight - 10);
1825         return false;
1826     }
1827     bool state; CBlockIndex *ptr = chainActive.Tip();
1828     if ( ptr == 0 )
1829         ptr = pindexBestHeader;
1830     else if ( pindexBestHeader != 0 && pindexBestHeader->nHeight > ptr->nHeight )
1831         ptr = pindexBestHeader;
1832     //if ( ASSETCHAINS_SYMBOL[0] == 0 )
1833     state = ((chainActive.Height() < ptr->nHeight - 24*60) ||
1834              ptr->GetBlockTime() < (GetTime() - chainParams.MaxTipAge()));
1835     //else state = (chainActive.Height() < ptr->nHeight - 24*60);
1836     //fprintf(stderr,"state.%d  ht.%d vs %d, t.%u %u\n",state,(int32_t)chainActive.Height(),(uint32_t)ptr->nHeight,(int32_t)ptr->GetBlockTime(),(uint32_t)(GetTime() - chainParams.MaxTipAge()));
1837     if (!state)
1838     {
1839         lockIBDState = true;
1840     }
1841     return state;
1842 }
1843
1844 bool fLargeWorkForkFound = false;
1845 bool fLargeWorkInvalidChainFound = false;
1846 CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
1847
1848 void CheckForkWarningConditions()
1849 {
1850     AssertLockHeld(cs_main);
1851     // Before we get past initial download, we cannot reliably alert about forks
1852     // (we assume we don't get stuck on a fork before the last checkpoint)
1853     if (IsInitialBlockDownload())
1854         return;
1855     
1856     // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
1857     // of our head, drop it
1858     if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 288)
1859         pindexBestForkTip = NULL;
1860     
1861     if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6)))
1862     {
1863         if (!fLargeWorkForkFound && pindexBestForkBase)
1864         {
1865             std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
1866             pindexBestForkBase->phashBlock->ToString() + std::string("'");
1867             CAlert::Notify(warning, true);
1868         }
1869         if (pindexBestForkTip && pindexBestForkBase)
1870         {
1871             LogPrintf("%s: Warning: Large valid fork found\n  forking the chain at height %d (%s)\n  lasting to height %d (%s).\nChain state database corruption likely.\n", __func__,
1872                       pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
1873                       pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
1874             fLargeWorkForkFound = true;
1875         }
1876         else
1877         {
1878             std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
1879             LogPrintf("%s: %s\n", warning.c_str(), __func__);
1880             CAlert::Notify(warning, true);
1881             fLargeWorkInvalidChainFound = true;
1882         }
1883     }
1884     else
1885     {
1886         fLargeWorkForkFound = false;
1887         fLargeWorkInvalidChainFound = false;
1888     }
1889 }
1890
1891 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
1892 {
1893     AssertLockHeld(cs_main);
1894     // If we are on a fork that is sufficiently large, set a warning flag
1895     CBlockIndex* pfork = pindexNewForkTip;
1896     CBlockIndex* plonger = chainActive.Tip();
1897     while (pfork && pfork != plonger)
1898     {
1899         while (plonger && plonger->nHeight > pfork->nHeight)
1900             plonger = plonger->pprev;
1901         if (pfork == plonger)
1902             break;
1903         pfork = pfork->pprev;
1904     }
1905     
1906     // We define a condition where we should warn the user about as a fork of at least 7 blocks
1907     // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
1908     // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
1909     // hash rate operating on the fork.
1910     // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
1911     // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
1912     // the 7-block condition and from this always have the most-likely-to-cause-warning fork
1913     if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
1914         pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
1915         chainActive.Height() - pindexNewForkTip->nHeight < 72)
1916     {
1917         pindexBestForkTip = pindexNewForkTip;
1918         pindexBestForkBase = pfork;
1919     }
1920     
1921     CheckForkWarningConditions();
1922 }
1923
1924 // Requires cs_main.
1925 void Misbehaving(NodeId pnode, int howmuch)
1926 {
1927     if (howmuch == 0)
1928         return;
1929     
1930     CNodeState *state = State(pnode);
1931     if (state == NULL)
1932         return;
1933     
1934     state->nMisbehavior += howmuch;
1935     int banscore = GetArg("-banscore", 101);
1936     if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
1937     {
1938         LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
1939         state->fShouldBan = true;
1940     } else
1941         LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
1942 }
1943
1944 void static InvalidChainFound(CBlockIndex* pindexNew)
1945 {
1946     if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
1947         pindexBestInvalid = pindexNew;
1948     
1949     LogPrintf("%s: invalid block=%s  height=%d  log2_work=%.8g  date=%s\n", __func__,
1950               pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
1951               log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
1952                                                                                  pindexNew->GetBlockTime()));
1953     CBlockIndex *tip = chainActive.Tip();
1954     assert (tip);
1955     LogPrintf("%s:  current best=%s  height=%d  log2_work=%.8g  date=%s\n", __func__,
1956               tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
1957               DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
1958     CheckForkWarningConditions();
1959 }
1960
1961 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
1962     int nDoS = 0;
1963     if (state.IsInvalid(nDoS)) {
1964         std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
1965         if (it != mapBlockSource.end() && State(it->second)) {
1966             CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
1967             State(it->second)->rejects.push_back(reject);
1968             if (nDoS > 0)
1969                 Misbehaving(it->second, nDoS);
1970         }
1971     }
1972     if (!state.CorruptionPossible()) {
1973         pindex->nStatus |= BLOCK_FAILED_VALID;
1974         setDirtyBlockIndex.insert(pindex);
1975         setBlockIndexCandidates.erase(pindex);
1976         InvalidChainFound(pindex);
1977     }
1978 }
1979
1980 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
1981 {
1982     if (!tx.IsCoinBase()) // mark inputs spent
1983     {
1984         txundo.vprevout.reserve(tx.vin.size());
1985         BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1986             CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
1987             unsigned nPos = txin.prevout.n;
1988             
1989             if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
1990                 assert(false);
1991             // mark an outpoint spent, and construct undo information
1992             txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
1993             coins->Spend(nPos);
1994             if (coins->vout.size() == 0) {
1995                 CTxInUndo& undo = txundo.vprevout.back();
1996                 undo.nHeight = coins->nHeight;
1997                 undo.fCoinBase = coins->fCoinBase;
1998                 undo.nVersion = coins->nVersion;
1999             }
2000         }
2001     }
2002     BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { // spend nullifiers
2003         BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
2004             inputs.SetNullifier(nf, true);
2005         }
2006     }
2007     inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2008 }
2009
2010 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2011 {
2012     CTxUndo txundo;
2013     UpdateCoins(tx, inputs, txundo, nHeight);
2014 }
2015
2016 bool CScriptCheck::operator()() {
2017     const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2018     if (!VerifyScript(scriptSig, scriptPubKey, nFlags, ServerTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), consensusBranchId, &error)) {
2019         return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2020     }
2021     return true;
2022 }
2023
2024 int GetSpendHeight(const CCoinsViewCache& inputs)
2025 {
2026     LOCK(cs_main);
2027     CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2028     return pindexPrev->nHeight + 1;
2029 }
2030
2031 namespace Consensus {
2032     bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2033     {
2034         // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2035         // for an attacker to attempt to split the network.
2036         if (!inputs.HaveInputs(tx))
2037             return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2038         
2039         // are the JoinSplit's requirements met?
2040         if (!inputs.HaveJoinSplitRequirements(tx))
2041             return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2042         
2043         CAmount nValueIn = 0;
2044         CAmount nFees = 0;
2045         for (unsigned int i = 0; i < tx.vin.size(); i++)
2046         {
2047             const COutPoint &prevout = tx.vin[i].prevout;
2048             const CCoins *coins = inputs.AccessCoins(prevout.hash);
2049             assert(coins);
2050
2051             if (coins->IsCoinBase()) {
2052                 // Ensure that coinbases are matured
2053                 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2054                     return state.Invalid(
2055                                          error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2056                                          REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2057                 }
2058
2059                 // ensure that output of coinbases are not still time locked
2060                 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2061                 if (nSpendHeight < unlockTime && coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE) {
2062                     return state.Invalid(
2063                                          error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2064                                          REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2065                 }
2066                 
2067                 // Ensure that coinbases cannot be spent to transparent outputs
2068                 // Disabled on regtest
2069                 if (fCoinbaseEnforcedProtectionEnabled &&
2070                     consensusParams.fCoinbaseMustBeProtected &&
2071                     !tx.vout.empty() &&
2072                     (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
2073                     return state.Invalid(
2074                                          error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2075                                          REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2076                 }
2077             }
2078             
2079             // Check for negative or overflow input values
2080             nValueIn += coins->vout[prevout.n].nValue;
2081 #ifdef KOMODO_ENABLE_INTEREST
2082             if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 )
2083             {
2084                 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2085                 {
2086                     int64_t interest; int32_t txheight; uint32_t locktime;
2087                     if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2088                     {
2089                         //fprintf(stderr,"checkResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nValueIn/COIN,(double)coins->vout[prevout.n].nValue/COIN,(double)interest/COIN,txheight,locktime,chainActive.Tip()->nTime);
2090                         nValueIn += interest;
2091                     }
2092                 }
2093             }
2094 #endif
2095             if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2096                 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2097                                  REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2098             
2099         }
2100         
2101         nValueIn += tx.GetJoinSplitValueIn();
2102         if (!MoneyRange(nValueIn))
2103             return state.DoS(100, error("CheckInputs(): vpub_old values out of range"),
2104                              REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2105         
2106         if (nValueIn < tx.GetValueOut())
2107         {
2108             fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2109             return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2110                                         tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2111         }
2112         // Tally transaction fees
2113         CAmount nTxFee = nValueIn - tx.GetValueOut();
2114         if (nTxFee < 0)
2115             return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2116                              REJECT_INVALID, "bad-txns-fee-negative");
2117         nFees += nTxFee;
2118         if (!MoneyRange(nFees))
2119             return state.DoS(100, error("CheckInputs(): nFees out of range"),
2120                              REJECT_INVALID, "bad-txns-fee-outofrange");
2121         return true;
2122     }
2123 }// namespace Consensus
2124
2125 bool ContextualCheckInputs(
2126                            const CTransaction& tx,
2127                            CValidationState &state,
2128                            const CCoinsViewCache &inputs,
2129                            bool fScriptChecks,
2130                            unsigned int flags,
2131                            bool cacheStore,
2132                            PrecomputedTransactionData& txdata,
2133                            const Consensus::Params& consensusParams,
2134                            uint32_t consensusBranchId,
2135                            std::vector<CScriptCheck> *pvChecks)
2136 {
2137     if (!tx.IsCoinBase())
2138     {
2139         if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2140             return false;
2141         }
2142         
2143         if (pvChecks)
2144             pvChecks->reserve(tx.vin.size());
2145         
2146         // The first loop above does all the inexpensive checks.
2147         // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2148         // Helps prevent CPU exhaustion attacks.
2149         
2150         // Skip ECDSA signature verification when connecting blocks
2151         // before the last block chain checkpoint. This is safe because block merkle hashes are
2152         // still computed and checked, and any change will be caught at the next checkpoint.
2153         if (fScriptChecks) {
2154             for (unsigned int i = 0; i < tx.vin.size(); i++) {
2155                 const COutPoint &prevout = tx.vin[i].prevout;
2156                 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2157                 assert(coins);
2158                 
2159                 // Verify signature
2160                 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2161                 if (pvChecks) {
2162                     pvChecks->push_back(CScriptCheck());
2163                     check.swap(pvChecks->back());
2164                 } else if (!check()) {
2165                     if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2166                         // Check whether the failure was caused by a
2167                         // non-mandatory script verification check, such as
2168                         // non-standard DER encodings or non-null dummy
2169                         // arguments; if so, don't trigger DoS protection to
2170                         // avoid splitting the network between upgraded and
2171                         // non-upgraded nodes.
2172                         CScriptCheck check2(*coins, tx, i,
2173                                             flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2174                         if (check2())
2175                             return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2176                     }
2177                     // Failures of other flags indicate a transaction that is
2178                     // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2179                     // such nodes as they are not following the protocol. That
2180                     // said during an upgrade careful thought should be taken
2181                     // as to the correct behavior - we may want to continue
2182                     // peering with non-upgraded nodes even after a soft-fork
2183                     // super-majority vote has passed.
2184                     return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2185                 }
2186             }
2187         }
2188     }
2189     
2190     return true;
2191 }
2192
2193
2194 /*bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector<CScriptCheck> *pvChecks)
2195  {
2196  if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2197  fprintf(stderr,"ContextualCheckInputs failure.0\n");
2198  return false;
2199  }
2200  
2201  if (!tx.IsCoinBase())
2202  {
2203  // While checking, GetBestBlock() refers to the parent block.
2204  // This is also true for mempool checks.
2205  CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2206  int nSpendHeight = pindexPrev->nHeight + 1;
2207  for (unsigned int i = 0; i < tx.vin.size(); i++)
2208  {
2209  const COutPoint &prevout = tx.vin[i].prevout;
2210  const CCoins *coins = inputs.AccessCoins(prevout.hash);
2211  // Assertion is okay because NonContextualCheckInputs ensures the inputs
2212  // are available.
2213  assert(coins);
2214  
2215  // If prev is coinbase, check that it's matured
2216  if (coins->IsCoinBase()) {
2217  if ( ASSETCHAINS_SYMBOL[0] == 0 )
2218  COINBASE_MATURITY = _COINBASE_MATURITY;
2219  if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2220  fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2221  
2222  return state.Invalid(
2223  error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2224  }
2225  }
2226  }
2227  }
2228  
2229  return true;
2230  }*/
2231
2232 namespace {
2233     
2234     bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2235     {
2236         // Open history file to append
2237         CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2238         if (fileout.IsNull())
2239             return error("%s: OpenUndoFile failed", __func__);
2240         
2241         // Write index header
2242         unsigned int nSize = fileout.GetSerializeSize(blockundo);
2243         fileout << FLATDATA(messageStart) << nSize;
2244         
2245         // Write undo data
2246         long fileOutPos = ftell(fileout.Get());
2247         if (fileOutPos < 0)
2248             return error("%s: ftell failed", __func__);
2249         pos.nPos = (unsigned int)fileOutPos;
2250         fileout << blockundo;
2251         
2252         // calculate & write checksum
2253         CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2254         hasher << hashBlock;
2255         hasher << blockundo;
2256         fileout << hasher.GetHash();
2257         
2258         return true;
2259     }
2260     
2261     bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2262     {
2263         // Open history file to read
2264         CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2265         if (filein.IsNull())
2266             return error("%s: OpenBlockFile failed", __func__);
2267         
2268         // Read block
2269         uint256 hashChecksum;
2270         try {
2271             filein >> blockundo;
2272             filein >> hashChecksum;
2273         }
2274         catch (const std::exception& e) {
2275             return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2276         }
2277         // Verify checksum
2278         CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2279         hasher << hashBlock;
2280         hasher << blockundo;
2281         if (hashChecksum != hasher.GetHash())
2282             return error("%s: Checksum mismatch", __func__);
2283         
2284         return true;
2285     }
2286     
2287     /** Abort with a message */
2288     bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2289     {
2290         strMiscWarning = strMessage;
2291         LogPrintf("*** %s\n", strMessage);
2292         uiInterface.ThreadSafeMessageBox(
2293                                          userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2294                                          "", CClientUIInterface::MSG_ERROR);
2295         StartShutdown();
2296         return false;
2297     }
2298     
2299     bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2300     {
2301         AbortNode(strMessage, userMessage);
2302         return state.Error(strMessage);
2303     }
2304     
2305 } // anon namespace
2306
2307 /**
2308  * Apply the undo operation of a CTxInUndo to the given chain state.
2309  * @param undo The undo object.
2310  * @param view The coins view to which to apply the changes.
2311  * @param out The out point that corresponds to the tx input.
2312  * @return True on success.
2313  */
2314 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2315 {
2316     bool fClean = true;
2317     
2318     CCoinsModifier coins = view.ModifyCoins(out.hash);
2319     if (undo.nHeight != 0) {
2320         // undo data contains height: this is the last output of the prevout tx being spent
2321         if (!coins->IsPruned())
2322             fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2323         coins->Clear();
2324         coins->fCoinBase = undo.fCoinBase;
2325         coins->nHeight = undo.nHeight;
2326         coins->nVersion = undo.nVersion;
2327     } else {
2328         if (coins->IsPruned())
2329             fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2330     }
2331     if (coins->IsAvailable(out.n))
2332         fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2333     if (coins->vout.size() < out.n+1)
2334         coins->vout.resize(out.n+1);
2335     coins->vout[out.n] = undo.txout;
2336     
2337     return fClean;
2338 }
2339
2340 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2341 {
2342     assert(pindex->GetBlockHash() == view.GetBestBlock());
2343     
2344     if (pfClean)
2345         *pfClean = false;
2346     
2347     bool fClean = true;
2348     komodo_disconnect(pindex,block);
2349     CBlockUndo blockUndo;
2350     CDiskBlockPos pos = pindex->GetUndoPos();
2351     if (pos.IsNull())
2352         return error("DisconnectBlock(): no undo data available");
2353     if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2354         return error("DisconnectBlock(): failure reading undo data");
2355     
2356     if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2357         return error("DisconnectBlock(): block and undo data inconsistent");
2358     std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2359     std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2360     std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2361
2362     // undo transactions in reverse order
2363     for (int i = block.vtx.size() - 1; i >= 0; i--) {
2364         const CTransaction &tx = block.vtx[i];
2365         uint256 hash = tx.GetHash();
2366         if (fAddressIndex) {
2367
2368             for (unsigned int k = tx.vout.size(); k-- > 0;) {
2369                 const CTxOut &out = tx.vout[k];
2370
2371                 if (out.scriptPubKey.IsPayToScriptHash()) {
2372                     vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2373
2374                     // undo receiving activity
2375                     addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2376
2377                     // undo unspent index
2378                     addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2379
2380                 } else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2381                     vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2382
2383                     // undo receiving activity
2384                     addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2385
2386                     // undo unspent index
2387                     addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2388
2389                 } else {
2390                     continue;
2391                 }
2392
2393             }
2394
2395         }
2396
2397         // Check that all outputs are available and match the outputs in the block itself
2398         // exactly.
2399         {
2400             CCoinsModifier outs = view.ModifyCoins(hash);
2401             outs->ClearUnspendable();
2402             
2403             CCoins outsBlock(tx, pindex->nHeight);
2404             // The CCoins serialization does not serialize negative numbers.
2405             // No network rules currently depend on the version here, so an inconsistency is harmless
2406             // but it must be corrected before txout nversion ever influences a network rule.
2407             if (outsBlock.nVersion < 0)
2408                 outs->nVersion = outsBlock.nVersion;
2409             if (*outs != outsBlock)
2410                 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2411             
2412             // remove outputs
2413             outs->Clear();
2414         }
2415         
2416         // unspend nullifiers
2417         BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
2418             BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
2419                 view.SetNullifier(nf, false);
2420             }
2421         }
2422         
2423         // restore inputs
2424         if (i > 0) { // not coinbases
2425             const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2426             if (txundo.vprevout.size() != tx.vin.size())
2427                 return error("DisconnectBlock(): transaction and undo data inconsistent");
2428             for (unsigned int j = tx.vin.size(); j-- > 0;) {
2429                 const COutPoint &out = tx.vin[j].prevout;
2430                 const CTxInUndo &undo = txundo.vprevout[j];
2431                 if (!ApplyTxInUndo(undo, view, out))
2432                     fClean = false;
2433
2434                 const CTxIn input = tx.vin[j];
2435
2436                 if (fSpentIndex) {
2437                     // undo and delete the spent index
2438                     spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2439                 }
2440
2441                 if (fAddressIndex) {
2442                     const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2443                     if (prevout.scriptPubKey.IsPayToScriptHash()) {
2444                         vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2445
2446                         // undo spending activity
2447                         addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2448
2449                         // restore unspent index
2450                         addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2451
2452
2453                     } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2454                         vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2455
2456                         // undo spending activity
2457                         addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2458
2459                         // restore unspent index
2460                         addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2461
2462                     } else {
2463                         continue;
2464                     }
2465                 }
2466             }
2467         }
2468     }
2469     
2470     // set the old best anchor back
2471     view.PopAnchor(blockUndo.old_tree_root);
2472     
2473     // move best block pointer to prevout block
2474     view.SetBestBlock(pindex->pprev->GetBlockHash());
2475     
2476     if (pfClean) {
2477         *pfClean = fClean;
2478         return true;
2479     }
2480
2481     if (fAddressIndex) {
2482         if (!pblocktree->EraseAddressIndex(addressIndex)) {
2483             return AbortNode(state, "Failed to delete address index");
2484         }
2485         if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2486             return AbortNode(state, "Failed to write address unspent index");
2487         }
2488     }
2489     return fClean;
2490 }
2491
2492 void static FlushBlockFile(bool fFinalize = false)
2493 {
2494     LOCK(cs_LastBlockFile);
2495     
2496     CDiskBlockPos posOld(nLastBlockFile, 0);
2497     
2498     FILE *fileOld = OpenBlockFile(posOld);
2499     if (fileOld) {
2500         if (fFinalize)
2501             TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2502         FileCommit(fileOld);
2503         fclose(fileOld);
2504     }
2505     
2506     fileOld = OpenUndoFile(posOld);
2507     if (fileOld) {
2508         if (fFinalize)
2509             TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2510         FileCommit(fileOld);
2511         fclose(fileOld);
2512     }
2513 }
2514
2515 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
2516
2517 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
2518
2519 void ThreadScriptCheck() {
2520     RenameThread("zcash-scriptch");
2521     scriptcheckqueue.Thread();
2522 }
2523
2524 //
2525 // Called periodically asynchronously; alerts if it smells like
2526 // we're being fed a bad chain (blocks being generated much
2527 // too slowly or too quickly).
2528 //
2529 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2530                     int64_t nPowTargetSpacing)
2531 {
2532     if (bestHeader == NULL || initialDownloadCheck()) return;
2533     
2534     static int64_t lastAlertTime = 0;
2535     int64_t now = GetAdjustedTime();
2536     if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
2537     
2538     const int SPAN_HOURS=4;
2539     const int SPAN_SECONDS=SPAN_HOURS*60*60;
2540     int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
2541     
2542     boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
2543     
2544     std::string strWarning;
2545     int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
2546     
2547     LOCK(cs);
2548     const CBlockIndex* i = bestHeader;
2549     int nBlocks = 0;
2550     while (i->GetBlockTime() >= startTime) {
2551         ++nBlocks;
2552         i = i->pprev;
2553         if (i == NULL) return; // Ran out of chain, we must not be fully synced
2554     }
2555     
2556     // How likely is it to find that many by chance?
2557     double p = boost::math::pdf(poisson, nBlocks);
2558     
2559     LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
2560     LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
2561     
2562     // Aim for one false-positive about every fifty years of normal running:
2563     const int FIFTY_YEARS = 50*365*24*60*60;
2564     double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
2565     
2566     if (bestHeader->nHeight > BLOCKS_EXPECTED)
2567     {
2568         if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
2569         {
2570             // Many fewer blocks than expected: alert!
2571             strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
2572                                 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
2573         }
2574         else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
2575         {
2576             // Many more blocks than expected: alert!
2577             strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
2578                                 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
2579         }
2580     }
2581     if (!strWarning.empty())
2582     {
2583         strMiscWarning = strWarning;
2584         CAlert::Notify(strWarning, true);
2585         lastAlertTime = now;
2586     }
2587 }
2588
2589 static int64_t nTimeVerify = 0;
2590 static int64_t nTimeConnect = 0;
2591 static int64_t nTimeIndex = 0;
2592 static int64_t nTimeCallbacks = 0;
2593 static int64_t nTimeTotal = 0;
2594
2595 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
2596 {
2597     const CChainParams& chainparams = Params();
2598     
2599     //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->nHeight);
2600     AssertLockHeld(cs_main);
2601     bool fExpensiveChecks = true;
2602     if (fCheckpointsEnabled) {
2603         CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
2604         if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
2605             // This block is an ancestor of a checkpoint: disable script checks
2606             fExpensiveChecks = false;
2607         }
2608     }
2609     auto verifier = libzcash::ProofVerifier::Strict();
2610     auto disabledVerifier = libzcash::ProofVerifier::Disabled();
2611     int32_t futureblock;
2612     // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
2613     if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
2614     {
2615         //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
2616         return false;
2617     }
2618     
2619     // verify that the view's current state corresponds to the previous block
2620     uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
2621     if ( hashPrevBlock != view.GetBestBlock() )
2622     {
2623         fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
2624         return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
2625                          REJECT_INVALID, "hashPrevBlock-not-bestblock");
2626     }
2627     assert(hashPrevBlock == view.GetBestBlock());
2628     
2629     // Special case for the genesis block, skipping connection of its transactions
2630     // (its coinbase is unspendable)
2631     if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
2632         if (!fJustCheck) {
2633             view.SetBestBlock(pindex->GetBlockHash());
2634             // Before the genesis block, there was an empty tree
2635             ZCIncrementalMerkleTree tree;
2636             pindex->hashAnchor = tree.root();
2637             // The genesis block contained no JoinSplits
2638             pindex->hashAnchorEnd = pindex->hashAnchor;
2639         }
2640         return true;
2641     }
2642     
2643     bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
2644     //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->nHeight > KOMODO_TESTNET_EXPIRATION ) // "testnet"
2645     //    return(false);
2646     // Do not allow blocks that contain transactions which 'overwrite' older transactions,
2647     // unless those are already completely spent.
2648     BOOST_FOREACH(const CTransaction& tx, block.vtx) {
2649         const CCoins* coins = view.AccessCoins(tx.GetHash());
2650         if (coins && !coins->IsPruned())
2651             return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
2652                              REJECT_INVALID, "bad-txns-BIP30");
2653     }
2654     
2655     unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
2656     
2657     // DERSIG (BIP66) is also always enforced, but does not have a flag.
2658     
2659     CBlockUndo blockundo;
2660     
2661     CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
2662     
2663     int64_t nTimeStart = GetTimeMicros();
2664     CAmount nFees = 0;
2665     int nInputs = 0;
2666     int64_t interest,sum = 0;
2667     unsigned int nSigOps = 0;
2668     CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
2669     std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2670     vPos.reserve(block.vtx.size());
2671     blockundo.vtxundo.reserve(block.vtx.size() - 1);
2672     std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2673     std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2674     std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2675     // Construct the incremental merkle tree at the current
2676     // block position,
2677     auto old_tree_root = view.GetBestAnchor();
2678     // saving the top anchor in the block index as we go.
2679     if (!fJustCheck) {
2680         pindex->hashAnchor = old_tree_root;
2681     }
2682     ZCIncrementalMerkleTree tree;
2683     // This should never fail: we should always be able to get the root
2684     // that is on the tip of our chain
2685     assert(view.GetAnchorAt(old_tree_root, tree));
2686     
2687     {
2688         // Consistency check: the root of the tree we're given should
2689         // match what we asked for.
2690         assert(tree.root() == old_tree_root);
2691     }
2692     
2693     // Grab the consensus branch ID for the block's height
2694     auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus());
2695     
2696     std::vector<PrecomputedTransactionData> txdata;
2697     txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
2698     for (unsigned int i = 0; i < block.vtx.size(); i++)
2699     {
2700         const CTransaction &tx = block.vtx[i];
2701         const uint256 txhash = tx.GetHash();
2702         nInputs += tx.vin.size();
2703         nSigOps += GetLegacySigOpCount(tx);
2704         if (nSigOps > MAX_BLOCK_SIGOPS)
2705             return state.DoS(100, error("ConnectBlock(): too many sigops"),
2706                              REJECT_INVALID, "bad-blk-sigops");
2707         //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->nHeight,tx.nLockTime);
2708         if (!tx.IsCoinBase())
2709         {
2710             if (!view.HaveInputs(tx))
2711             {
2712                 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
2713                                  REJECT_INVALID, "bad-txns-inputs-missingorspent");
2714             }
2715             // are the JoinSplit's requirements met?
2716             if (!view.HaveJoinSplitRequirements(tx))
2717                 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
2718                                  REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
2719             if (fAddressIndex || fSpentIndex)
2720             {
2721                 for (size_t j = 0; j < tx.vin.size(); j++) {
2722
2723                     const CTxIn input = tx.vin[j];
2724                     const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2725                     uint160 hashBytes;
2726                     int addressType;
2727
2728                     if (prevout.scriptPubKey.IsPayToScriptHash()) {
2729                         hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
2730                         addressType = 2;
2731                     } else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2732                         hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
2733                         addressType = 1;
2734                     } else {
2735                         hashBytes.SetNull();
2736                         addressType = 0;
2737                     }
2738
2739                     if (fAddressIndex && addressType > 0) {
2740                         // record spending activity
2741                         addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
2742
2743                         // remove address from unspent index
2744                         addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
2745                     }
2746
2747                     if (fSpentIndex) {
2748                         // add the spent index to determine the txid and input that spent an output
2749                         // and to find the amount and address from an input
2750                         spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes)));
2751                     }
2752                 }
2753
2754             }
2755             // Add in sigops done by pay-to-script-hash inputs;
2756             // this is to prevent a "rogue miner" from creating
2757             // an incredibly-expensive-to-validate block.
2758             nSigOps += GetP2SHSigOpCount(tx, view);
2759             if (nSigOps > MAX_BLOCK_SIGOPS)
2760                 return state.DoS(100, error("ConnectBlock(): too many sigops"),
2761                                  REJECT_INVALID, "bad-blk-sigops");
2762         }
2763         
2764         txdata.emplace_back(tx);
2765         
2766         if (!tx.IsCoinBase())
2767         {
2768             nFees += view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime) - tx.GetValueOut();
2769             sum += interest;
2770             
2771             std::vector<CScriptCheck> vChecks;
2772             if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
2773                 return false;
2774             control.Add(vChecks);
2775         }
2776
2777         if (fAddressIndex) {
2778             for (unsigned int k = 0; k < tx.vout.size(); k++) {
2779                 const CTxOut &out = tx.vout[k];
2780
2781                 if (out.scriptPubKey.IsPayToScriptHash()) {
2782                     vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2783
2784                     // record receiving activity
2785                     addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
2786
2787                     // record unspent output
2788                     addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
2789
2790                 } else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2791                     vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2792
2793                     // record receiving activity
2794                     addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
2795
2796                     // record unspent output
2797                     addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
2798
2799                 } else {
2800                     continue;
2801                 }
2802
2803             }
2804         }
2805
2806         //if ( ASSETCHAINS_SYMBOL[0] == 0 )
2807         //    komodo_earned_interest(pindex->nHeight,sum);
2808         CTxUndo undoDummy;
2809         if (i > 0) {
2810             blockundo.vtxundo.push_back(CTxUndo());
2811         }
2812         UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
2813         
2814         BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
2815             BOOST_FOREACH(const uint256 &note_commitment, joinsplit.commitments) {
2816                 // Insert the note commitments into our temporary tree.
2817                 
2818                 tree.append(note_commitment);
2819             }
2820         }
2821         
2822         vPos.push_back(std::make_pair(tx.GetHash(), pos));
2823         pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
2824     }
2825
2826     view.PushAnchor(tree);
2827     if (!fJustCheck) {
2828         pindex->hashAnchorEnd = tree.root();
2829     }
2830     blockundo.old_tree_root = old_tree_root;
2831     
2832     int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
2833     LogPrint("bench", "      - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
2834     
2835     CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
2836     if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
2837     {
2838         uint64_t checktoshis;
2839         if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
2840         {
2841             if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
2842                 blockReward += checktoshis;
2843             else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
2844         }
2845     }
2846     if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->nHeight == 1 && block.vtx[0].GetValueOut() != blockReward)
2847     {
2848         return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
2849                             REJECT_INVALID, "bad-cb-amount");
2850     }
2851     if ( block.vtx[0].GetValueOut() > blockReward+1 )
2852     {
2853         if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
2854         {
2855             return state.DoS(100,
2856                              error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
2857                                    block.vtx[0].GetValueOut(), blockReward),
2858                              REJECT_INVALID, "bad-cb-amount");
2859         } else if ( NOTARY_PUBKEY33[0] != 0 )
2860             fprintf(stderr,"allow nHeight.%d coinbase %.8f vs %.8f interest %.8f\n",(int32_t)pindex->nHeight,dstr(block.vtx[0].GetValueOut()),dstr(blockReward),dstr(sum));
2861     }
2862     if (!control.Wait())
2863         return state.DoS(100, false);
2864     int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
2865     LogPrint("bench", "    - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n", nInputs - 1, 0.001 * (nTime2 - nTimeStart), nInputs <= 1 ? 0 : 0.001 * (nTime2 - nTimeStart) / (nInputs-1), nTimeVerify * 0.000001);
2866     
2867     if (fJustCheck)
2868         return true;
2869     
2870     // Write undo information to disk
2871     if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
2872     {
2873         if (pindex->GetUndoPos().IsNull()) {
2874             CDiskBlockPos pos;
2875             if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
2876                 return error("ConnectBlock(): FindUndoPos failed");
2877             if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
2878                 return AbortNode(state, "Failed to write undo data");
2879             
2880             // update nUndoPos in block index
2881             pindex->nUndoPos = pos.nPos;
2882             pindex->nStatus |= BLOCK_HAVE_UNDO;
2883         }
2884         
2885         // Now that all consensus rules have been validated, set nCachedBranchId.
2886         // Move this if BLOCK_VALID_CONSENSUS is ever altered.
2887         static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
2888                       "nCachedBranchId must be set after all consensus rules have been validated.");
2889         if (IsActivationHeightForAnyUpgrade(pindex->nHeight, Params().GetConsensus())) {
2890             pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
2891             pindex->nCachedBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus());
2892         } else if (pindex->pprev) {
2893             pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
2894         }
2895         
2896         pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
2897         setDirtyBlockIndex.insert(pindex);
2898     }
2899     
2900     if (fTxIndex)
2901         if (!pblocktree->WriteTxIndex(vPos))
2902             return AbortNode(state, "Failed to write transaction index");
2903     if (fAddressIndex) {
2904         if (!pblocktree->WriteAddressIndex(addressIndex)) {
2905             return AbortNode(state, "Failed to write address index");
2906         }
2907
2908         if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2909             return AbortNode(state, "Failed to write address unspent index");
2910         }
2911     }
2912
2913     if (fSpentIndex)
2914         if (!pblocktree->UpdateSpentIndex(spentIndex))
2915             return AbortNode(state, "Failed to write transaction index");
2916
2917     if (fTimestampIndex) {
2918         unsigned int logicalTS = pindex->nTime;
2919         unsigned int prevLogicalTS = 0;
2920
2921         // retrieve logical timestamp of the previous block
2922         if (pindex->pprev)
2923             if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
2924                 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
2925
2926         if (logicalTS <= prevLogicalTS) {
2927             logicalTS = prevLogicalTS + 1;
2928             LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
2929         }
2930
2931         if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
2932             return AbortNode(state, "Failed to write timestamp index");
2933
2934         if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
2935             return AbortNode(state, "Failed to write blockhash index");
2936     }
2937
2938     // add this block to the view's block chain
2939     view.SetBestBlock(pindex->GetBlockHash());
2940     
2941     int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
2942     LogPrint("bench", "    - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
2943     
2944     // Watch for changes to the previous coinbase transaction.
2945     static uint256 hashPrevBestCoinBase;
2946     GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
2947     hashPrevBestCoinBase = block.vtx[0].GetHash();
2948     
2949     int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
2950     LogPrint("bench", "    - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
2951     
2952     //FlushStateToDisk();
2953     komodo_connectblock(pindex,*(CBlock *)&block);
2954     return true;
2955 }
2956
2957 enum FlushStateMode {
2958     FLUSH_STATE_NONE,
2959     FLUSH_STATE_IF_NEEDED,
2960     FLUSH_STATE_PERIODIC,
2961     FLUSH_STATE_ALWAYS
2962 };
2963
2964 /**
2965  * Update the on-disk chain state.
2966  * The caches and indexes are flushed depending on the mode we're called with
2967  * if they're too large, if it's been a while since the last write,
2968  * or always and in all cases if we're in prune mode and are deleting files.
2969  */
2970 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
2971     LOCK2(cs_main, cs_LastBlockFile);
2972     static int64_t nLastWrite = 0;
2973     static int64_t nLastFlush = 0;
2974     static int64_t nLastSetChain = 0;
2975     std::set<int> setFilesToPrune;
2976     bool fFlushForPrune = false;
2977     try {
2978         if (fPruneMode && fCheckForPruning && !fReindex) {
2979             FindFilesToPrune(setFilesToPrune);
2980             fCheckForPruning = false;
2981             if (!setFilesToPrune.empty()) {
2982                 fFlushForPrune = true;
2983                 if (!fHavePruned) {
2984                     pblocktree->WriteFlag("prunedblockfiles", true);
2985                     fHavePruned = true;
2986                 }
2987             }
2988         }
2989         int64_t nNow = GetTimeMicros();
2990         // Avoid writing/flushing immediately after startup.
2991         if (nLastWrite == 0) {
2992             nLastWrite = nNow;
2993         }
2994         if (nLastFlush == 0) {
2995             nLastFlush = nNow;
2996         }
2997         if (nLastSetChain == 0) {
2998             nLastSetChain = nNow;
2999         }
3000         size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3001         // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3002         bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3003         // The cache is over the limit, we have to write now.
3004         bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3005         // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash.
3006         bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3007         // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3008         bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3009         // Combine all conditions that result in a full cache flush.
3010         bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3011         // Write blocks and block index to disk.
3012         if (fDoFullFlush || fPeriodicWrite) {
3013             // Depend on nMinDiskSpace to ensure we can write block index
3014             if (!CheckDiskSpace(0))
3015                 return state.Error("out of disk space");
3016             // First make sure all block and undo data is flushed to disk.
3017             FlushBlockFile();
3018             // Then update all block file information (which may refer to block and undo files).
3019             {
3020                 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3021                 vFiles.reserve(setDirtyFileInfo.size());
3022                 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3023                     vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3024                     setDirtyFileInfo.erase(it++);
3025                 }
3026                 std::vector<const CBlockIndex*> vBlocks;
3027                 vBlocks.reserve(setDirtyBlockIndex.size());
3028                 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3029                     vBlocks.push_back(*it);
3030                     setDirtyBlockIndex.erase(it++);
3031                 }
3032                 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3033                     return AbortNode(state, "Files to write to block index database");
3034                 }
3035             }
3036             // Finally remove any pruned files
3037             if (fFlushForPrune)
3038                 UnlinkPrunedFiles(setFilesToPrune);
3039             nLastWrite = nNow;
3040         }
3041         // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3042         if (fDoFullFlush) {
3043             // Typical CCoins structures on disk are around 128 bytes in size.
3044             // Pushing a new one to the database can cause it to be written
3045             // twice (once in the log, and once in the tables). This is already
3046             // an overestimation, as most will delete an existing entry or
3047             // overwrite one. Still, use a conservative safety factor of 2.
3048             if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3049                 return state.Error("out of disk space");
3050             // Flush the chainstate (which may refer to block index entries).
3051             if (!pcoinsTip->Flush())
3052                 return AbortNode(state, "Failed to write to coin database");
3053             nLastFlush = nNow;
3054         }
3055         if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3056             // Update best block in wallet (so we can detect restored wallets).
3057             GetMainSignals().SetBestChain(chainActive.GetLocator());
3058             nLastSetChain = nNow;
3059         }
3060     } catch (const std::runtime_error& e) {
3061         return AbortNode(state, std::string("System error while flushing: ") + e.what());
3062     }
3063     return true;
3064 }
3065
3066 void FlushStateToDisk() {
3067     CValidationState state;
3068     FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3069 }
3070
3071 void PruneAndFlush() {
3072     CValidationState state;
3073     fCheckForPruning = true;
3074     FlushStateToDisk(state, FLUSH_STATE_NONE);
3075 }
3076
3077 /** Update chainActive and related internal data structures. */
3078 void static UpdateTip(CBlockIndex *pindexNew) {
3079     const CChainParams& chainParams = Params();
3080     chainActive.SetTip(pindexNew);
3081     
3082     // New best block
3083     nTimeBestReceived = GetTime();
3084     mempool.AddTransactionsUpdated(1);
3085     KOMODO_NEWBLOCKS++;
3086     LogPrintf("%s: new best=%s  height=%d  log2_work=%.8g  tx=%lu  date=%s progress=%f  cache=%.1fMiB(%utx)\n", __func__,
3087               chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
3088               DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
3089               Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3090     
3091     cvBlockChange.notify_all();
3092     
3093     // Check the version of the last 100 blocks to see if we need to upgrade:
3094     static bool fWarned = false;
3095     if (!IsInitialBlockDownload() && !fWarned)
3096     {
3097         int nUpgraded = 0;
3098         const CBlockIndex* pindex = chainActive.Tip();
3099         for (int i = 0; i < 100 && pindex != NULL; i++)
3100         {
3101             if (pindex->nVersion > CBlock::CURRENT_VERSION)
3102                 ++nUpgraded;
3103             pindex = pindex->pprev;
3104         }
3105         if (nUpgraded > 0)
3106             LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3107         if (nUpgraded > 100/2)
3108         {
3109             // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3110             strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3111             CAlert::Notify(strMiscWarning, true);
3112             fWarned = true;
3113         }
3114     }
3115 }
3116
3117 /**
3118  * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3119  * mempool.removeWithoutBranchId after this, with cs_main held.
3120  */
3121 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3122     CBlockIndex *pindexDelete = chainActive.Tip();
3123     assert(pindexDelete);
3124     // Read block from disk.
3125     CBlock block;
3126     if (!ReadBlockFromDisk(block, pindexDelete,1))
3127         return AbortNode(state, "Failed to read block");
3128     // Apply the block atomically to the chain state.
3129     uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
3130     int64_t nStart = GetTimeMicros();
3131     {
3132         CCoinsViewCache view(pcoinsTip);
3133         if (!DisconnectBlock(block, state, pindexDelete, view))
3134             return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3135         assert(view.Flush());
3136     }
3137     LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3138     uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor();
3139     // Write the chain state to disk, if necessary.
3140     if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3141         return false;
3142     
3143     if (!fBare) {
3144         // resurrect mempool transactions from the disconnected block.
3145         for (int i = 0; i < block.vtx.size(); i++)
3146         {
3147             // ignore validation errors in resurrected transactions
3148             CTransaction &tx = block.vtx[i];
3149             list<CTransaction> removed;
3150             CValidationState stateDummy;
3151             // don't keep staking or invalid transactions
3152             if (tx.IsCoinBase() || (block.IsVerusPOSBlock() && (i == (block.vtx.size() - 1))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3153             {
3154                 mempool.remove(tx, removed, true);
3155             }
3156         }
3157         if (anchorBeforeDisconnect != anchorAfterDisconnect) {
3158             // The anchor may not change between block disconnects,
3159             // in which case we don't want to evict from the mempool yet!
3160             mempool.removeWithAnchor(anchorBeforeDisconnect);
3161         }
3162     }
3163     
3164     // Update chainActive and related variables.
3165     UpdateTip(pindexDelete->pprev);
3166     // Get the current commitment tree
3167     ZCIncrementalMerkleTree newTree;
3168     assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), newTree));
3169     // Let wallets know transactions went from 1-confirmed to
3170     // 0-confirmed or conflicted:
3171     for (int i = 0; i < block.vtx.size(); i++)
3172     {
3173         CTransaction &tx = block.vtx[i];
3174         if (block.IsVerusPOSBlock() && (i == (block.vtx.size() - 1)))
3175         {
3176             EraseFromWallets(tx.GetHash());
3177         }
3178         else
3179         {
3180             SyncWithWallets(tx, NULL);
3181         }
3182     }
3183     // Update cached incremental witnesses
3184     //fprintf(stderr,"chaintip false\n");
3185     GetMainSignals().ChainTip(pindexDelete, &block, newTree, false);
3186     return true;
3187 }
3188
3189 static int64_t nTimeReadFromDisk = 0;
3190 static int64_t nTimeConnectTotal = 0;
3191 static int64_t nTimeFlush = 0;
3192 static int64_t nTimeChainState = 0;
3193 static int64_t nTimePostConnect = 0;
3194
3195 /**
3196  * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3197  * corresponding to pindexNew, to bypass loading it again from disk.
3198  * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3199  */
3200 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3201     
3202     assert(pindexNew->pprev == chainActive.Tip());
3203     // Read block from disk.
3204     int64_t nTime1 = GetTimeMicros();
3205     CBlock block;
3206     if (!pblock) {
3207         if (!ReadBlockFromDisk(block, pindexNew,1))
3208             return AbortNode(state, "Failed to read block");
3209         pblock = &block;
3210     }
3211     // Get the current commitment tree
3212     ZCIncrementalMerkleTree oldTree;
3213     assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree));
3214     // Apply the block atomically to the chain state.
3215     int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3216     int64_t nTime3;
3217     LogPrint("bench", "  - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3218     {
3219         CCoinsViewCache view(pcoinsTip);
3220         bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3221         GetMainSignals().BlockChecked(*pblock, state);
3222         if (!rv) {
3223             if (state.IsInvalid())
3224                 InvalidBlockFound(pindexNew, state);
3225             return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3226         }
3227         mapBlockSource.erase(pindexNew->GetBlockHash());
3228         nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3229         LogPrint("bench", "  - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3230         assert(view.Flush());
3231     }
3232     int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3233     LogPrint("bench", "  - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3234     // Write the chain state to disk, if necessary.
3235     if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3236         return false;
3237     int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3238     LogPrint("bench", "  - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3239     // Remove conflicting transactions from the mempool.
3240     list<CTransaction> txConflicted;
3241     mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
3242     
3243     // Remove transactions that expire at new block height from mempool
3244     mempool.removeExpired(pindexNew->nHeight);
3245     
3246     // Update chainActive & related variables.
3247     UpdateTip(pindexNew);
3248     // Tell wallet about transactions that went from mempool
3249     // to conflicted:
3250     BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3251         SyncWithWallets(tx, NULL);
3252     }
3253     // ... and about transactions that got confirmed:
3254     BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3255         SyncWithWallets(tx, pblock);
3256     }
3257     // Update cached incremental witnesses
3258     //fprintf(stderr,"chaintip true\n");
3259     GetMainSignals().ChainTip(pindexNew, pblock, oldTree, true);
3260     
3261     EnforceNodeDeprecation(pindexNew->nHeight);
3262     
3263     int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3264     LogPrint("bench", "  - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3265     LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3266     if ( ASSETCHAINS_SYMBOL[0] == 0 )
3267         komodo_broadcast(pblock,8);
3268     return true;
3269 }
3270
3271 /**
3272  * Return the tip of the chain with the most work in it, that isn't
3273  * known to be invalid (it's however far from certain to be valid).
3274  */
3275 static CBlockIndex* FindMostWorkChain() {
3276     do {
3277         CBlockIndex *pindexNew = NULL;
3278         
3279         // Find the best candidate header.
3280         {
3281             std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3282             if (it == setBlockIndexCandidates.rend())
3283                 return NULL;
3284             pindexNew = *it;
3285         }
3286         
3287         // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3288         // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3289         CBlockIndex *pindexTest = pindexNew;
3290         bool fInvalidAncestor = false;
3291         while (pindexTest && !chainActive.Contains(pindexTest)) {
3292             assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
3293             
3294             // Pruned nodes may have entries in setBlockIndexCandidates for
3295             // which block files have been deleted.  Remove those as candidates
3296             // for the most work chain if we come across them; we can't switch
3297             // to a chain unless we have all the non-active-chain parent blocks.
3298             bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3299             bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3300             if (fFailedChain || fMissingData) {
3301                 // Candidate chain is not usable (either invalid or missing data)
3302                 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
3303                     pindexBestInvalid = pindexNew;
3304                 CBlockIndex *pindexFailed = pindexNew;
3305                 // Remove the entire chain from the set.
3306                 while (pindexTest != pindexFailed) {
3307                     if (fFailedChain) {
3308                         pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3309                     } else if (fMissingData) {
3310                         // If we're missing data, then add back to mapBlocksUnlinked,
3311                         // so that if the block arrives in the future we can try adding
3312                         // to setBlockIndexCandidates again.
3313                         mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3314                     }
3315                     setBlockIndexCandidates.erase(pindexFailed);
3316                     pindexFailed = pindexFailed->pprev;
3317                 }
3318                 setBlockIndexCandidates.erase(pindexTest);
3319                 fInvalidAncestor = true;
3320                 break;
3321             }
3322             pindexTest = pindexTest->pprev;
3323         }
3324         if (!fInvalidAncestor)
3325             return pindexNew;
3326     } while(true);
3327 }
3328
3329 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3330 static void PruneBlockIndexCandidates() {
3331     // Note that we can't delete the current block itself, as we may need to return to it later in case a
3332     // reorganization to a better block fails.
3333     std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3334     while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
3335         setBlockIndexCandidates.erase(it++);
3336     }
3337     // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3338     assert(!setBlockIndexCandidates.empty());
3339 }
3340
3341 /**
3342  * Try to make some progress towards making pindexMostWork the active block.
3343  * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3344  */
3345 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3346     AssertLockHeld(cs_main);
3347     bool fInvalidFound = false;
3348     const CBlockIndex *pindexOldTip = chainActive.Tip();
3349     const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3350
3351     // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3352     // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3353     //   then pindexFork will be null, and we would need to remove the entire chain including
3354     //   our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3355     auto reorgLength = pindexOldTip ? pindexOldTip->nHeight - (pindexFork ? pindexFork->nHeight : -1) : 0;
3356     static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3357     if (reorgLength > MAX_REORG_LENGTH) {
3358         auto msg = strprintf(_(
3359                                "A block chain reorganization has been detected that would roll back %d blocks! "
3360                                "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3361                                ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3362         _("Reorganization details") + ":\n" +
3363         "- " + strprintf(_("Current tip: %s, height %d, work %s"),
3364                          pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" +
3365         "- " + strprintf(_("New tip:     %s, height %d, work %s"),
3366                          pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" +
3367         "- " + strprintf(_("Fork point:  %s %s, height %d"),
3368                          ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" +
3369         _("Please help, human!");
3370         LogPrintf("*** %s\n", msg);
3371         uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3372         StartShutdown();
3373         return false;
3374     }
3375     
3376     // Disconnect active blocks which are no longer in the best chain.
3377     bool fBlocksDisconnected = false;
3378     while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3379         if (!DisconnectTip(state))
3380             return false;
3381         fBlocksDisconnected = true;
3382     }
3383     if ( KOMODO_REWIND != 0 )
3384     {
3385         CBlockIndex *tipindex;
3386         fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.Tip()->nHeight,KOMODO_REWIND);
3387         while ( KOMODO_REWIND > 0 && (tipindex= chainActive.Tip()) != 0 && tipindex->nHeight > KOMODO_REWIND )
3388         {
3389             fBlocksDisconnected = true;
3390             fprintf(stderr,"%d ",(int32_t)tipindex->nHeight);
3391             InvalidateBlock(state,tipindex);
3392             if ( !DisconnectTip(state) )
3393                 break;
3394         }
3395         fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3396         sleep(20);
3397         fprintf(stderr,"resuming normal operations\n");
3398         KOMODO_REWIND = 0;
3399         //return(true);
3400     }
3401     // Build list of new blocks to connect.
3402     std::vector<CBlockIndex*> vpindexToConnect;
3403     bool fContinue = true;
3404     int nHeight = pindexFork ? pindexFork->nHeight : -1;
3405     while (fContinue && nHeight != pindexMostWork->nHeight) {
3406         // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3407         // a few blocks along the way.
3408         int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
3409         vpindexToConnect.clear();
3410         vpindexToConnect.reserve(nTargetHeight - nHeight);
3411         CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3412         while (pindexIter && pindexIter->nHeight != nHeight) {
3413             vpindexToConnect.push_back(pindexIter);
3414             pindexIter = pindexIter->pprev;
3415         }
3416         nHeight = nTargetHeight;
3417         
3418         // Connect new blocks.
3419         BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
3420             if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
3421                 if (state.IsInvalid()) {
3422                     // The block violates a consensus rule.
3423                     if (!state.CorruptionPossible())
3424                         InvalidChainFound(vpindexToConnect.back());
3425                     state = CValidationState();
3426                     fInvalidFound = true;
3427                     fContinue = false;
3428                     break;
3429                 } else {
3430                     // A system error occurred (disk space, database error, ...).
3431                     return false;
3432                 }
3433             } else {
3434                 PruneBlockIndexCandidates();
3435                 if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
3436                     // We're in a better position than we were. Return temporarily to release the lock.
3437                     fContinue = false;
3438                     break;
3439                 }
3440             }
3441         }
3442     }
3443     
3444     if (fBlocksDisconnected) {
3445         mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3446     }
3447     mempool.removeWithoutBranchId(
3448                                   CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3449     mempool.check(pcoinsTip);
3450     
3451     // Callbacks/notifications for a new best chain.
3452     if (fInvalidFound)
3453         CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
3454     else
3455         CheckForkWarningConditions();
3456     
3457     return true;
3458 }
3459
3460 /**
3461  * Make the best chain active, in multiple steps. The result is either failure
3462  * or an activated best chain. pblock is either NULL or a pointer to a block
3463  * that is already loaded (to avoid loading it again from disk).
3464  */
3465 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
3466     CBlockIndex *pindexNewTip = NULL;
3467     CBlockIndex *pindexMostWork = NULL;
3468     const CChainParams& chainParams = Params();
3469     do {
3470         boost::this_thread::interruption_point();
3471         
3472         bool fInitialDownload;
3473         {
3474             LOCK(cs_main);
3475             pindexMostWork = FindMostWorkChain();
3476             
3477             // Whether we have anything to do at all.
3478             if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
3479                 return true;
3480             
3481             if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
3482                 return false;
3483             pindexNewTip = chainActive.Tip();
3484             fInitialDownload = IsInitialBlockDownload();
3485         }
3486         // When we reach this point, we switched to a new tip (stored in pindexNewTip).
3487         
3488         // Notifications/callbacks that can run without cs_main
3489         if (!fInitialDownload) {
3490             uint256 hashNewTip = pindexNewTip->GetBlockHash();
3491             // Relay inventory, but don't relay old inventory during initial block download.
3492             int nBlockEstimate = 0;
3493             if (fCheckpointsEnabled)
3494                 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
3495             // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
3496             // in a stalled download if the block file is pruned before the request.
3497             if (nLocalServices & NODE_NETWORK) {
3498                 LOCK(cs_vNodes);
3499                 BOOST_FOREACH(CNode* pnode, vNodes)
3500                 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
3501                     pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
3502             }
3503             // Notify external listeners about the new tip.
3504             GetMainSignals().UpdatedBlockTip(pindexNewTip);
3505             uiInterface.NotifyBlockTip(hashNewTip);
3506         } //else fprintf(stderr,"initial download skips propagation\n");
3507     } while(pindexMostWork != chainActive.Tip());
3508     CheckBlockIndex();
3509     
3510     // Write changes periodically to disk, after relay.
3511     if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
3512         return false;
3513     }
3514     
3515     return true;
3516 }
3517
3518 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
3519     AssertLockHeld(cs_main);
3520     
3521     // Mark the block itself as invalid.
3522     pindex->nStatus |= BLOCK_FAILED_VALID;
3523     setDirtyBlockIndex.insert(pindex);
3524     setBlockIndexCandidates.erase(pindex);
3525     
3526     while (chainActive.Contains(pindex)) {
3527         CBlockIndex *pindexWalk = chainActive.Tip();
3528         pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
3529         setDirtyBlockIndex.insert(pindexWalk);
3530         setBlockIndexCandidates.erase(pindexWalk);
3531         // ActivateBestChain considers blocks already in chainActive
3532         // unconditionally valid already, so force disconnect away from it.
3533         if (!DisconnectTip(state)) {
3534             mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3535             mempool.removeWithoutBranchId(
3536                                           CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3537             return false;
3538         }
3539     }
3540     //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
3541     
3542     // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
3543     // add it again.
3544     BlockMap::iterator it = mapBlockIndex.begin();
3545     while (it != mapBlockIndex.end() && it->second != 0 ) {
3546         if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
3547             setBlockIndexCandidates.insert(it->second);
3548         }
3549         it++;
3550     }
3551     
3552     InvalidChainFound(pindex);
3553     mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3554     mempool.removeWithoutBranchId(
3555                                   CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3556     return true;
3557 }
3558
3559 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
3560     AssertLockHeld(cs_main);
3561     
3562     int nHeight = pindex->nHeight;
3563     
3564     // Remove the invalidity flag from this block and all its descendants.
3565     BlockMap::iterator it = mapBlockIndex.begin();
3566     while (it != mapBlockIndex.end()) {
3567         if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
3568             it->second->nStatus &= ~BLOCK_FAILED_MASK;
3569             setDirtyBlockIndex.insert(it->second);
3570             if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
3571                 setBlockIndexCandidates.insert(it->second);
3572             }
3573             if (it->second == pindexBestInvalid) {
3574                 // Reset invalid block marker if it was pointing to one of those.
3575                 pindexBestInvalid = NULL;
3576             }
3577         }
3578         it++;
3579     }
3580     
3581     // Remove the invalidity flag from all ancestors too.
3582     while (pindex != NULL) {
3583         if (pindex->nStatus & BLOCK_FAILED_MASK) {
3584             pindex->nStatus &= ~BLOCK_FAILED_MASK;
3585             setDirtyBlockIndex.insert(pindex);
3586         }
3587         pindex = pindex->pprev;
3588     }
3589     return true;
3590 }
3591
3592 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
3593 {
3594     // Check for duplicate
3595     uint256 hash = block.GetHash();
3596     BlockMap::iterator it = mapBlockIndex.find(hash);
3597     BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
3598     if (it != mapBlockIndex.end())
3599     {
3600         if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
3601         {
3602             // this is the strange case where somehow the hash is in the mapBlockIndex via as yet undetermined process, but the pindex for the hash is not there. Theoretically it is due to processing the block headers, but I have seen it get this case without having received it from the block headers or anywhere else... jl777
3603             //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
3604             return it->second;
3605         }
3606         if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
3607         {
3608             //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
3609             return(0); // return here to avoid the state of pindex->nHeight not set and pprev NULL
3610         }
3611     }
3612     // Construct new block index object
3613     CBlockIndex* pindexNew = new CBlockIndex(block);
3614     assert(pindexNew);
3615     // We assign the sequence id to blocks only when the full data is available,
3616     // to avoid miners withholding blocks but broadcasting headers, to get a
3617     // competitive advantage.
3618     pindexNew->nSequenceId = 0;
3619     BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
3620     pindexNew->phashBlock = &((*mi).first);
3621     if (miPrev != mapBlockIndex.end())
3622     {
3623         if ( (pindexNew->pprev= (*miPrev).second) != 0 )
3624             pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
3625         else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
3626         pindexNew->BuildSkip();
3627     }
3628     pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
3629     pindexNew->RaiseValidity(BLOCK_VALID_TREE);
3630     if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
3631         pindexBestHeader = pindexNew;
3632     
3633     setDirtyBlockIndex.insert(pindexNew);
3634     //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
3635     mi->second = pindexNew;
3636     return pindexNew;
3637 }
3638
3639 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
3640 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
3641 {
3642     pindexNew->nTx = block.vtx.size();
3643     pindexNew->nChainTx = 0;
3644     CAmount sproutValue = 0;
3645     for (auto tx : block.vtx) {
3646         for (auto js : tx.vjoinsplit) {
3647             sproutValue += js.vpub_old;
3648             sproutValue -= js.vpub_new;
3649         }
3650     }
3651     pindexNew->nSproutValue = sproutValue;
3652     pindexNew->nChainSproutValue = boost::none;
3653     pindexNew->nFile = pos.nFile;
3654     pindexNew->nDataPos = pos.nPos;
3655     pindexNew->nUndoPos = 0;
3656     pindexNew->nStatus |= BLOCK_HAVE_DATA;
3657     pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
3658     setDirtyBlockIndex.insert(pindexNew);
3659     
3660     if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
3661         // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
3662         deque<CBlockIndex*> queue;
3663         queue.push_back(pindexNew);
3664         
3665         // Recursively process any descendant blocks that now may be eligible to be connected.
3666         while (!queue.empty()) {
3667             CBlockIndex *pindex = queue.front();
3668             queue.pop_front();
3669             pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
3670             if (pindex->pprev) {
3671                 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
3672                     pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
3673                 } else {
3674                     pindex->nChainSproutValue = boost::none;
3675                 }
3676             } else {
3677                 pindex->nChainSproutValue = pindex->nSproutValue;
3678             }
3679             {
3680                 LOCK(cs_nBlockSequenceId);
3681                 pindex->nSequenceId = nBlockSequenceId++;
3682             }
3683             if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
3684                 setBlockIndexCandidates.insert(pindex);
3685             }
3686             std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
3687             while (range.first != range.second) {
3688                 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3689                 queue.push_back(it->second);
3690                 range.first++;
3691                 mapBlocksUnlinked.erase(it);
3692             }
3693         }
3694     } else {
3695         if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
3696             mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
3697         }
3698     }
3699     
3700     return true;
3701 }
3702
3703 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
3704 {
3705     LOCK(cs_LastBlockFile);
3706     
3707     unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
3708     if (vinfoBlockFile.size() <= nFile) {
3709         vinfoBlockFile.resize(nFile + 1);
3710     }
3711     
3712     if (!fKnown) {
3713         while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
3714             nFile++;
3715             if (vinfoBlockFile.size() <= nFile) {
3716                 vinfoBlockFile.resize(nFile + 1);
3717             }
3718         }
3719         pos.nFile = nFile;
3720         pos.nPos = vinfoBlockFile[nFile].nSize;
3721     }
3722     
3723     if (nFile != nLastBlockFile) {
3724         if (!fKnown) {
3725             LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
3726         }
3727         FlushBlockFile(!fKnown);
3728         nLastBlockFile = nFile;
3729     }
3730     
3731     vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
3732     if (fKnown)
3733         vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3734     else
3735         vinfoBlockFile[nFile].nSize += nAddSize;
3736     
3737     if (!fKnown) {
3738         unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3739         unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3740         if (nNewChunks > nOldChunks) {
3741             if (fPruneMode)
3742                 fCheckForPruning = true;
3743             if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
3744                 FILE *file = OpenBlockFile(pos);
3745                 if (file) {
3746                     LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
3747                     AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
3748                     fclose(file);
3749                 }
3750             }
3751             else
3752                 return state.Error("out of disk space");
3753         }
3754     }
3755     
3756     setDirtyFileInfo.insert(nFile);
3757     return true;
3758 }
3759
3760 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
3761 {
3762     pos.nFile = nFile;
3763     
3764     LOCK(cs_LastBlockFile);
3765     
3766     unsigned int nNewSize;
3767     pos.nPos = vinfoBlockFile[nFile].nUndoSize;
3768     nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
3769     setDirtyFileInfo.insert(nFile);
3770     
3771     unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3772     unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3773     if (nNewChunks > nOldChunks) {
3774         if (fPruneMode)
3775             fCheckForPruning = true;
3776         if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
3777             FILE *file = OpenUndoFile(pos);
3778             if (file) {
3779                 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
3780                 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
3781                 fclose(file);
3782             }
3783         }
3784         else
3785             return state.Error("out of disk space");
3786     }
3787     
3788     return true;
3789 }
3790
3791 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
3792 {
3793     // Check timestamp
3794     if ( 0 )
3795     {
3796         uint256 hash; int32_t i;
3797         hash = blockhdr.GetHash();
3798         for (i=31; i>=0; i--)
3799             fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
3800         fprintf(stderr," <- CheckBlockHeader\n");
3801         if ( chainActive.Tip() != 0 )
3802         {
3803             hash = chainActive.Tip()->GetBlockHash();
3804             for (i=31; i>=0; i--)
3805                 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
3806             fprintf(stderr," <- chainTip\n");
3807         }
3808     }
3809     *futureblockp = 0;
3810     if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
3811     {
3812         CBlockIndex *tipindex;
3813         //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
3814         if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
3815         {
3816             //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
3817             while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
3818                 sleep(1);
3819             //fprintf(stderr,"now its valid\n");
3820         }
3821         else
3822         {
3823             if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
3824                 *futureblockp = 1;
3825             LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
3826             return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
3827         }
3828     }
3829     // Check block version
3830     if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
3831         return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
3832     
3833     // Check Equihash solution is valid
3834     if ( fCheckPOW )
3835     {
3836         if ( !CheckEquihashSolution(&blockhdr, Params()) )
3837             return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
3838     }
3839     // Check proof of work matches claimed amount
3840     /*komodo_index2pubkey33(pubkey33,pindex,height);
3841      if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
3842      return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
3843     return true;
3844 }
3845
3846 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
3847 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
3848
3849 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
3850                 libzcash::ProofVerifier& verifier,
3851                 bool fCheckPOW, bool fCheckMerkleRoot)
3852 {
3853     uint8_t pubkey33[33]; uint256 hash;
3854     // These are checks that are independent of context.
3855     hash = block.GetHash();
3856    
3857     // Check that the header is valid (particularly PoW).  This is mostly
3858     // redundant with the call in AcceptBlockHeader.
3859     if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
3860     {
3861         if ( *futureblockp == 0 )
3862         {
3863             LogPrintf("CheckBlock header error");
3864             return false;
3865         }
3866     }
3867     if ( fCheckPOW )
3868     {
3869         //if ( !CheckEquihashSolution(&block, Params()) )
3870         //    return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
3871         komodo_block2pubkey33(pubkey33,(CBlock *)&block);
3872         if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
3873         {
3874             int32_t z; for (z=31; z>=0; z--)
3875                 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
3876             fprintf(stderr," failed hash ht.%d\n",height);
3877             return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
3878         }
3879         if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
3880             return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
3881     }
3882     // Check the merkle root.
3883     if (fCheckMerkleRoot) {
3884         bool mutated;
3885         uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
3886         if (block.hashMerkleRoot != hashMerkleRoot2)
3887             return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
3888                              REJECT_INVALID, "bad-txnmrklroot", true);
3889         
3890         // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
3891         // of transactions in a block without affecting the merkle root of a block,
3892         // while still invalidating it.
3893         if (mutated)
3894             return state.DoS(100, error("CheckBlock: duplicate transaction"),
3895                              REJECT_INVALID, "bad-txns-duplicate", true);
3896     }
3897     
3898     // All potential-corruption validation must be done before we do any
3899     // transaction validation, as otherwise we may mark the header as invalid
3900     // because we receive the wrong transactions for it.
3901     
3902     // Size limits
3903     if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
3904         return state.DoS(100, error("CheckBlock: size limits failed"),
3905                          REJECT_INVALID, "bad-blk-length");
3906     
3907     // First transaction must be coinbase, the rest must not be
3908     if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
3909         return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
3910                          REJECT_INVALID, "bad-cb-missing");
3911
3912     for (unsigned int i = 1; i < block.vtx.size(); i++)
3913         if (block.vtx[i].IsCoinBase())
3914             return state.DoS(100, error("CheckBlock: more than one coinbase"),
3915                              REJECT_INVALID, "bad-cb-multiple");
3916     
3917     // Check transactions
3918     BOOST_FOREACH(const CTransaction& tx, block.vtx)
3919     {
3920         if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
3921             return error("CheckBlock: komodo_validate_interest failed");
3922         if (!CheckTransaction(tx, state, verifier))
3923             return error("CheckBlock: CheckTransaction failed");
3924     }
3925     unsigned int nSigOps = 0;
3926     BOOST_FOREACH(const CTransaction& tx, block.vtx)
3927     {
3928         nSigOps += GetLegacySigOpCount(tx);
3929     }
3930     if (nSigOps > MAX_BLOCK_SIGOPS)
3931         return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
3932                          REJECT_INVALID, "bad-blk-sigops", true);
3933     if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
3934     {
3935         //static uint32_t counter;
3936         //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
3937         //    fprintf(stderr,"check deposit rejection\n");
3938         LogPrintf("CheckBlockHeader komodo_check_deposit error");
3939         return(false);
3940     }
3941     return true;
3942 }
3943
3944 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
3945 {
3946     const CChainParams& chainParams = Params();
3947     const Consensus::Params& consensusParams = chainParams.GetConsensus();
3948     uint256 hash = block.GetHash();
3949     if (hash == consensusParams.hashGenesisBlock)
3950         return true;
3951     
3952     assert(pindexPrev);
3953     
3954     int nHeight = pindexPrev->nHeight+1;
3955
3956     // Check proof of work
3957     if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
3958     {
3959         cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << 
3960                                " for block #" << nHeight << endl;
3961         return state.DoS(100, error("%s: incorrect proof of work", __func__),
3962                         REJECT_INVALID, "bad-diffbits");
3963     }
3964     
3965     // Check timestamp against prev
3966     if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
3967     {
3968         return state.Invalid(error("%s: block's timestamp is too early", __func__),
3969                         REJECT_INVALID, "time-too-old");
3970     }
3971
3972     // Check that timestamp is not too far in the future
3973     if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
3974     {
3975         return state.Invalid(error("%s: block timestamp too far in the future", __func__),
3976                         REJECT_INVALID, "time-too-new");
3977     }
3978
3979     if (fCheckpointsEnabled)
3980     {
3981         // Check that the block chain matches the known block chain up to a checkpoint
3982         if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
3983         {
3984             /*CBlockIndex *heightblock = chainActive[nHeight];
3985             if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
3986             {
3987                 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
3988                 return true;
3989             }*/
3990             return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
3991         }
3992         // Don't accept any forks from the main chain prior to last checkpoint
3993         CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
3994         int32_t notarized_height;
3995         if (pcheckpoint && nHeight > 1 && nHeight < pcheckpoint->nHeight )
3996             return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->nHeight));
3997         else if ( komodo_checkpoint(&notarized_height,nHeight,hash) < 0 )
3998         {
3999             CBlockIndex *heightblock = chainActive[nHeight];
4000             if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4001             {
4002                 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4003                 return true;
4004             } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4005         }
4006     }
4007     // Reject block.nVersion < 4 blocks
4008     if (block.nVersion < 4)
4009         return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4010                              REJECT_OBSOLETE, "bad-version");
4011     
4012     return true;
4013 }
4014
4015 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4016 {
4017     const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
4018     const Consensus::Params& consensusParams = Params().GetConsensus();
4019     
4020     // Check that all transactions are finalized
4021     BOOST_FOREACH(const CTransaction& tx, block.vtx) {
4022         
4023         // Check transaction contextually against consensus rules at block height
4024         if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4025             return false; // Failure reason has been set in validation state object
4026         }
4027
4028         int nLockTimeFlags = 0;
4029         int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4030         ? pindexPrev->GetMedianTimePast()
4031         : block.GetBlockTime();
4032         if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4033             return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4034         }
4035     }
4036     
4037     // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4038     // In Zcash this has been enforced since launch, except that the genesis
4039     // block didn't include the height in the coinbase (see Zcash protocol spec
4040     // section '6.8 Bitcoin Improvement Proposals').
4041     if (nHeight > 0)
4042     {
4043         CScript expect = CScript() << nHeight;
4044         if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4045             !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4046             return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4047         }
4048     }
4049     return true;
4050 }
4051
4052 //static uint256 komodo_requestedhash;
4053 //static int32_t komodo_requestedcount;
4054
4055 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4056 {
4057     static uint256 zero;
4058     const CChainParams& chainparams = Params();
4059     AssertLockHeld(cs_main);
4060
4061     // Check for duplicate
4062     uint256 hash = block.GetHash();
4063     BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4064     CBlockIndex *pindex = NULL;
4065     if (miSelf != mapBlockIndex.end())
4066     {
4067         // Block header is already known.
4068         if ( (pindex= miSelf->second) == 0 )
4069             miSelf->second = pindex = AddToBlockIndex(block);
4070         if (ppindex)
4071             *ppindex = pindex;
4072         if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4073             return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4074         /*if ( pindex != 0 && hash == komodo_requestedhash )
4075         {
4076             fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4077             memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4078             komodo_requestedcount = 0;
4079         }*/
4080
4081         //if ( pindex == 0 )
4082         //    fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4083         return true;
4084     }
4085     if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
4086     {
4087         if ( *futureblockp == 0 )
4088         {
4089             LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4090             return false;
4091         }
4092     }
4093     // Get prev block index
4094     CBlockIndex* pindexPrev = NULL;
4095     if (hash != chainparams.GetConsensus().hashGenesisBlock)
4096     {
4097         BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4098         if (mi == mapBlockIndex.end())
4099         {
4100             //fprintf(stderr,"AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4101             /*if ( komodo_requestedhash == zero )
4102             {
4103                 komodo_requestedhash = block.hashPrevBlock;
4104                 komodo_requestedcount = 0;
4105             }*/
4106             LogPrintf("AcceptBlockHeader %s\n hashPrevBlock %s not found\n", hash.ToString().c_str(), block.hashPrevBlock.ToString().c_str());
4107             return(false);
4108             //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4109         }
4110         pindexPrev = (*mi).second;
4111         if (pindexPrev == 0 )
4112         {
4113             /*fprintf(stderr,"AcceptBlockHeader failed no pindexPrev %s\n",block.hashPrevBlock.ToString().c_str());
4114             if ( komodo_requestedhash == zero )
4115             {
4116                 komodo_requestedhash = block.hashPrevBlock;
4117                 komodo_requestedcount = 0;
4118             }*/
4119             LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4120             return(false);
4121         }
4122         if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4123             return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4124     }
4125     if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4126     {
4127         //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4128         LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4129         return false;
4130     }
4131     if (pindex == NULL)
4132     {
4133         if ( (pindex= AddToBlockIndex(block)) != 0 )
4134         {
4135             miSelf = mapBlockIndex.find(hash);
4136             if (miSelf != mapBlockIndex.end())
4137                 miSelf->second = pindex;
4138             //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4139         }
4140     }
4141     if (ppindex)
4142         *ppindex = pindex;
4143     /*if ( pindex != 0 && hash == komodo_requestedhash )
4144     {
4145         fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4146         memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4147         komodo_requestedcount = 0;
4148     }*/
4149     return true;
4150 }
4151
4152 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4153 {
4154     const CChainParams& chainparams = Params();
4155     AssertLockHeld(cs_main);
4156     
4157     CBlockIndex *&pindex = *ppindex;
4158     if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
4159     {
4160         if ( *futureblockp == 0 )
4161         {
4162             LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4163             return false;
4164         }
4165     }
4166     if ( pindex == 0 )
4167     {
4168         LogPrintf("AcceptBlock null pindex error\n");
4169         return false;
4170     }
4171     //fprintf(stderr,"acceptblockheader passed\n");
4172     // Try to process all requested blocks that we don't have, but only
4173     // process an unrequested block if it's new and has enough work to
4174     // advance our tip, and isn't too many blocks ahead.
4175     bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4176     bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
4177     // Blocks that are too out-of-order needlessly limit the effectiveness of
4178     // pruning, because pruning will not delete block files that contain any
4179     // blocks which are too close in height to the tip.  Apply this test
4180     // regardless of whether pruning is enabled; it should generally be safe to
4181     // not process unrequested blocks.
4182     bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4183     
4184     // TODO: deal better with return value and error conditions for duplicate
4185     // and unrequested blocks.
4186     //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4187     if (fAlreadyHave) return true;
4188     if (!fRequested) {  // If we didn't ask for it:
4189         if (pindex->nTx != 0) return true;  // This is a previously-processed block that was pruned
4190         if (!fHasMoreWork) return true;     // Don't process less-work chains
4191         if (fTooFarAhead) return true;      // Block height is too high
4192     }
4193     
4194     // See method docstring for why this is always disabled
4195     auto verifier = libzcash::ProofVerifier::Disabled();
4196     if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4197     {
4198         if ( *futureblockp == 0 )
4199         {
4200             if (state.IsInvalid() && !state.CorruptionPossible()) {
4201                 pindex->nStatus |= BLOCK_FAILED_VALID;
4202                 setDirtyBlockIndex.insert(pindex);
4203             }
4204             LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4205             return false;
4206         }
4207     }
4208     
4209     int nHeight = pindex->nHeight;
4210     
4211     // Write block to history file
4212     try {
4213         unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4214         CDiskBlockPos blockPos;
4215         if (dbp != NULL)
4216             blockPos = *dbp;
4217         if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4218             return error("AcceptBlock(): FindBlockPos failed");
4219         if (dbp == NULL)
4220             if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4221                 AbortNode(state, "Failed to write block");
4222         if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4223             return error("AcceptBlock(): ReceivedBlockTransactions failed");
4224     } catch (const std::runtime_error& e) {
4225         return AbortNode(state, std::string("System error: ") + e.what());
4226     }
4227     
4228     if (fCheckForPruning)
4229         FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4230     if ( *futureblockp == 0 )
4231         return true;
4232     LogPrintf("AcceptBlock block from future error\n");
4233     return false;
4234 }
4235
4236 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4237 {
4238     unsigned int nFound = 0;
4239     for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4240     {
4241         if (pstart->nVersion >= minVersion)
4242             ++nFound;
4243         pstart = pstart->pprev;
4244     }
4245     return (nFound >= nRequired);
4246 }
4247
4248 void komodo_currentheight_set(int32_t height);
4249
4250 CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4251 {
4252     CBlockIndex *pindex = 0;
4253     BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4254     if ( miSelf != mapBlockIndex.end() )
4255     {
4256         if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4257         {
4258             miSelf->second = AddToBlockIndex(*pblock);
4259             //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4260         }
4261         /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4262         {
4263             miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4264             if ( miSelf != mapBlockIndex.end() )
4265             {
4266                 if ( miSelf->second == 0 )
4267                 {
4268                     miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4269                     fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4270                 }
4271             }
4272         }*/
4273     }
4274     return(pindex);
4275 }
4276
4277 CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
4278 {
4279     CBlockIndex *pindex=0,*previndex=0;
4280     if ( (pindex= mapBlockIndex[hash]) == 0 )
4281     {
4282         pindex = new CBlockIndex();
4283         if (!pindex)
4284             throw runtime_error("komodo_ensure: new CBlockIndex failed");
4285         BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4286         pindex->phashBlock = &((*mi).first);
4287     }
4288     BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4289     if ( miSelf == mapBlockIndex.end() )
4290     {
4291         LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4292         return(0);
4293     }
4294     if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4295     {
4296         if ( pindex == 0 )
4297         {
4298             pindex = AddToBlockIndex(*pblock);
4299             fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4300         }
4301         if ( pindex != 0 )
4302         {
4303             miSelf->second = pindex;
4304             LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4305         } else LogPrintf("komodo_ensure unexpected null pindex\n");
4306     }
4307     /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4308         {
4309             miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4310             if ( miSelf == mapBlockIndex.end() )
4311                 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4312             if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4313             {
4314                 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4315                 {
4316                     if ( previndex == 0 )
4317                         previndex = InsertBlockIndex(pblock->hashPrevBlock);
4318                     if ( previndex != 0 )
4319                     {
4320                         miSelf->second = previndex;
4321                         LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4322                     } else LogPrintf("komodo_ensure unexpected null previndex\n");
4323                 }
4324             } else LogPrintf("komodo_ensure unexpected null miprev\n");
4325         }
4326      }*/
4327     return(pindex);
4328 }
4329
4330 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
4331 {
4332     // Preliminary checks
4333     bool checked; uint256 hash; int32_t futureblock=0;
4334     auto verifier = libzcash::ProofVerifier::Disabled();
4335     hash = pblock->GetHash();
4336 //fprintf(stderr,"process newblock %s\n",hash.ToString().c_str());
4337     if ( chainActive.Tip() != 0 )
4338         komodo_currentheight_set(chainActive.Tip()->nHeight);
4339     checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
4340     {
4341         LOCK(cs_main);
4342         bool fRequested = MarkBlockAsReceived(hash);
4343         fRequested |= fForceProcessing;
4344         if ( checked != 0 && komodo_checkPOW(from_miner && ASSETCHAINS_STAKED == 0,pblock,height) < 0 )
4345         {
4346             checked = 0;
4347             fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
4348         }
4349         if (!checked && futureblock == 0)
4350         {
4351             if ( pfrom != 0 )
4352             {
4353                 Misbehaving(pfrom->GetId(), 1);
4354             }
4355             return error("%s: CheckBlock FAILED", __func__);
4356         }
4357         // Store to disk
4358         CBlockIndex *pindex = NULL;
4359         if ( 1 )
4360         {
4361             // without the komodo_ensure call, it is quite possible to get a non-error but null pindex returned from AcceptBlockHeader. In a 2 node network, it will be a long time before that block is reprocessed. Even though restarting makes it rescan, it seems much better to keep the nodes in sync
4362             komodo_ensure(pblock, hash);
4363         }
4364         bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
4365         if (pindex && pfrom) {
4366             mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
4367         }
4368         CheckBlockIndex();
4369         if (!ret && futureblock == 0)
4370             return error("%s: AcceptBlock FAILED", __func__);
4371         //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
4372     }
4373     
4374     if (futureblock == 0 && !ActivateBestChain(state, pblock))
4375         return error("%s: ActivateBestChain failed", __func__);
4376     
4377     return true;
4378 }
4379
4380 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4381 {
4382     AssertLockHeld(cs_main);
4383     assert(pindexPrev == chainActive.Tip());
4384     
4385     CCoinsViewCache viewNew(pcoinsTip);
4386     CBlockIndex indexDummy(block);
4387     indexDummy.pprev = pindexPrev;
4388     indexDummy.nHeight = pindexPrev->nHeight + 1;
4389     // JoinSplit proofs are verified in ConnectBlock
4390     auto verifier = libzcash::ProofVerifier::Disabled();
4391     // NOTE: CheckBlockHeader is called by CheckBlock
4392     if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4393     {
4394         //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
4395         return false;
4396     }
4397     int32_t futureblock;
4398     if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
4399     {
4400         //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
4401         return false;
4402     }
4403     if (!ContextualCheckBlock(block, state, pindexPrev))
4404     {
4405         //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
4406         return false;
4407     }
4408     if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
4409     {
4410         //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
4411         return false;
4412     }
4413     assert(state.IsValid());
4414     if ( futureblock != 0 )
4415         return(false);
4416     return true;
4417 }
4418
4419 /**
4420  * BLOCK PRUNING CODE
4421  */
4422
4423 /* Calculate the amount of disk space the block & undo files currently use */
4424 uint64_t CalculateCurrentUsage()
4425 {
4426     uint64_t retval = 0;
4427     BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
4428         retval += file.nSize + file.nUndoSize;
4429     }
4430     return retval;
4431 }
4432
4433 /* Prune a block file (modify associated database entries)*/
4434 void PruneOneBlockFile(const int fileNumber)
4435 {
4436     for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
4437         CBlockIndex* pindex = it->second;
4438         if (pindex->nFile == fileNumber) {
4439             pindex->nStatus &= ~BLOCK_HAVE_DATA;
4440             pindex->nStatus &= ~BLOCK_HAVE_UNDO;
4441             pindex->nFile = 0;
4442             pindex->nDataPos = 0;
4443             pindex->nUndoPos = 0;
4444             setDirtyBlockIndex.insert(pindex);
4445             
4446             // Prune from mapBlocksUnlinked -- any block we prune would have
4447             // to be downloaded again in order to consider its chain, at which
4448             // point it would be considered as a candidate for
4449             // mapBlocksUnlinked or setBlockIndexCandidates.
4450             std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
4451             while (range.first != range.second) {
4452                 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
4453                 range.first++;
4454                 if (it->second == pindex) {
4455                     mapBlocksUnlinked.erase(it);
4456                 }
4457             }
4458         }
4459     }
4460     
4461     vinfoBlockFile[fileNumber].SetNull();
4462     setDirtyFileInfo.insert(fileNumber);
4463 }
4464
4465
4466 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
4467 {
4468     for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
4469         CDiskBlockPos pos(*it, 0);
4470         boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
4471         boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
4472         LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
4473     }
4474 }
4475
4476 /* Calculate the block/rev files that should be deleted to remain under target*/
4477 void FindFilesToPrune(std::set<int>& setFilesToPrune)
4478 {
4479     LOCK2(cs_main, cs_LastBlockFile);
4480     if (chainActive.Tip() == NULL || nPruneTarget == 0) {
4481         return;
4482     }
4483     if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
4484         return;
4485     }
4486     unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
4487     uint64_t nCurrentUsage = CalculateCurrentUsage();
4488     // We don't check to prune until after we've allocated new space for files
4489     // So we should leave a buffer under our target to account for another allocation
4490     // before the next pruning.
4491     uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
4492     uint64_t nBytesToPrune;
4493     int count=0;
4494     
4495     if (nCurrentUsage + nBuffer >= nPruneTarget) {
4496         for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4497             nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
4498             
4499             if (vinfoBlockFile[fileNumber].nSize == 0)
4500                 continue;
4501             
4502             if (nCurrentUsage + nBuffer < nPruneTarget)  // are we below our target?
4503                 break;
4504             
4505             // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
4506             if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
4507                 continue;
4508             
4509             PruneOneBlockFile(fileNumber);
4510             // Queue up the files for removal
4511             setFilesToPrune.insert(fileNumber);
4512             nCurrentUsage -= nBytesToPrune;
4513             count++;
4514         }
4515     }
4516     
4517     LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
4518              nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
4519              ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4520              nLastBlockWeCanPrune, count);
4521 }
4522
4523 bool CheckDiskSpace(uint64_t nAdditionalBytes)
4524 {
4525     uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
4526     
4527     // Check for nMinDiskSpace bytes (currently 50MB)
4528     if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
4529         return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
4530     
4531     return true;
4532 }
4533
4534 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
4535 {
4536     static int32_t didinit[64];
4537     if (pos.IsNull())
4538         return NULL;
4539     boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
4540     boost::filesystem::create_directories(path.parent_path());
4541     FILE* file = fopen(path.string().c_str(), "rb+");
4542     if (!file && !fReadOnly)
4543         file = fopen(path.string().c_str(), "wb+");
4544     if (!file) {
4545         LogPrintf("Unable to open file %s\n", path.string());
4546         return NULL;
4547     }
4548     if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
4549     {
4550         komodo_prefetch(file);
4551         didinit[pos.nFile] = 1;
4552     }
4553     if (pos.nPos) {
4554         if (fseek(file, pos.nPos, SEEK_SET)) {
4555             LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
4556             fclose(file);
4557             return NULL;
4558         }
4559     }
4560     return file;
4561 }
4562
4563 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
4564     return OpenDiskFile(pos, "blk", fReadOnly);
4565 }
4566
4567 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
4568     return OpenDiskFile(pos, "rev", fReadOnly);
4569 }
4570
4571 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
4572 {
4573     return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
4574 }
4575
4576 CBlockIndex * InsertBlockIndex(uint256 hash)
4577 {
4578     if (hash.IsNull())
4579         return NULL;
4580     
4581     // Return existing
4582     BlockMap::iterator mi = mapBlockIndex.find(hash);
4583     if (mi != mapBlockIndex.end())
4584         return (*mi).second;
4585     
4586     // Create new
4587     CBlockIndex* pindexNew = new CBlockIndex();
4588     if (!pindexNew)
4589         throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
4590     mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4591     pindexNew->phashBlock = &((*mi).first);
4592     //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
4593
4594     return pindexNew;
4595 }
4596
4597 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
4598
4599 bool static LoadBlockIndexDB()
4600 {
4601     const CChainParams& chainparams = Params();
4602     LogPrintf("%s: start loading guts\n", __func__);
4603     if (!pblocktree->LoadBlockIndexGuts())
4604         return false;
4605     LogPrintf("%s: loaded guts\n", __func__);
4606     boost::this_thread::interruption_point();
4607     
4608     // Calculate nChainWork
4609     vector<pair<int, CBlockIndex*> > vSortedByHeight;
4610     vSortedByHeight.reserve(mapBlockIndex.size());
4611     BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4612     {
4613         CBlockIndex* pindex = item.second;
4614         vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
4615         //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4616     }
4617     //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
4618     sort(vSortedByHeight.begin(), vSortedByHeight.end());
4619     //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
4620     BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
4621     {
4622         CBlockIndex* pindex = item.second;
4623         pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
4624         // We can link the chain of blocks for which we've received transactions at some point.
4625         // Pruned nodes may have deleted the block.
4626         if (pindex->nTx > 0) {
4627             if (pindex->pprev) {
4628                 if (pindex->pprev->nChainTx) {
4629                     pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
4630                     if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4631                         pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4632                     } else {
4633                         pindex->nChainSproutValue = boost::none;
4634                     }
4635                 } else {
4636                     pindex->nChainTx = 0;
4637                     pindex->nChainSproutValue = boost::none;
4638                     mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
4639                 }
4640             } else {
4641                 pindex->nChainTx = pindex->nTx;
4642                 pindex->nChainSproutValue = pindex->nSproutValue;
4643             }
4644         }
4645         // Construct in-memory chain of branch IDs.
4646         // Relies on invariant: a block that does not activate a network upgrade
4647         // will always be valid under the same consensus rules as its parent.
4648         // Genesis block has a branch ID of zero by definition, but has no
4649         // validity status because it is side-loaded into a fresh chain.
4650         // Activation blocks will have branch IDs set (read from disk).
4651         if (pindex->pprev) {
4652             if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
4653                 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
4654             }
4655         } else {
4656             pindex->nCachedBranchId = SPROUT_BRANCH_ID;
4657         }
4658         if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
4659             setBlockIndexCandidates.insert(pindex);
4660         if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
4661             pindexBestInvalid = pindex;
4662         if (pindex->pprev)
4663             pindex->BuildSkip();
4664         if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
4665             pindexBestHeader = pindex;
4666         //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4667     }
4668     //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
4669
4670     // Load block file info
4671     pblocktree->ReadLastBlockFile(nLastBlockFile);
4672     vinfoBlockFile.resize(nLastBlockFile + 1);
4673     LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
4674     for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4675         pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4676     }
4677     LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
4678     for (int nFile = nLastBlockFile + 1; true; nFile++) {
4679         CBlockFileInfo info;
4680         if (pblocktree->ReadBlockFileInfo(nFile, info)) {
4681             vinfoBlockFile.push_back(info);
4682         } else {
4683             break;
4684         }
4685     }
4686     
4687     // Check presence of blk files
4688     LogPrintf("Checking all blk files are present...\n");
4689     set<int> setBlkDataFiles;
4690     BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4691     {
4692         CBlockIndex* pindex = item.second;
4693         if (pindex->nStatus & BLOCK_HAVE_DATA) {
4694             setBlkDataFiles.insert(pindex->nFile);
4695         }
4696         //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4697     }
4698     //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
4699     for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
4700     {
4701         CDiskBlockPos pos(*it, 0);
4702         if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
4703             return false;
4704         }
4705     }
4706     
4707     // Check whether we have ever pruned block & undo files
4708     pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
4709     if (fHavePruned)
4710         LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
4711     
4712     // Check whether we need to continue reindexing
4713     bool fReindexing = false;
4714     pblocktree->ReadReindexing(fReindexing);
4715     fReindex |= fReindexing;
4716     
4717     // Check whether we have a transaction index
4718     pblocktree->ReadFlag("txindex", fTxIndex);
4719     LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
4720     // Check whether we have an address index
4721     pblocktree->ReadFlag("addressindex", fAddressIndex);
4722     LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
4723
4724     // Check whether we have a timestamp index
4725     pblocktree->ReadFlag("timestampindex", fTimestampIndex);
4726     LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
4727
4728     // Check whether we have a spent index
4729     pblocktree->ReadFlag("spentindex", fSpentIndex);
4730     LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
4731
4732     // Fill in-memory data
4733     BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4734     {
4735         CBlockIndex* pindex = item.second;
4736         // - This relationship will always be true even if pprev has multiple
4737         //   children, because hashAnchor is technically a property of pprev,
4738         //   not its children.
4739         // - This will miss chain tips; we handle the best tip below, and other
4740         //   tips will be handled by ConnectTip during a re-org.
4741         if (pindex->pprev) {
4742             pindex->pprev->hashAnchorEnd = pindex->hashAnchor;
4743         }
4744         //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4745     }
4746     
4747     // Load pointer to end of best chain
4748     BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
4749     if (it == mapBlockIndex.end())
4750         return true;
4751     chainActive.SetTip(it->second);
4752     // Set hashAnchorEnd for the end of best chain
4753     it->second->hashAnchorEnd = pcoinsTip->GetBestAnchor();
4754     
4755     PruneBlockIndexCandidates();
4756     
4757     LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
4758               chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
4759               DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
4760               Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()));
4761     
4762     EnforceNodeDeprecation(chainActive.Height(), true);
4763     
4764     return true;
4765 }
4766
4767 CVerifyDB::CVerifyDB()
4768 {
4769     uiInterface.ShowProgress(_("Verifying blocks..."), 0);
4770 }
4771
4772 CVerifyDB::~CVerifyDB()
4773 {
4774     uiInterface.ShowProgress("", 100);
4775 }
4776
4777 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
4778 {
4779     LOCK(cs_main);
4780     if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
4781         return true;
4782     
4783     // Verify blocks in the best chain
4784     if (nCheckDepth <= 0)
4785         nCheckDepth = 1000000000; // suffices until the year 19000
4786     if (nCheckDepth > chainActive.Height())
4787         nCheckDepth = chainActive.Height();
4788     nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4789     LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4790     CCoinsViewCache coins(coinsview);
4791     CBlockIndex* pindexState = chainActive.Tip();
4792     CBlockIndex* pindexFailure = NULL;
4793     int nGoodTransactions = 0;
4794     CValidationState state;
4795     // No need to verify JoinSplits twice
4796     auto verifier = libzcash::ProofVerifier::Disabled();
4797     //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
4798     for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
4799     {
4800         boost::this_thread::interruption_point();
4801         uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
4802         if (pindex->nHeight < chainActive.Height()-nCheckDepth)
4803             break;
4804         CBlock block;
4805         // check level 0: read from disk
4806         if (!ReadBlockFromDisk(block, pindex,0))
4807             return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
4808         // check level 1: verify block validity
4809         int32_t futureblock;
4810         if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0) )
4811             return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
4812         // check level 2: verify undo validity
4813         if (nCheckLevel >= 2 && pindex) {
4814             CBlockUndo undo;
4815             CDiskBlockPos pos = pindex->GetUndoPos();
4816             if (!pos.IsNull()) {
4817                 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
4818                     return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
4819             }
4820         }
4821         // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
4822         if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
4823             bool fClean = true;
4824             if (!DisconnectBlock(block, state, pindex, coins, &fClean))
4825                 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
4826             pindexState = pindex->pprev;
4827             if (!fClean) {
4828                 nGoodTransactions = 0;
4829                 pindexFailure = pindex;
4830             } else
4831                 nGoodTransactions += block.vtx.size();
4832         }
4833         if (ShutdownRequested())
4834             return true;
4835     }
4836     //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
4837     if (pindexFailure)
4838         return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
4839     
4840     // check level 4: try reconnecting blocks
4841     if (nCheckLevel >= 4) {
4842         CBlockIndex *pindex = pindexState;
4843         while (pindex != chainActive.Tip()) {
4844             boost::this_thread::interruption_point();
4845             uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
4846             pindex = chainActive.Next(pindex);
4847             CBlock block;
4848             if (!ReadBlockFromDisk(block, pindex,0))
4849                 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
4850             if (!ConnectBlock(block, state, pindex, coins,false, true))
4851                 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
4852         }
4853     }
4854     
4855     LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
4856     
4857     return true;
4858 }
4859
4860 bool RewindBlockIndex(const CChainParams& params)
4861 {
4862     LOCK(cs_main);
4863     
4864     // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
4865     // index will have nCachedBranchId set based on the values previously persisted
4866     // to disk. By definition, a set nCachedBranchId means that the block was
4867     // fully-validated under the corresponding consensus rules. Thus we can quickly
4868     // identify whether the current active chain matches our expected sequence of
4869     // consensus rule changes, with two checks:
4870     //
4871     // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
4872     // - nCachedBranchId for each block matches what we expect.
4873     auto sufficientlyValidated = [&params](const CBlockIndex* pindex) {
4874         auto consensus = params.GetConsensus();
4875         bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
4876         bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus);
4877         return fFlagSet == fFlagExpected &&
4878         pindex->nCachedBranchId &&
4879         *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->nHeight, consensus);
4880     };
4881     
4882     int nHeight = 1;
4883     while (nHeight <= chainActive.Height()) {
4884         if (!sufficientlyValidated(chainActive[nHeight])) {
4885             break;
4886         }
4887         nHeight++;
4888     }
4889     
4890     // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
4891     auto rewindLength = chainActive.Height() - nHeight;
4892     if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH) {
4893         auto pindexOldTip = chainActive.Tip();
4894         auto pindexRewind = chainActive[nHeight - 1];
4895         auto msg = strprintf(_(
4896                                "A block chain rewind has been detected that would roll back %d blocks! "
4897                                "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
4898                                ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
4899         _("Rewind details") + ":\n" +
4900         "- " + strprintf(_("Current tip:   %s, height %d"),
4901                          pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
4902         "- " + strprintf(_("Rewinding to:  %s, height %d"),
4903                          pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
4904         _("Please help, human!");
4905         LogPrintf("*** %s\n", msg);
4906         uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
4907         StartShutdown();
4908         return false;
4909     }
4910     
4911     CValidationState state;
4912     CBlockIndex* pindex = chainActive.Tip();
4913     while (chainActive.Height() >= nHeight) {
4914         if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
4915             // If pruning, don't try rewinding past the HAVE_DATA point;
4916             // since older blocks can't be served anyway, there's
4917             // no need to walk further, and trying to DisconnectTip()
4918             // will fail (and require a needless reindex/redownload
4919             // of the blockchain).
4920             break;
4921         }
4922         if (!DisconnectTip(state, true)) {
4923             return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
4924         }
4925         // Occasionally flush state to disk.
4926         if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
4927             return false;
4928     }
4929     
4930     // Reduce validity flag and have-data flags.
4931     // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
4932     // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
4933     for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
4934         CBlockIndex* pindexIter = it->second;
4935         
4936         // Note: If we encounter an insufficiently validated block that
4937         // is on chainActive, it must be because we are a pruning node, and
4938         // this block or some successor doesn't HAVE_DATA, so we were unable to
4939         // rewind all the way.  Blocks remaining on chainActive at this point
4940         // must not have their validity reduced.
4941         if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
4942             // Reduce validity
4943             pindexIter->nStatus =
4944             std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
4945             (pindexIter->nStatus & ~BLOCK_VALID_MASK);
4946             // Remove have-data flags
4947             pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
4948             // Remove branch ID
4949             pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
4950             pindexIter->nCachedBranchId = boost::none;
4951             // Remove storage location
4952             pindexIter->nFile = 0;
4953             pindexIter->nDataPos = 0;
4954             pindexIter->nUndoPos = 0;
4955             // Remove various other things
4956             pindexIter->nTx = 0;
4957             pindexIter->nChainTx = 0;
4958             pindexIter->nSproutValue = boost::none;
4959             pindexIter->nChainSproutValue = boost::none;
4960             pindexIter->nSequenceId = 0;
4961             // Make sure it gets written
4962             setDirtyBlockIndex.insert(pindexIter);
4963             if (pindexIter == pindexBestInvalid)
4964             {
4965                 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
4966                 pindexBestInvalid = NULL;
4967             }
4968             
4969             // Update indices
4970             setBlockIndexCandidates.erase(pindexIter);
4971             auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
4972             while (ret.first != ret.second) {
4973                 if (ret.first->second == pindexIter) {
4974                     mapBlocksUnlinked.erase(ret.first++);
4975                 } else {
4976                     ++ret.first;
4977                 }
4978             }
4979         } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
4980             setBlockIndexCandidates.insert(pindexIter);
4981         }
4982     }
4983     
4984     PruneBlockIndexCandidates();
4985     
4986     CheckBlockIndex();
4987     
4988     if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
4989         return false;
4990     }
4991     
4992     return true;
4993 }
4994
4995 void UnloadBlockIndex()
4996 {
4997     LOCK(cs_main);
4998     setBlockIndexCandidates.clear();
4999     chainActive.SetTip(NULL);
5000     pindexBestInvalid = NULL;
5001     pindexBestHeader = NULL;
5002     mempool.clear();
5003     mapOrphanTransactions.clear();
5004     mapOrphanTransactionsByPrev.clear();
5005     nSyncStarted = 0;
5006     mapBlocksUnlinked.clear();
5007     vinfoBlockFile.clear();
5008     nLastBlockFile = 0;
5009     nBlockSequenceId = 1;
5010     mapBlockSource.clear();
5011     mapBlocksInFlight.clear();
5012     nQueuedValidatedHeaders = 0;
5013     nPreferredDownload = 0;
5014     setDirtyBlockIndex.clear();
5015     setDirtyFileInfo.clear();
5016     mapNodeState.clear();
5017     recentRejects.reset(NULL);
5018     
5019     BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5020         delete entry.second;
5021     }
5022     mapBlockIndex.clear();
5023     fHavePruned = false;
5024 }
5025
5026 bool LoadBlockIndex()
5027 {
5028     // Load block index from databases
5029     KOMODO_LOADINGBLOCKS = 1;
5030     if (!fReindex && !LoadBlockIndexDB())
5031     {
5032         KOMODO_LOADINGBLOCKS = 0;
5033         return false;
5034     }
5035     fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5036     return true;
5037 }
5038
5039
5040 bool InitBlockIndex() {
5041     const CChainParams& chainparams = Params();
5042     LOCK(cs_main);
5043     
5044     // Initialize global variables that cannot be constructed at startup.
5045     recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5046     
5047     // Check whether we're already initialized
5048     if (chainActive.Genesis() != NULL)
5049         return true;
5050     
5051     // Use the provided setting for -txindex in the new database
5052     fTxIndex = GetBoolArg("-txindex", true);
5053     pblocktree->WriteFlag("txindex", fTxIndex);
5054     // Use the provided setting for -addressindex in the new database
5055     fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5056     pblocktree->WriteFlag("addressindex", fAddressIndex);
5057
5058     // Use the provided setting for -timestampindex in the new database
5059     fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5060     pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5061
5062     fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5063     pblocktree->WriteFlag("spentindex", fSpentIndex);
5064     LogPrintf("Initializing databases...\n");
5065     
5066     // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5067     if (!fReindex) {
5068         try {
5069             CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5070             // Start new block file
5071             unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5072             CDiskBlockPos blockPos;
5073             CValidationState state;
5074             if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5075                 return error("LoadBlockIndex(): FindBlockPos failed");
5076             if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5077                 return error("LoadBlockIndex(): writing genesis block to disk failed");
5078             CBlockIndex *pindex = AddToBlockIndex(block);
5079             if ( pindex == 0 )
5080                 return error("LoadBlockIndex(): couldnt add to block index");
5081             if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5082                 return error("LoadBlockIndex(): genesis block not accepted");
5083             if (!ActivateBestChain(state, &block))
5084                 return error("LoadBlockIndex(): genesis block cannot be activated");
5085             // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5086             return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5087         } catch (const std::runtime_error& e) {
5088             return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5089         }
5090     }
5091     
5092     return true;
5093 }
5094
5095
5096
5097 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5098 {
5099     const CChainParams& chainparams = Params();
5100     // Map of disk positions for blocks with unknown parent (only used for reindex)
5101     static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5102     int64_t nStart = GetTimeMillis();
5103     
5104     int nLoaded = 0;
5105     try {
5106         // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5107         //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5108         CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5109         uint64_t nRewind = blkdat.GetPos();
5110         while (!blkdat.eof()) {
5111             boost::this_thread::interruption_point();
5112             
5113             blkdat.SetPos(nRewind);
5114             nRewind++; // start one byte further next time, in case of failure
5115             blkdat.SetLimit(); // remove former limit
5116             unsigned int nSize = 0;
5117             try {
5118                 // locate a header
5119                 unsigned char buf[MESSAGE_START_SIZE];
5120                 blkdat.FindByte(Params().MessageStart()[0]);
5121                 nRewind = blkdat.GetPos()+1;
5122                 blkdat >> FLATDATA(buf);
5123                 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5124                     continue;
5125                 // read size
5126                 blkdat >> nSize;
5127                 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5128                     continue;
5129             } catch (const std::exception&) {
5130                 // no valid block header found; don't complain
5131                 break;
5132             }
5133             try {
5134                 // read block
5135                 uint64_t nBlockPos = blkdat.GetPos();
5136                 if (dbp)
5137                     dbp->nPos = nBlockPos;
5138                 blkdat.SetLimit(nBlockPos + nSize);
5139                 blkdat.SetPos(nBlockPos);
5140                 CBlock block;
5141                 blkdat >> block;
5142                 nRewind = blkdat.GetPos();
5143                 
5144                 // detect out of order blocks, and store them for later
5145                 uint256 hash = block.GetHash();
5146                 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5147                     LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5148                              block.hashPrevBlock.ToString());
5149                     if (dbp)
5150                         mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5151                     continue;
5152                 }
5153                 
5154                 // process in case the block isn't known yet
5155                 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5156                     CValidationState state;
5157                     if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5158                         nLoaded++;
5159                     if (state.IsError())
5160                         break;
5161                 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
5162                     LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
5163                 }
5164                 
5165                 // Recursively process earlier encountered successors of this block
5166                 deque<uint256> queue;
5167                 queue.push_back(hash);
5168                 while (!queue.empty()) {
5169                     uint256 head = queue.front();
5170                     queue.pop_front();
5171                     std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5172                     while (range.first != range.second) {
5173                         std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5174                         if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1))
5175                         {
5176                             LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5177                                       head.ToString());
5178                             CValidationState dummy;
5179                             if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5180                             {
5181                                 nLoaded++;
5182                                 queue.push_back(block.GetHash());
5183                             }
5184                         }
5185                         range.first++;
5186                         mapBlocksUnknownParent.erase(it);
5187                     }
5188                 }
5189             } catch (const std::exception& e) {
5190                 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5191             }
5192         }
5193     } catch (const std::runtime_error& e) {
5194         AbortNode(std::string("System error: ") + e.what());
5195     }
5196     if (nLoaded > 0)
5197         LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5198     return nLoaded > 0;
5199 }
5200
5201 void static CheckBlockIndex()
5202 {
5203     const Consensus::Params& consensusParams = Params().GetConsensus();
5204     if (!fCheckBlockIndex) {
5205         return;
5206     }
5207     
5208     LOCK(cs_main);
5209     
5210     // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5211     // so we have the genesis block in mapBlockIndex but no active chain.  (A few of the tests when
5212     // iterating the block tree require that chainActive has been initialized.)
5213     if (chainActive.Height() < 0) {
5214         assert(mapBlockIndex.size() <= 1);
5215         return;
5216     }
5217     
5218     // Build forward-pointing map of the entire block tree.
5219     std::multimap<CBlockIndex*,CBlockIndex*> forward;
5220     for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5221         forward.insert(std::make_pair(it->second->pprev, it->second));
5222     }
5223     
5224     assert(forward.size() == mapBlockIndex.size());
5225     
5226     std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5227     CBlockIndex *pindex = rangeGenesis.first->second;
5228     rangeGenesis.first++;
5229     assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5230     
5231     // Iterate over the entire block tree, using depth-first search.
5232     // Along the way, remember whether there are blocks on the path from genesis
5233     // block being explored which are the first to have certain properties.
5234     size_t nNodes = 0;
5235     int nHeight = 0;
5236     CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5237     CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5238     CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5239     CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5240     CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5241     CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5242     CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5243     while (pindex != NULL) {
5244         nNodes++;
5245         if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5246         if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5247         if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5248         if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5249         if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5250         if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5251         if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5252         
5253         // Begin: actual consistency checks.
5254         if (pindex->pprev == NULL) {
5255             // Genesis block checks.
5256             assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5257             assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5258         }
5259         if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0);  // nSequenceId can't be set for blocks that aren't linked
5260         // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5261         // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5262         if (!fHavePruned) {
5263             // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5264             assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5265             assert(pindexFirstMissing == pindexFirstNeverProcessed);
5266         } else {
5267             // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5268             if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5269         }
5270         if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5271         assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5272         // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5273         assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5274         assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5275         assert(pindex->nHeight == nHeight); // nHeight must be consistent.
5276         assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
5277         assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5278         assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5279         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5280         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5281         if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5282         if (pindexFirstInvalid == NULL) {
5283             // Checks for not-invalid blocks.
5284             assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5285         }
5286         if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5287             if (pindexFirstInvalid == NULL) {
5288                 // If this block sorts at least as good as the current tip and
5289                 // is valid and we have all data for its parents, it must be in
5290                 // setBlockIndexCandidates.  chainActive.Tip() must also be there
5291                 // even if some data has been pruned.
5292                 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5293                     assert(setBlockIndexCandidates.count(pindex));
5294                 }
5295                 // If some parent is missing, then it could be that this block was in
5296                 // setBlockIndexCandidates but had to be removed because of the missing data.
5297                 // In this case it must be in mapBlocksUnlinked -- see test below.
5298             }
5299         } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
5300             assert(setBlockIndexCandidates.count(pindex) == 0);
5301         }
5302         // Check whether this block is in mapBlocksUnlinked.
5303         std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5304         bool foundInUnlinked = false;
5305         while (rangeUnlinked.first != rangeUnlinked.second) {
5306             assert(rangeUnlinked.first->first == pindex->pprev);
5307             if (rangeUnlinked.first->second == pindex) {
5308                 foundInUnlinked = true;
5309                 break;
5310             }
5311             rangeUnlinked.first++;
5312         }
5313         if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5314             // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5315             assert(foundInUnlinked);
5316         }
5317         if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5318         if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5319         if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5320             // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5321             assert(fHavePruned); // We must have pruned.
5322             // This block may have entered mapBlocksUnlinked if:
5323             //  - it has a descendant that at some point had more work than the
5324             //    tip, and
5325             //  - we tried switching to that descendant but were missing
5326             //    data for some intermediate block between chainActive and the
5327             //    tip.
5328             // So if this block is itself better than chainActive.Tip() and it wasn't in
5329             // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5330             if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5331                 if (pindexFirstInvalid == NULL) {
5332                     assert(foundInUnlinked);
5333                 }
5334             }
5335         }
5336         // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5337         // End: actual consistency checks.
5338         
5339         // Try descending into the first subnode.
5340         std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5341         if (range.first != range.second) {
5342             // A subnode was found.
5343             pindex = range.first->second;
5344             nHeight++;
5345             continue;
5346         }
5347         // This is a leaf node.
5348         // Move upwards until we reach a node of which we have not yet visited the last child.
5349         while (pindex) {
5350             // We are going to either move to a parent or a sibling of pindex.
5351             // If pindex was the first with a certain property, unset the corresponding variable.
5352             if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
5353             if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
5354             if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
5355             if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
5356             if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
5357             if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
5358             if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
5359             // Find our parent.
5360             CBlockIndex* pindexPar = pindex->pprev;
5361             // Find which child we just visited.
5362             std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
5363             while (rangePar.first->second != pindex) {
5364                 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
5365                 rangePar.first++;
5366             }
5367             // Proceed to the next one.
5368             rangePar.first++;
5369             if (rangePar.first != rangePar.second) {
5370                 // Move to the sibling.
5371                 pindex = rangePar.first->second;
5372                 break;
5373             } else {
5374                 // Move up further.
5375                 pindex = pindexPar;
5376                 nHeight--;
5377                 continue;
5378             }
5379         }
5380     }
5381     
5382     // Check that we actually traversed the entire map.
5383     assert(nNodes == forward.size());
5384 }
5385
5386 //////////////////////////////////////////////////////////////////////////////
5387 //
5388 // CAlert
5389 //
5390
5391 std::string GetWarnings(const std::string& strFor)
5392 {
5393     int nPriority = 0;
5394     string strStatusBar;
5395     string strRPC;
5396     
5397     if (!CLIENT_VERSION_IS_RELEASE)
5398         strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
5399     
5400     if (GetBoolArg("-testsafemode", false))
5401         strStatusBar = strRPC = "testsafemode enabled";
5402     
5403     // Misc warnings like out of disk space and clock is wrong
5404     if (strMiscWarning != "")
5405     {
5406         nPriority = 1000;
5407         strStatusBar = strMiscWarning;
5408     }
5409     
5410     if (fLargeWorkForkFound)
5411     {
5412         nPriority = 2000;
5413         strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
5414     }
5415     else if (fLargeWorkInvalidChainFound)
5416     {
5417         nPriority = 2000;
5418         strStatusBar = strRPC = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.");
5419     }
5420     
5421     // Alerts
5422     {
5423         LOCK(cs_mapAlerts);
5424         BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
5425         {
5426             const CAlert& alert = item.second;
5427             if (alert.AppliesToMe() && alert.nPriority > nPriority)
5428             {
5429                 nPriority = alert.nPriority;
5430                 strStatusBar = alert.strStatusBar;
5431                 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
5432                     strRPC = alert.strRPCError;
5433                 }
5434             }
5435         }
5436     }
5437     
5438     if (strFor == "statusbar")
5439         return strStatusBar;
5440     else if (strFor == "rpc")
5441         return strRPC;
5442     assert(!"GetWarnings(): invalid parameter");
5443     return "error";
5444 }
5445
5446
5447
5448
5449
5450
5451
5452
5453 //////////////////////////////////////////////////////////////////////////////
5454 //
5455 // Messages
5456 //
5457
5458
5459 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
5460 {
5461     switch (inv.type)
5462     {
5463         case MSG_TX:
5464         {
5465             assert(recentRejects);
5466             if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
5467             {
5468                 // If the chain tip has changed previously rejected transactions
5469                 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
5470                 // or a double-spend. Reset the rejects filter and give those
5471                 // txs a second chance.
5472                 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
5473                 recentRejects->reset();
5474             }
5475             
5476             return recentRejects->contains(inv.hash) ||
5477             mempool.exists(inv.hash) ||
5478             mapOrphanTransactions.count(inv.hash) ||
5479             pcoinsTip->HaveCoins(inv.hash);
5480         }
5481         case MSG_BLOCK:
5482             return mapBlockIndex.count(inv.hash);
5483     }
5484     // Don't know what it is, just say we already got one
5485     return true;
5486 }
5487
5488 void static ProcessGetData(CNode* pfrom)
5489 {
5490     std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
5491     
5492     vector<CInv> vNotFound;
5493     
5494     LOCK(cs_main);
5495     
5496     while (it != pfrom->vRecvGetData.end()) {
5497         // Don't bother if send buffer is too full to respond anyway
5498         if (pfrom->nSendSize >= SendBufferSize())
5499             break;
5500         
5501         const CInv &inv = *it;
5502         {
5503             boost::this_thread::interruption_point();
5504             it++;
5505             
5506             if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5507             {
5508                 bool send = false;
5509                 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
5510                 if (mi != mapBlockIndex.end())
5511                 {
5512                     if (chainActive.Contains(mi->second)) {
5513                         send = true;
5514                     } else {
5515                         static const int nOneMonth = 30 * 24 * 60 * 60;
5516                         // To prevent fingerprinting attacks, only send blocks outside of the active
5517                         // chain if they are valid, and no more than a month older (both in time, and in
5518                         // best equivalent proof of work) than the best header chain we know about.
5519                         send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
5520                         (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
5521                         (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
5522                         if (!send) {
5523                             LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
5524                         }
5525                     }
5526                 }
5527                 // Pruned nodes may have deleted the block, so check whether
5528                 // it's available before trying to send.
5529                 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
5530                 {
5531                     // Send block from disk
5532                     CBlock block;
5533                     if (!ReadBlockFromDisk(block, (*mi).second,1))
5534                     {
5535                         assert(!"cannot load block from disk");
5536                     }
5537                     else
5538                     {
5539                         if (inv.type == MSG_BLOCK)
5540                         {
5541                             //uint256 hash; int32_t z;
5542                             //hash = block.GetHash();
5543                             //for (z=31; z>=0; z--)
5544                             //    fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
5545                             //fprintf(stderr," send block %d\n",komodo_block2height(&block));
5546                             pfrom->PushMessage("block", block);
5547                         }
5548                         else // MSG_FILTERED_BLOCK)
5549                         {
5550                             LOCK(pfrom->cs_filter);
5551                             if (pfrom->pfilter)
5552                             {
5553                                 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
5554                                 pfrom->PushMessage("merkleblock", merkleBlock);
5555                                 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
5556                                 // This avoids hurting performance by pointlessly requiring a round-trip
5557                                 // Note that there is currently no way for a node to request any single transactions we didn't send here -
5558                                 // they must either disconnect and retry or request the full block.
5559                                 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
5560                                 // however we MUST always provide at least what the remote peer needs
5561                                 typedef std::pair<unsigned int, uint256> PairType;
5562                                 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
5563                                 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
5564                                     pfrom->PushMessage("tx", block.vtx[pair.first]);
5565                             }
5566                             // else
5567                             // no response
5568                         }
5569                     }
5570                     // Trigger the peer node to send a getblocks request for the next batch of inventory
5571                     if (inv.hash == pfrom->hashContinue)
5572                     {
5573                         // Bypass PushInventory, this must send even if redundant,
5574                         // and we want it right after the last block so they don't
5575                         // wait for other stuff first.
5576                         vector<CInv> vInv;
5577                         vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
5578                         pfrom->PushMessage("inv", vInv);
5579                         pfrom->hashContinue.SetNull();
5580                     }
5581                 }
5582             }
5583             else if (inv.IsKnownType())
5584             {
5585                 // Send stream from relay memory
5586                 bool pushed = false;
5587                 {
5588                     LOCK(cs_mapRelay);
5589                     map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
5590                     if (mi != mapRelay.end()) {
5591                         pfrom->PushMessage(inv.GetCommand(), (*mi).second);
5592                         pushed = true;
5593                     }
5594                 }
5595                 if (!pushed && inv.type == MSG_TX) {
5596                     CTransaction tx;
5597                     if (mempool.lookup(inv.hash, tx)) {
5598                         CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
5599                         ss.reserve(1000);
5600                         ss << tx;
5601                         pfrom->PushMessage("tx", ss);
5602                         pushed = true;
5603                     }
5604                 }
5605                 if (!pushed) {
5606                     vNotFound.push_back(inv);
5607                 }
5608             }
5609             
5610             // Track requests for our stuff.
5611             GetMainSignals().Inventory(inv.hash);
5612             
5613             if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5614                 break;
5615         }
5616     }
5617     
5618     pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
5619     
5620     if (!vNotFound.empty()) {
5621         // Let the peer know that we didn't find what it asked for, so it doesn't
5622         // have to wait around forever. Currently only SPV clients actually care
5623         // about this message: it's needed when they are recursively walking the
5624         // dependencies of relevant unconfirmed transactions. SPV clients want to
5625         // do that because they want to know about (and store and rebroadcast and
5626         // risk analyze) the dependencies of transactions relevant to them, without
5627         // having to download the entire memory pool.
5628         pfrom->PushMessage("notfound", vNotFound);
5629     }
5630 }
5631
5632 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
5633 {
5634     const CChainParams& chainparams = Params();
5635     LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
5636     //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
5637     if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
5638     {
5639         LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
5640         return true;
5641     }
5642
5643     if (strCommand == "version")
5644     {
5645         // Each connection can only send one version message
5646         if (pfrom->nVersion != 0)
5647         {
5648             pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
5649             Misbehaving(pfrom->GetId(), 1);
5650             return false;
5651         }
5652         
5653         int64_t nTime;
5654         CAddress addrMe;
5655         CAddress addrFrom;
5656         uint64_t nNonce = 1;
5657         vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
5658         if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
5659         {
5660             // disconnect from peers older than this proto version
5661             LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5662             pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5663                                strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
5664             pfrom->fDisconnect = true;
5665             return false;
5666         }
5667         
5668         // When Overwinter is active, reject incoming connections from non-Overwinter nodes
5669         const Consensus::Params& params = Params().GetConsensus();
5670         if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER)
5671             && pfrom->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)
5672         {
5673             LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5674             pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5675                                strprintf("Version must be %d or greater",
5676                                          params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
5677             pfrom->fDisconnect = true;
5678             return false;
5679         }
5680         
5681         if (pfrom->nVersion == 10300)
5682             pfrom->nVersion = 300;
5683         if (!vRecv.empty())
5684             vRecv >> addrFrom >> nNonce;
5685         if (!vRecv.empty()) {
5686             vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
5687             pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
5688         }
5689         if (!vRecv.empty())
5690             vRecv >> pfrom->nStartingHeight;
5691         if (!vRecv.empty())
5692             vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
5693         else
5694             pfrom->fRelayTxes = true;
5695         
5696         // Disconnect if we connected to ourself
5697         if (nNonce == nLocalHostNonce && nNonce > 1)
5698         {
5699             LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
5700             pfrom->fDisconnect = true;
5701             return true;
5702         }
5703         
5704         pfrom->addrLocal = addrMe;
5705         if (pfrom->fInbound && addrMe.IsRoutable())
5706         {
5707             SeenLocal(addrMe);
5708         }
5709         
5710         // Be shy and don't send version until we hear
5711         if (pfrom->fInbound)
5712             pfrom->PushVersion();
5713         
5714         pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
5715         
5716         // Potentially mark this peer as a preferred download peer.
5717         UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
5718         
5719         // Change version
5720         pfrom->PushMessage("verack");
5721         pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
5722         
5723         if (!pfrom->fInbound)
5724         {
5725             // Advertise our address
5726             if (fListen && !IsInitialBlockDownload())
5727             {
5728                 CAddress addr = GetLocalAddress(&pfrom->addr);
5729                 if (addr.IsRoutable())
5730                 {
5731                     LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
5732                     pfrom->PushAddress(addr);
5733                 } else if (IsPeerAddrLocalGood(pfrom)) {
5734                     addr.SetIP(pfrom->addrLocal);
5735                     LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
5736                     pfrom->PushAddress(addr);
5737                 }
5738             }
5739             
5740             // Get recent addresses
5741             if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
5742             {
5743                 pfrom->PushMessage("getaddr");
5744                 pfrom->fGetAddr = true;
5745             }
5746             addrman.Good(pfrom->addr);
5747         } else {
5748             if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
5749             {
5750                 addrman.Add(addrFrom, addrFrom);
5751                 addrman.Good(addrFrom);
5752             }
5753         }
5754         
5755         // Relay alerts
5756         {
5757             LOCK(cs_mapAlerts);
5758             BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
5759             item.second.RelayTo(pfrom);
5760         }
5761         
5762         pfrom->fSuccessfullyConnected = true;
5763         
5764         string remoteAddr;
5765         if (fLogIPs)
5766             remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
5767         
5768         LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
5769                   pfrom->cleanSubVer, pfrom->nVersion,
5770                   pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
5771                   remoteAddr);
5772         
5773         int64_t nTimeOffset = nTime - GetTime();
5774         pfrom->nTimeOffset = nTimeOffset;
5775         AddTimeData(pfrom->addr, nTimeOffset);
5776     }
5777     
5778     
5779     else if (pfrom->nVersion == 0)
5780     {
5781         // Must have a version message before anything else
5782         Misbehaving(pfrom->GetId(), 1);
5783         return false;
5784     }
5785     
5786     
5787     else if (strCommand == "verack")
5788     {
5789         pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
5790         
5791         // Mark this node as currently connected, so we update its timestamp later.
5792         if (pfrom->fNetworkNode) {
5793             LOCK(cs_main);
5794             State(pfrom->GetId())->fCurrentlyConnected = true;
5795         }
5796     }
5797     
5798     
5799     // Disconnect existing peer connection when:
5800     // 1. The version message has been received
5801     // 2. Overwinter is active
5802     // 3. Peer version is pre-Overwinter
5803     else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
5804              && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
5805     {
5806         LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5807         pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5808                            strprintf("Version must be %d or greater",
5809                                      chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
5810         pfrom->fDisconnect = true;
5811         return false;
5812     }
5813     
5814     
5815     else if (strCommand == "addr")
5816     {
5817         vector<CAddress> vAddr;
5818         vRecv >> vAddr;
5819         
5820         // Don't want addr from older versions unless seeding
5821         if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
5822             return true;
5823         if (vAddr.size() > 1000)
5824         {
5825             Misbehaving(pfrom->GetId(), 20);
5826             return error("message addr size() = %u", vAddr.size());
5827         }
5828         
5829         // Store the new addresses
5830         vector<CAddress> vAddrOk;
5831         int64_t nNow = GetAdjustedTime();
5832         int64_t nSince = nNow - 10 * 60;
5833         BOOST_FOREACH(CAddress& addr, vAddr)
5834         {
5835             boost::this_thread::interruption_point();
5836             
5837             if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
5838                 addr.nTime = nNow - 5 * 24 * 60 * 60;
5839             pfrom->AddAddressKnown(addr);
5840             bool fReachable = IsReachable(addr);
5841             if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
5842             {
5843                 // Relay to a limited number of other nodes
5844                 {
5845                     LOCK(cs_vNodes);
5846                     // Use deterministic randomness to send to the same nodes for 24 hours
5847                     // at a time so the addrKnowns of the chosen nodes prevent repeats
5848                     static uint256 hashSalt;
5849                     if (hashSalt.IsNull())
5850                         hashSalt = GetRandHash();
5851                     uint64_t hashAddr = addr.GetHash();
5852                     uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
5853                     hashRand = Hash(BEGIN(hashRand), END(hashRand));
5854                     multimap<uint256, CNode*> mapMix;
5855                     BOOST_FOREACH(CNode* pnode, vNodes)
5856                     {
5857                         if (pnode->nVersion < CADDR_TIME_VERSION)
5858                             continue;
5859                         unsigned int nPointer;
5860                         memcpy(&nPointer, &pnode, sizeof(nPointer));
5861                         uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
5862                         hashKey = Hash(BEGIN(hashKey), END(hashKey));
5863                         mapMix.insert(make_pair(hashKey, pnode));
5864                     }
5865                     int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
5866                     for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
5867                         ((*mi).second)->PushAddress(addr);
5868                 }
5869             }
5870             // Do not store addresses outside our network
5871             if (fReachable)
5872                 vAddrOk.push_back(addr);
5873         }
5874         addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
5875         if (vAddr.size() < 1000)
5876             pfrom->fGetAddr = false;
5877         if (pfrom->fOneShot)
5878             pfrom->fDisconnect = true;
5879     }
5880     
5881     
5882     else if (strCommand == "inv")
5883     {
5884         vector<CInv> vInv;
5885         vRecv >> vInv;
5886         if (vInv.size() > MAX_INV_SZ)
5887         {
5888             Misbehaving(pfrom->GetId(), 20);
5889             return error("message inv size() = %u", vInv.size());
5890         }
5891         
5892         LOCK(cs_main);
5893         
5894         std::vector<CInv> vToFetch;
5895         
5896         for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
5897         {
5898             const CInv &inv = vInv[nInv];
5899             
5900             boost::this_thread::interruption_point();
5901             pfrom->AddInventoryKnown(inv);
5902             
5903             bool fAlreadyHave = AlreadyHave(inv);
5904             LogPrint("net", "got inv: %s  %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
5905             
5906             if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
5907                 pfrom->AskFor(inv);
5908             
5909             if (inv.type == MSG_BLOCK) {
5910                 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
5911                 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
5912                     // First request the headers preceding the announced block. In the normal fully-synced
5913                     // case where a new block is announced that succeeds the current tip (no reorganization),
5914                     // there are no such headers.
5915                     // Secondly, and only when we are close to being synced, we request the announced block directly,
5916                     // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
5917                     // time the block arrives, the header chain leading up to it is already validated. Not
5918                     // doing this will result in the received block being rejected as an orphan in case it is
5919                     // not a direct successor.
5920                     pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
5921                     CNodeState *nodestate = State(pfrom->GetId());
5922                     if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
5923                         nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
5924                         vToFetch.push_back(inv);
5925                         // Mark block as in flight already, even though the actual "getdata" message only goes out
5926                         // later (within the same cs_main lock, though).
5927                         MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
5928                     }
5929                     LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
5930                 }
5931             }
5932             
5933             // Track requests for our stuff
5934             GetMainSignals().Inventory(inv.hash);
5935             
5936             if (pfrom->nSendSize > (SendBufferSize() * 2)) {
5937                 Misbehaving(pfrom->GetId(), 50);
5938                 return error("send buffer size() = %u", pfrom->nSendSize);
5939             }
5940         }
5941         
5942         if (!vToFetch.empty())
5943             pfrom->PushMessage("getdata", vToFetch);
5944     }
5945     
5946     
5947     else if (strCommand == "getdata")
5948     {
5949         vector<CInv> vInv;
5950         vRecv >> vInv;
5951         if (vInv.size() > MAX_INV_SZ)
5952         {
5953             Misbehaving(pfrom->GetId(), 20);
5954             return error("message getdata size() = %u", vInv.size());
5955         }
5956         
5957         if (fDebug || (vInv.size() != 1))
5958             LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
5959         
5960         if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
5961             LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
5962         
5963         pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
5964         ProcessGetData(pfrom);
5965     }
5966     
5967     
5968     else if (strCommand == "getblocks")
5969     {
5970         CBlockLocator locator;
5971         uint256 hashStop;
5972         vRecv >> locator >> hashStop;
5973         
5974         LOCK(cs_main);
5975         
5976         // Find the last block the caller has in the main chain
5977         CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
5978         
5979         // Send the rest of the chain
5980         if (pindex)
5981             pindex = chainActive.Next(pindex);
5982         int nLimit = 500;
5983         LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
5984         for (; pindex; pindex = chainActive.Next(pindex))
5985         {
5986             if (pindex->GetBlockHash() == hashStop)
5987             {
5988                 LogPrint("net", "  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
5989                 break;
5990             }
5991             pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
5992             if (--nLimit <= 0)
5993             {
5994                 // When this block is requested, we'll send an inv that'll
5995                 // trigger the peer to getblocks the next batch of inventory.
5996                 LogPrint("net", "  getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
5997                 pfrom->hashContinue = pindex->GetBlockHash();
5998                 break;
5999             }
6000         }
6001     }
6002     
6003     
6004     else if (strCommand == "getheaders")
6005     {
6006         CBlockLocator locator;
6007         uint256 hashStop;
6008         vRecv >> locator >> hashStop;
6009         
6010         LOCK(cs_main);
6011         
6012         if (IsInitialBlockDownload())
6013             return true;
6014         
6015         CBlockIndex* pindex = NULL;
6016         if (locator.IsNull())
6017         {
6018             // If locator is null, return the hashStop block
6019             BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6020             if (mi == mapBlockIndex.end())
6021                 return true;
6022             pindex = (*mi).second;
6023         }
6024         else
6025         {
6026             // Find the last block the caller has in the main chain
6027             pindex = FindForkInGlobalIndex(chainActive, locator);
6028             if (pindex)
6029                 pindex = chainActive.Next(pindex);
6030         }
6031
6032         // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6033         vector<CNetworkBlockHeader> vHeaders;
6034         int nLimit = MAX_HEADERS_RESULTS;
6035         LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
6036         //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) )// no need to ever suppress this
6037         {
6038             pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->nHeight : -1);
6039             for (; pindex; pindex = chainActive.Next(pindex))
6040             {
6041                 CBlockHeader h = pindex->GetBlockHeader();
6042                 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6043                 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
6044                 vHeaders.push_back(pindex->GetBlockHeader());
6045                 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6046                     break;
6047             }
6048             pfrom->PushMessage("headers", vHeaders);
6049         }
6050         /*else if ( NOTARY_PUBKEY33[0] != 0 )
6051         {
6052             static uint32_t counter;
6053             if ( counter++ < 3 )
6054                 fprintf(stderr,"you can ignore redundant getheaders from peer.%d %d prev.%d\n",(int32_t)pfrom->id,(int32_t)(pindex ? pindex->nHeight : -1),pfrom->lasthdrsreq);
6055         }*/
6056     }
6057     
6058     
6059     else if (strCommand == "tx")
6060     {
6061         vector<uint256> vWorkQueue;
6062         vector<uint256> vEraseQueue;
6063         CTransaction tx;
6064         vRecv >> tx;
6065         
6066         CInv inv(MSG_TX, tx.GetHash());
6067         pfrom->AddInventoryKnown(inv);
6068         
6069         LOCK(cs_main);
6070         
6071         bool fMissingInputs = false;
6072         CValidationState state;
6073         
6074         pfrom->setAskFor.erase(inv.hash);
6075         mapAlreadyAskedFor.erase(inv);
6076         
6077         if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6078         {
6079             mempool.check(pcoinsTip);
6080             RelayTransaction(tx);
6081             vWorkQueue.push_back(inv.hash);
6082             
6083             LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6084                      pfrom->id, pfrom->cleanSubVer,
6085                      tx.GetHash().ToString(),
6086                      mempool.mapTx.size());
6087             
6088             // Recursively process any orphan transactions that depended on this one
6089             set<NodeId> setMisbehaving;
6090             for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6091             {
6092                 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6093                 if (itByPrev == mapOrphanTransactionsByPrev.end())
6094                     continue;
6095                 for (set<uint256>::iterator mi = itByPrev->second.begin();
6096                      mi != itByPrev->second.end();
6097                      ++mi)
6098                 {
6099                     const uint256& orphanHash = *mi;
6100                     const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6101                     NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6102                     bool fMissingInputs2 = false;
6103                     // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6104                     // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6105                     // anyone relaying LegitTxX banned)
6106                     CValidationState stateDummy;
6107                     
6108                     
6109                     if (setMisbehaving.count(fromPeer))
6110                         continue;
6111                     if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6112                     {
6113                         LogPrint("mempool", "   accepted orphan tx %s\n", orphanHash.ToString());
6114                         RelayTransaction(orphanTx);
6115                         vWorkQueue.push_back(orphanHash);
6116                         vEraseQueue.push_back(orphanHash);
6117                     }
6118                     else if (!fMissingInputs2)
6119                     {
6120                         int nDos = 0;
6121                         if (stateDummy.IsInvalid(nDos) && nDos > 0)
6122                         {
6123                             // Punish peer that gave us an invalid orphan tx
6124                             Misbehaving(fromPeer, nDos);
6125                             setMisbehaving.insert(fromPeer);
6126                             LogPrint("mempool", "   invalid orphan tx %s\n", orphanHash.ToString());
6127                         }
6128                         // Has inputs but not accepted to mempool
6129                         // Probably non-standard or insufficient fee/priority
6130                         LogPrint("mempool", "   removed orphan tx %s\n", orphanHash.ToString());
6131                         vEraseQueue.push_back(orphanHash);
6132                         assert(recentRejects);
6133                         recentRejects->insert(orphanHash);
6134                     }
6135                     mempool.check(pcoinsTip);
6136                 }
6137             }
6138             
6139             BOOST_FOREACH(uint256 hash, vEraseQueue)
6140             EraseOrphanTx(hash);
6141         }
6142         // TODO: currently, prohibit joinsplits from entering mapOrphans
6143         else if (fMissingInputs && tx.vjoinsplit.size() == 0)
6144         {
6145             AddOrphanTx(tx, pfrom->GetId());
6146             
6147             // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6148             unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6149             unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6150             if (nEvicted > 0)
6151                 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6152         } else {
6153             assert(recentRejects);
6154             recentRejects->insert(tx.GetHash());
6155             
6156             if (pfrom->fWhitelisted) {
6157                 // Always relay transactions received from whitelisted peers, even
6158                 // if they were already in the mempool or rejected from it due
6159                 // to policy, allowing the node to function as a gateway for
6160                 // nodes hidden behind it.
6161                 //
6162                 // Never relay transactions that we would assign a non-zero DoS
6163                 // score for, as we expect peers to do the same with us in that
6164                 // case.
6165                 int nDoS = 0;
6166                 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6167                     LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6168                     RelayTransaction(tx);
6169                 } else {
6170                     LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6171                               tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6172                 }
6173             }
6174         }
6175         int nDoS = 0;
6176         if (state.IsInvalid(nDoS))
6177         {
6178             LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6179                      pfrom->id, pfrom->cleanSubVer,
6180                      state.GetRejectReason());
6181             pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6182                                state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6183             if (nDoS > 0)
6184                 Misbehaving(pfrom->GetId(), nDoS);
6185         }
6186     }
6187
6188     else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6189     {
6190         std::vector<CBlockHeader> headers;
6191         
6192         // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6193         unsigned int nCount = ReadCompactSize(vRecv);
6194         if (nCount > MAX_HEADERS_RESULTS) {
6195             Misbehaving(pfrom->GetId(), 20);
6196             return error("headers message size = %u", nCount);
6197         }
6198         headers.resize(nCount);
6199         for (unsigned int n = 0; n < nCount; n++) {
6200             vRecv >> headers[n];
6201             ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6202         }
6203         
6204         LOCK(cs_main);
6205         
6206         if (nCount == 0) {
6207             // Nothing interesting. Stop asking this peers for more headers.
6208             return true;
6209         }
6210         
6211         CBlockIndex *pindexLast = NULL;
6212         BOOST_FOREACH(const CBlockHeader& header, headers) {
6213             //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6214             //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
6215
6216             CValidationState state;
6217             if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6218                 Misbehaving(pfrom->GetId(), 20);
6219                 return error("non-continuous headers sequence");
6220             }
6221             int32_t futureblock;
6222             //fprintf(stderr,"headers msg nCount.%d\n",(int32_t)nCount);
6223             if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6224                 int nDoS;
6225                 if (state.IsInvalid(nDoS))
6226                 {
6227                     if (nDoS > 0 && futureblock == 0)
6228                         Misbehaving(pfrom->GetId(), nDoS/nDoS);
6229                     return error("invalid header received");
6230                 }
6231             }
6232         }
6233         
6234         if (pindexLast)
6235             UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6236         
6237         if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6238             // Headers message had its maximum size; the peer may have more headers.
6239             // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6240             // from there instead.
6241             if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->nHeight != pfrom->sendhdrsreq )
6242             {
6243                 pfrom->sendhdrsreq = (int32_t)pindexLast->nHeight;
6244                 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
6245                 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6246             }
6247         }
6248         
6249         CheckBlockIndex();
6250     }
6251     
6252     else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6253     {
6254         CBlock block;
6255         vRecv >> block;
6256         
6257         CInv inv(MSG_BLOCK, block.GetHash());
6258         LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6259         
6260         pfrom->AddInventoryKnown(inv);
6261         
6262         CValidationState state;
6263         // Process all blocks from whitelisted peers, even if not requested,
6264         // unless we're still syncing with the network.
6265         // Such an unrequested block may still be processed, subject to the
6266         // conditions in AcceptBlock().
6267         bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6268         ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
6269         int nDoS;
6270         if (state.IsInvalid(nDoS)) {
6271             pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6272                                state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6273             if (nDoS > 0) {
6274                 LOCK(cs_main);
6275                 Misbehaving(pfrom->GetId(), nDoS);
6276             }
6277         }
6278         
6279     }
6280     
6281     
6282     // This asymmetric behavior for inbound and outbound connections was introduced
6283     // to prevent a fingerprinting attack: an attacker can send specific fake addresses
6284     // to users' AddrMan and later request them by sending getaddr messages.
6285     // Making nodes which are behind NAT and can only make outgoing connections ignore
6286     // the getaddr message mitigates the attack.
6287     else if ((strCommand == "getaddr") && (pfrom->fInbound))
6288     {
6289         // Only send one GetAddr response per connection to reduce resource waste
6290         //  and discourage addr stamping of INV announcements.
6291         if (pfrom->fSentAddr) {
6292             LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6293             return true;
6294         }
6295         pfrom->fSentAddr = true;
6296         
6297         pfrom->vAddrToSend.clear();
6298         vector<CAddress> vAddr = addrman.GetAddr();
6299         BOOST_FOREACH(const CAddress &addr, vAddr)
6300         pfrom->PushAddress(addr);
6301     }
6302     
6303     
6304     else if (strCommand == "mempool")
6305     {
6306         LOCK2(cs_main, pfrom->cs_filter);
6307         
6308         std::vector<uint256> vtxid;
6309         mempool.queryHashes(vtxid);
6310         vector<CInv> vInv;
6311         BOOST_FOREACH(uint256& hash, vtxid) {
6312             CInv inv(MSG_TX, hash);
6313             CTransaction tx;
6314             bool fInMemPool = mempool.lookup(hash, tx);
6315             if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
6316             if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
6317                 (!pfrom->pfilter))
6318                 vInv.push_back(inv);
6319             if (vInv.size() == MAX_INV_SZ) {
6320                 pfrom->PushMessage("inv", vInv);
6321                 vInv.clear();
6322             }
6323         }
6324         if (vInv.size() > 0)
6325             pfrom->PushMessage("inv", vInv);
6326     }
6327     
6328     
6329     else if (strCommand == "ping")
6330     {
6331         if (pfrom->nVersion > BIP0031_VERSION)
6332         {
6333             uint64_t nonce = 0;
6334             vRecv >> nonce;
6335             // Echo the message back with the nonce. This allows for two useful features:
6336             //
6337             // 1) A remote node can quickly check if the connection is operational
6338             // 2) Remote nodes can measure the latency of the network thread. If this node
6339             //    is overloaded it won't respond to pings quickly and the remote node can
6340             //    avoid sending us more work, like chain download requests.
6341             //
6342             // The nonce stops the remote getting confused between different pings: without
6343             // it, if the remote node sends a ping once per second and this node takes 5
6344             // seconds to respond to each, the 5th ping the remote sends would appear to
6345             // return very quickly.
6346             pfrom->PushMessage("pong", nonce);
6347         }
6348     }
6349     
6350     
6351     else if (strCommand == "pong")
6352     {
6353         int64_t pingUsecEnd = nTimeReceived;
6354         uint64_t nonce = 0;
6355         size_t nAvail = vRecv.in_avail();
6356         bool bPingFinished = false;
6357         std::string sProblem;
6358         
6359         if (nAvail >= sizeof(nonce)) {
6360             vRecv >> nonce;
6361             
6362             // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
6363             if (pfrom->nPingNonceSent != 0) {
6364                 if (nonce == pfrom->nPingNonceSent) {
6365                     // Matching pong received, this ping is no longer outstanding
6366                     bPingFinished = true;
6367                     int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
6368                     if (pingUsecTime > 0) {
6369                         // Successful ping time measurement, replace previous
6370                         pfrom->nPingUsecTime = pingUsecTime;
6371                         pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
6372                     } else {
6373                         // This should never happen
6374                         sProblem = "Timing mishap";
6375                     }
6376                 } else {
6377                     // Nonce mismatches are normal when pings are overlapping
6378                     sProblem = "Nonce mismatch";
6379                     if (nonce == 0) {
6380                         // This is most likely a bug in another implementation somewhere; cancel this ping
6381                         bPingFinished = true;
6382                         sProblem = "Nonce zero";
6383                     }
6384                 }
6385             } else {
6386                 sProblem = "Unsolicited pong without ping";
6387             }
6388         } else {
6389             // This is most likely a bug in another implementation somewhere; cancel this ping
6390             bPingFinished = true;
6391             sProblem = "Short payload";
6392         }
6393         
6394         if (!(sProblem.empty())) {
6395             LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
6396                      pfrom->id,
6397                      pfrom->cleanSubVer,
6398                      sProblem,
6399                      pfrom->nPingNonceSent,
6400                      nonce,
6401                      nAvail);
6402         }
6403         if (bPingFinished) {
6404             pfrom->nPingNonceSent = 0;
6405         }
6406     }
6407     
6408     
6409     else if (fAlerts && strCommand == "alert")
6410     {
6411         CAlert alert;
6412         vRecv >> alert;
6413         
6414         uint256 alertHash = alert.GetHash();
6415         if (pfrom->setKnown.count(alertHash) == 0)
6416         {
6417             if (alert.ProcessAlert(Params().AlertKey()))
6418             {
6419                 // Relay
6420                 pfrom->setKnown.insert(alertHash);
6421                 {
6422                     LOCK(cs_vNodes);
6423                     BOOST_FOREACH(CNode* pnode, vNodes)
6424                     alert.RelayTo(pnode);
6425                 }
6426             }
6427             else {
6428                 // Small DoS penalty so peers that send us lots of
6429                 // duplicate/expired/invalid-signature/whatever alerts
6430                 // eventually get banned.
6431                 // This isn't a Misbehaving(100) (immediate ban) because the
6432                 // peer might be an older or different implementation with
6433                 // a different signature key, etc.
6434                 Misbehaving(pfrom->GetId(), 10);
6435             }
6436         }
6437     }
6438     
6439     
6440     else if (strCommand == "filterload")
6441     {
6442         CBloomFilter filter;
6443         vRecv >> filter;
6444         
6445         if (!filter.IsWithinSizeConstraints())
6446             // There is no excuse for sending a too-large filter
6447             Misbehaving(pfrom->GetId(), 100);
6448         else
6449         {
6450             LOCK(pfrom->cs_filter);
6451             delete pfrom->pfilter;
6452             pfrom->pfilter = new CBloomFilter(filter);
6453             pfrom->pfilter->UpdateEmptyFull();
6454         }
6455         pfrom->fRelayTxes = true;
6456     }
6457     
6458     
6459     else if (strCommand == "filteradd")
6460     {
6461         vector<unsigned char> vData;
6462         vRecv >> vData;
6463         
6464         // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
6465         // and thus, the maximum size any matched object can have) in a filteradd message
6466         if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
6467         {
6468             Misbehaving(pfrom->GetId(), 100);
6469         } else {
6470             LOCK(pfrom->cs_filter);
6471             if (pfrom->pfilter)
6472                 pfrom->pfilter->insert(vData);
6473             else
6474                 Misbehaving(pfrom->GetId(), 100);
6475         }
6476     }
6477     
6478     
6479     else if (strCommand == "filterclear")
6480     {
6481         LOCK(pfrom->cs_filter);
6482         delete pfrom->pfilter;
6483         pfrom->pfilter = new CBloomFilter();
6484         pfrom->fRelayTxes = true;
6485     }
6486     
6487     
6488     else if (strCommand == "reject")
6489     {
6490         if (fDebug) {
6491             try {
6492                 string strMsg; unsigned char ccode; string strReason;
6493                 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
6494                 
6495                 ostringstream ss;
6496                 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
6497                 
6498                 if (strMsg == "block" || strMsg == "tx")
6499                 {
6500                     uint256 hash;
6501                     vRecv >> hash;
6502                     ss << ": hash " << hash.ToString();
6503                 }
6504                 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
6505             } catch (const std::ios_base::failure&) {
6506                 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
6507                 LogPrint("net", "Unparseable reject message received\n");
6508             }
6509         }
6510     }
6511     else if (strCommand == "notfound") {
6512         // We do not care about the NOTFOUND message, but logging an Unknown Command
6513         // message would be undesirable as we transmit it ourselves.
6514     }
6515     
6516     else {
6517         // Ignore unknown commands for extensibility
6518         LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
6519     }
6520     
6521     
6522     
6523     return true;
6524 }
6525
6526 // requires LOCK(cs_vRecvMsg)
6527 bool ProcessMessages(CNode* pfrom)
6528 {
6529     //if (fDebug)
6530     //    LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
6531     
6532     //
6533     // Message format
6534     //  (4) message start
6535     //  (12) command
6536     //  (4) size
6537     //  (4) checksum
6538     //  (x) data
6539     //
6540     bool fOk = true;
6541     
6542     if (!pfrom->vRecvGetData.empty())
6543         ProcessGetData(pfrom);
6544     
6545     // this maintains the order of responses
6546     if (!pfrom->vRecvGetData.empty()) return fOk;
6547     
6548     std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
6549     while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
6550         // Don't bother if send buffer is too full to respond anyway
6551         if (pfrom->nSendSize >= SendBufferSize())
6552             break;
6553         
6554         // get next message
6555         CNetMessage& msg = *it;
6556         
6557         //if (fDebug)
6558         //    LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
6559         //            msg.hdr.nMessageSize, msg.vRecv.size(),
6560         //            msg.complete() ? "Y" : "N");
6561         
6562         // end, if an incomplete message is found
6563         if (!msg.complete())
6564             break;
6565         
6566         // at this point, any failure means we can delete the current message
6567         it++;
6568         
6569         // Scan for message start
6570         if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
6571             LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
6572             fOk = false;
6573             break;
6574         }
6575         
6576         // Read header
6577         CMessageHeader& hdr = msg.hdr;
6578         if (!hdr.IsValid(Params().MessageStart()))
6579         {
6580             LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
6581             continue;
6582         }
6583         string strCommand = hdr.GetCommand();
6584         
6585         // Message size
6586         unsigned int nMessageSize = hdr.nMessageSize;
6587         
6588         // Checksum
6589         CDataStream& vRecv = msg.vRecv;
6590         uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
6591         unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
6592         if (nChecksum != hdr.nChecksum)
6593         {
6594             LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
6595                       SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
6596             continue;
6597         }
6598         
6599         // Process message
6600         bool fRet = false;
6601         try
6602         {
6603             fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
6604             boost::this_thread::interruption_point();
6605         }
6606         catch (const std::ios_base::failure& e)
6607         {
6608             pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
6609             if (strstr(e.what(), "end of data"))
6610             {
6611                 // Allow exceptions from under-length message on vRecv
6612                 LogPrintf("%s(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
6613             }
6614             else if (strstr(e.what(), "size too large"))
6615             {
6616                 // Allow exceptions from over-long size
6617                 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
6618             }
6619             else
6620             {
6621                 //PrintExceptionContinue(&e, "ProcessMessages()");
6622             }
6623         }
6624         catch (const boost::thread_interrupted&) {
6625             throw;
6626         }
6627         catch (const std::exception& e) {
6628             PrintExceptionContinue(&e, "ProcessMessages()");
6629         } catch (...) {
6630             PrintExceptionContinue(NULL, "ProcessMessages()");
6631         }
6632         
6633         if (!fRet)
6634             LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
6635         
6636         break;
6637     }
6638     
6639     // In case the connection got shut down, its receive buffer was wiped
6640     if (!pfrom->fDisconnect)
6641         pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
6642     
6643     return fOk;
6644 }
6645
6646
6647 bool SendMessages(CNode* pto, bool fSendTrickle)
6648 {
6649     const Consensus::Params& consensusParams = Params().GetConsensus();
6650     {
6651         // Don't send anything until we get its version message
6652         if (pto->nVersion == 0)
6653             return true;
6654         
6655         //
6656         // Message: ping
6657         //
6658         bool pingSend = false;
6659         if (pto->fPingQueued) {
6660             // RPC ping request by user
6661             pingSend = true;
6662         }
6663         if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
6664             // Ping automatically sent as a latency probe & keepalive.
6665             pingSend = true;
6666         }
6667         if (pingSend) {
6668             uint64_t nonce = 0;
6669             while (nonce == 0) {
6670                 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
6671             }
6672             pto->fPingQueued = false;
6673             pto->nPingUsecStart = GetTimeMicros();
6674             if (pto->nVersion > BIP0031_VERSION) {
6675                 pto->nPingNonceSent = nonce;
6676                 pto->PushMessage("ping", nonce);
6677             } else {
6678                 // Peer is too old to support ping command with nonce, pong will never arrive.
6679                 pto->nPingNonceSent = 0;
6680                 pto->PushMessage("ping");
6681             }
6682         }
6683         
6684         TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
6685         if (!lockMain)
6686             return true;
6687         
6688         // Address refresh broadcast
6689         static int64_t nLastRebroadcast;
6690         if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
6691         {
6692             LOCK(cs_vNodes);
6693             BOOST_FOREACH(CNode* pnode, vNodes)
6694             {
6695                 // Periodically clear addrKnown to allow refresh broadcasts
6696                 if (nLastRebroadcast)
6697                     pnode->addrKnown.reset();
6698                 
6699                 // Rebroadcast our address
6700                 AdvertizeLocal(pnode);
6701             }
6702             if (!vNodes.empty())
6703                 nLastRebroadcast = GetTime();
6704         }
6705         
6706         //
6707         // Message: addr
6708         //
6709         if (fSendTrickle)
6710         {
6711             vector<CAddress> vAddr;
6712             vAddr.reserve(pto->vAddrToSend.size());
6713             BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
6714             {
6715                 if (!pto->addrKnown.contains(addr.GetKey()))
6716                 {
6717                     pto->addrKnown.insert(addr.GetKey());
6718                     vAddr.push_back(addr);
6719                     // receiver rejects addr messages larger than 1000
6720                     if (vAddr.size() >= 1000)
6721                     {
6722                         pto->PushMessage("addr", vAddr);
6723                         vAddr.clear();
6724                     }
6725                 }
6726             }
6727             pto->vAddrToSend.clear();
6728             if (!vAddr.empty())
6729                 pto->PushMessage("addr", vAddr);
6730         }
6731         
6732         CNodeState &state = *State(pto->GetId());
6733         if (state.fShouldBan) {
6734             if (pto->fWhitelisted)
6735                 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
6736             else {
6737                 pto->fDisconnect = true;
6738                 if (pto->addr.IsLocal())
6739                     LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
6740                 else
6741                 {
6742                     CNode::Ban(pto->addr);
6743                 }
6744             }
6745             state.fShouldBan = false;
6746         }
6747         
6748         BOOST_FOREACH(const CBlockReject& reject, state.rejects)
6749         pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
6750         state.rejects.clear();
6751         
6752         // Start block sync
6753         if (pindexBestHeader == NULL)
6754             pindexBestHeader = chainActive.Tip();
6755         bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
6756         if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
6757             // Only actively request headers from a single peer, unless we're close to today.
6758             if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
6759                 state.fSyncStarted = true;
6760                 nSyncStarted++;
6761                 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
6762                 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
6763                 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
6764             }
6765         }
6766         
6767         // Resend wallet transactions that haven't gotten in a block yet
6768         // Except during reindex, importing and IBD, when old wallet
6769         // transactions become unconfirmed and spams other nodes.
6770         if (!fReindex && !fImporting && !IsInitialBlockDownload())
6771         {
6772             GetMainSignals().Broadcast(nTimeBestReceived);
6773         }
6774         
6775         //
6776         // Message: inventory
6777         //
6778         vector<CInv> vInv;
6779         vector<CInv> vInvWait;
6780         {
6781             LOCK(pto->cs_inventory);
6782             vInv.reserve(pto->vInventoryToSend.size());
6783             vInvWait.reserve(pto->vInventoryToSend.size());
6784             BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
6785             {
6786                 if (pto->setInventoryKnown.count(inv))
6787                     continue;
6788                 
6789                 // trickle out tx inv to protect privacy
6790                 if (inv.type == MSG_TX && !fSendTrickle)
6791                 {
6792                     // 1/4 of tx invs blast to all immediately
6793                     static uint256 hashSalt;
6794                     if (hashSalt.IsNull())
6795                         hashSalt = GetRandHash();
6796                     uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
6797                     hashRand = Hash(BEGIN(hashRand), END(hashRand));
6798                     bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
6799                     
6800                     if (fTrickleWait)
6801                     {
6802                         vInvWait.push_back(inv);
6803                         continue;
6804                     }
6805                 }
6806                 
6807                 // returns true if wasn't already contained in the set
6808                 if (pto->setInventoryKnown.insert(inv).second)
6809                 {
6810                     vInv.push_back(inv);
6811                     if (vInv.size() >= 1000)
6812                     {
6813                         pto->PushMessage("inv", vInv);
6814                         vInv.clear();
6815                     }
6816                 }
6817             }
6818             pto->vInventoryToSend = vInvWait;
6819         }
6820         if (!vInv.empty())
6821             pto->PushMessage("inv", vInv);
6822         
6823         // Detect whether we're stalling
6824         int64_t nNow = GetTimeMicros();
6825         if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
6826             // Stalling only triggers when the block download window cannot move. During normal steady state,
6827             // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
6828             // should only happen during initial block download.
6829             LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
6830             pto->fDisconnect = true;
6831         }
6832         // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
6833         // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
6834         // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
6835         // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
6836         // to unreasonably increase our timeout.
6837         // We also compare the block download timeout originally calculated against the time at which we'd disconnect
6838         // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
6839         // only looking at this peer's oldest request).  This way a large queue in the past doesn't result in a
6840         // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
6841         // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
6842         if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
6843             QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
6844             int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
6845             if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
6846                 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
6847                 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
6848             }
6849             if (queuedBlock.nTimeDisconnect < nNow) {
6850                 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
6851                 pto->fDisconnect = true;
6852             }
6853         }
6854         
6855         //
6856         // Message: getdata (blocks)
6857         //
6858         static uint256 zero;
6859         vector<CInv> vGetData;
6860         if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6861             vector<CBlockIndex*> vToDownload;
6862             NodeId staller = -1;
6863             FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
6864             BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
6865                 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6866                 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
6867                 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
6868                          pindex->nHeight, pto->id);
6869             }
6870             if (state.nBlocksInFlight == 0 && staller != -1) {
6871                 if (State(staller)->nStallingSince == 0) {
6872                     State(staller)->nStallingSince = nNow;
6873                     LogPrint("net", "Stall started peer=%d\n", staller);
6874                 }
6875             }
6876         }
6877         /*CBlockIndex *pindex;
6878         if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
6879         {
6880             LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
6881             fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
6882             vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
6883             MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
6884             komodo_requestedcount++;
6885             if ( komodo_requestedcount > 16 )
6886             {
6887                 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
6888                 komodo_requestedcount = 0;
6889             }
6890         }*/
6891    
6892         //
6893         // Message: getdata (non-blocks)
6894         //
6895         while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
6896         {
6897             const CInv& inv = (*pto->mapAskFor.begin()).second;
6898             if (!AlreadyHave(inv))
6899             {
6900                 if (fDebug)
6901                     LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
6902                 vGetData.push_back(inv);
6903                 if (vGetData.size() >= 1000)
6904                 {
6905                     pto->PushMessage("getdata", vGetData);
6906                     vGetData.clear();
6907                 }
6908             } else {
6909                 //If we're not going to ask, don't expect a response.
6910                 pto->setAskFor.erase(inv.hash);
6911             }
6912             pto->mapAskFor.erase(pto->mapAskFor.begin());
6913         }
6914         if (!vGetData.empty())
6915             pto->PushMessage("getdata", vGetData);
6916         
6917     }
6918     return true;
6919 }
6920
6921 std::string CBlockFileInfo::ToString() const {
6922     return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
6923 }
6924
6925
6926
6927 class CMainCleanup
6928 {
6929 public:
6930     CMainCleanup() {}
6931     ~CMainCleanup() {
6932         // block headers
6933         BlockMap::iterator it1 = mapBlockIndex.begin();
6934         for (; it1 != mapBlockIndex.end(); it1++)
6935             delete (*it1).second;
6936         mapBlockIndex.clear();
6937         
6938         // orphan transactions
6939         mapOrphanTransactions.clear();
6940         mapOrphanTransactionsByPrev.clear();
6941     }
6942 } instance_of_cmaincleanup;
6943
6944 extern "C" const char* getDataDir()
6945 {
6946     return GetDataDir().string().c_str();
6947 }
6948
6949
6950 // Set default values of new CMutableTransaction based on consensus rules at given height.
6951 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
6952 {
6953     CMutableTransaction mtx;
6954     
6955     bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
6956     if (isOverwintered) {
6957         mtx.fOverwintered = true;
6958         mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
6959         mtx.nVersion = 3;
6960         // Expiry height is not set. Only fields required for a parser to treat as a valid Overwinter V3 tx.
6961         
6962         // TODO: In future, when moving from Overwinter to Sapling, it will be useful
6963         // to set the expiry height to: min(activation_height - 1, default_expiry_height)
6964     }
6965     return mtx;
6966 }
This page took 0.420872 seconds and 4 git commands to generate.