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