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