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.
12 #include "arith_uint256.h"
13 #include "importcoin.h"
14 #include "chainparams.h"
15 #include "checkpoints.h"
16 #include "checkqueue.h"
17 #include "consensus/upgrades.h"
18 #include "consensus/validation.h"
19 #include "deprecation.h"
21 #include "merkleblock.h"
23 #include "notarisationdb.h"
26 #include "script/interpreter.h"
28 #include "txmempool.h"
29 #include "ui_interface.h"
32 #include "utilmoneystr.h"
33 #include "validationinterface.h"
34 #include "wallet/asyncrpcoperation_sendmany.h"
35 #include "wallet/asyncrpcoperation_shieldcoinbase.h"
39 #include <boost/algorithm/string/replace.hpp>
40 #include <boost/filesystem.hpp>
41 #include <boost/filesystem/fstream.hpp>
42 #include <boost/math/distributions/poisson.hpp>
43 #include <boost/thread.hpp>
44 #include <boost/static_assert.hpp>
49 # error "Zcash cannot be compiled without assertions."
57 CCriticalSection cs_main;
58 extern uint8_t NOTARY_PUBKEY33[33];
59 extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN;
60 int32_t KOMODO_NEWBLOCKS;
61 int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
62 void komodo_broadcast(CBlock *pblock,int32_t limit);
64 BlockMap mapBlockIndex;
66 CBlockIndex *pindexBestHeader = NULL;
67 int64_t nTimeBestReceived = 0;
68 CWaitableCriticalSection csBestBlock;
69 CConditionVariable cvBlockChange;
70 int nScriptCheckThreads = 0;
71 bool fExperimentalMode = false;
72 bool fImporting = false;
73 bool fReindex = false;
74 bool fTxIndex = false;
75 bool fAddressIndex = false;
76 bool fTimestampIndex = false;
77 bool fSpentIndex = false;
78 bool fHavePruned = false;
79 bool fPruneMode = false;
80 bool fIsBareMultisigStd = true;
81 bool fCheckBlockIndex = false;
82 bool fCheckpointsEnabled = true;
83 bool fCoinbaseEnforcedProtectionEnabled = true;
84 size_t nCoinCacheUsage = 5000 * 300;
85 uint64_t nPruneTarget = 0;
86 bool fAlerts = DEFAULT_ALERTS;
88 unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
90 /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
91 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
93 CTxMemPool mempool(::minRelayTxFee);
99 map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
100 map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
101 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
104 * Returns true if there are nRequired or more blocks of minVersion or above
105 * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
107 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
108 static void CheckBlockIndex();
110 /** Constant stuff for coinbase transactions we create: */
111 CScript COINBASE_FLAGS;
113 const string strMessageMagic = "Komodo Signed Message:\n";
118 struct CBlockIndexWorkComparator
120 bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
121 // First sort by most total work, ...
122 if (pa->nChainWork > pb->nChainWork) return false;
123 if (pa->nChainWork < pb->nChainWork) return true;
125 // ... then by earliest time received, ...
126 if (pa->nSequenceId < pb->nSequenceId) return false;
127 if (pa->nSequenceId > pb->nSequenceId) return true;
129 // Use pointer address as tie breaker (should only happen with blocks
130 // loaded from disk, as those all have id 0).
131 if (pa < pb) return false;
132 if (pa > pb) return true;
139 CBlockIndex *pindexBestInvalid;
142 * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
143 * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
144 * missing the data for the block.
146 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
147 /** Number of nodes with fSyncStarted. */
148 int nSyncStarted = 0;
149 /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
150 * Pruned nodes may have entries where B is missing data.
152 multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
154 CCriticalSection cs_LastBlockFile;
155 std::vector<CBlockFileInfo> vinfoBlockFile;
156 int nLastBlockFile = 0;
157 /** Global flag to indicate we should check to see if there are
158 * block/undo files that should be deleted. Set on startup
159 * or if we allocate more file space when we're in prune mode
161 bool fCheckForPruning = false;
164 * Every received block is assigned a unique and increasing identifier, so we
165 * know which one to give priority in case of a fork.
167 CCriticalSection cs_nBlockSequenceId;
168 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
169 uint32_t nBlockSequenceId = 1;
172 * Sources of received blocks, saved to be able to send them reject
173 * messages or ban them when processing happens afterwards. Protected by
176 map<uint256, NodeId> mapBlockSource;
179 * Filter for transactions that were recently rejected by
180 * AcceptToMemoryPool. These are not rerequested until the chain tip
181 * changes, at which point the entire filter is reset. Protected by
184 * Without this filter we'd be re-requesting txs from each of our peers,
185 * increasing bandwidth consumption considerably. For instance, with 100
186 * peers, half of which relay a tx we don't accept, that might be a 50x
187 * bandwidth increase. A flooding attacker attempting to roll-over the
188 * filter using minimum-sized, 60byte, transactions might manage to send
189 * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
190 * two minute window to send invs to us.
192 * Decreasing the false positive rate is fairly cheap, so we pick one in a
193 * million to make it highly unlikely for users to have issues with this
198 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
199 uint256 hashRecentRejectsChainTip;
201 /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
204 CBlockIndex *pindex; //! Optional.
205 int64_t nTime; //! Time of "getdata" request in microseconds.
206 bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
207 int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
209 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
211 /** Number of blocks in flight with validated headers. */
212 int nQueuedValidatedHeaders = 0;
214 /** Number of preferable block download peers. */
215 int nPreferredDownload = 0;
217 /** Dirty block index entries. */
218 set<CBlockIndex*> setDirtyBlockIndex;
220 /** Dirty block file entries. */
221 set<int> setDirtyFileInfo;
224 //////////////////////////////////////////////////////////////////////////////
226 // Registration of network node signals.
231 struct CBlockReject {
232 unsigned char chRejectCode;
233 string strRejectReason;
238 * Maintain validation-specific state about nodes, protected by cs_main, instead
239 * by CNode's own locks. This simplifies asynchronous operation, where
240 * processing of incoming data is done after the ProcessMessage call returns,
241 * and we're no longer holding the node's locks.
244 //! The peer's address
246 //! Whether we have a fully established connection.
247 bool fCurrentlyConnected;
248 //! Accumulated misbehaviour score for this peer.
250 //! Whether this peer should be disconnected and banned (unless whitelisted).
252 //! String name of this peer (debugging/logging purposes).
254 //! List of asynchronously-determined block rejections to notify this peer about.
255 std::vector<CBlockReject> rejects;
256 //! The best known block we know this peer has announced.
257 CBlockIndex *pindexBestKnownBlock;
258 //! The hash of the last unknown block this peer has announced.
259 uint256 hashLastUnknownBlock;
260 //! The last full block we both have.
261 CBlockIndex *pindexLastCommonBlock;
262 //! Whether we've started headers synchronization with this peer.
264 //! Since when we're stalling block download progress (in microseconds), or 0.
265 int64_t nStallingSince;
266 list<QueuedBlock> vBlocksInFlight;
268 int nBlocksInFlightValidHeaders;
269 //! Whether we consider this a preferred download peer.
270 bool fPreferredDownload;
273 fCurrentlyConnected = false;
276 pindexBestKnownBlock = NULL;
277 hashLastUnknownBlock.SetNull();
278 pindexLastCommonBlock = NULL;
279 fSyncStarted = false;
282 nBlocksInFlightValidHeaders = 0;
283 fPreferredDownload = false;
287 /** Map maintaining per-node state. Requires cs_main. */
288 map<NodeId, CNodeState> mapNodeState;
291 CNodeState *State(NodeId pnode) {
292 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
293 if (it == mapNodeState.end())
301 return chainActive.Height();
304 void UpdatePreferredDownload(CNode* node, CNodeState* state)
306 nPreferredDownload -= state->fPreferredDownload;
308 // Whether this node should be marked as a preferred download node.
309 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
311 nPreferredDownload += state->fPreferredDownload;
314 // Returns time at which to timeout block request (nTime in microseconds)
315 int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
317 return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
320 void InitializeNode(NodeId nodeid, const CNode *pnode) {
322 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
323 state.name = pnode->addrName;
324 state.address = pnode->addr;
327 void FinalizeNode(NodeId nodeid) {
329 CNodeState *state = State(nodeid);
331 if (state->fSyncStarted)
334 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
335 AddressCurrentlyConnected(state->address);
338 BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
339 mapBlocksInFlight.erase(entry.hash);
340 EraseOrphansFor(nodeid);
341 nPreferredDownload -= state->fPreferredDownload;
343 mapNodeState.erase(nodeid);
346 void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
348 /* int expired = pool.Expire(GetTime() - age);
350 LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
352 std::vector<uint256> vNoSpendsRemaining;
353 pool.TrimToSize(limit, &vNoSpendsRemaining);
354 BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
355 pcoinsTip->Uncache(removed);*/
359 // Returns a bool indicating whether we requested this block.
360 bool MarkBlockAsReceived(const uint256& hash) {
361 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
362 if (itInFlight != mapBlocksInFlight.end()) {
363 CNodeState *state = State(itInFlight->second.first);
364 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
365 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
366 state->vBlocksInFlight.erase(itInFlight->second.second);
367 state->nBlocksInFlight--;
368 state->nStallingSince = 0;
369 mapBlocksInFlight.erase(itInFlight);
376 void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
377 CNodeState *state = State(nodeid);
378 assert(state != NULL);
380 // Make sure it's not listed somewhere already.
381 MarkBlockAsReceived(hash);
383 int64_t nNow = GetTimeMicros();
384 QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
385 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
386 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
387 state->nBlocksInFlight++;
388 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
389 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
392 /** Check whether the last unknown block a peer advertized is not yet known. */
393 void ProcessBlockAvailability(NodeId nodeid) {
394 CNodeState *state = State(nodeid);
395 assert(state != NULL);
397 if (!state->hashLastUnknownBlock.IsNull()) {
398 BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
399 if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0)
401 if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
402 state->pindexBestKnownBlock = itOld->second;
403 state->hashLastUnknownBlock.SetNull();
408 /** Update tracking information about which blocks a peer is assumed to have. */
409 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
410 CNodeState *state = State(nodeid);
411 assert(state != NULL);
413 /*ProcessBlockAvailability(nodeid);
415 BlockMap::iterator it = mapBlockIndex.find(hash);
416 if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
417 // An actually better block was announced.
418 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
419 state->pindexBestKnownBlock = it->second;
422 // An unknown block was announced; just assume that the latest one is the best one.
423 state->hashLastUnknownBlock = hash;
427 /** Find the last common ancestor two blocks have.
428 * Both pa and pb must be non-NULL. */
429 CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
430 if (pa->nHeight > pb->nHeight) {
431 pa = pa->GetAncestor(pb->nHeight);
432 } else if (pb->nHeight > pa->nHeight) {
433 pb = pb->GetAncestor(pa->nHeight);
436 while (pa != pb && pa && pb) {
441 // Eventually all chain branches meet at the genesis block.
446 /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
447 * at most count entries. */
448 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
452 vBlocks.reserve(vBlocks.size() + count);
453 CNodeState *state = State(nodeid);
454 assert(state != NULL);
456 // Make sure pindexBestKnownBlock is up to date, we'll need it.
457 ProcessBlockAvailability(nodeid);
459 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
460 // This peer has nothing interesting.
464 if (state->pindexLastCommonBlock == NULL) {
465 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
466 // Guessing wrong in either direction is not a problem.
467 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
470 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
471 // of its current tip anymore. Go back enough to fix that.
472 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
473 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
476 std::vector<CBlockIndex*> vToFetch;
477 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
478 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
479 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
480 // download that next block if the window were 1 larger.
481 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
482 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
483 NodeId waitingfor = -1;
484 while (pindexWalk->nHeight < nMaxHeight) {
485 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
486 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
487 // as iterating over ~100 CBlockIndex* entries anyway.
488 int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
489 vToFetch.resize(nToFetch);
490 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
491 vToFetch[nToFetch - 1] = pindexWalk;
492 for (unsigned int i = nToFetch - 1; i > 0; i--) {
493 vToFetch[i - 1] = vToFetch[i]->pprev;
496 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
497 // are not yet downloaded and not in flight to vBlocks. In the meantime, update
498 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
499 // already part of our chain (and therefore don't need it even if pruned).
500 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
501 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
502 // We consider the chain that this peer is on invalid.
505 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
506 if (pindex->nChainTx)
507 state->pindexLastCommonBlock = pindex;
508 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
509 // The block is not already downloaded, and not yet in flight.
510 if (pindex->nHeight > nWindowEnd) {
511 // We reached the end of the window.
512 if (vBlocks.size() == 0 && waitingfor != nodeid) {
513 // We aren't able to fetch anything, but we would be if the download window was one larger.
514 nodeStaller = waitingfor;
518 vBlocks.push_back(pindex);
519 if (vBlocks.size() == count) {
522 } else if (waitingfor == -1) {
523 // This is the first already-in-flight block.
524 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
532 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
534 CNodeState *state = State(nodeid);
537 stats.nMisbehavior = state->nMisbehavior;
538 stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
539 stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
540 BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
542 stats.vHeightInFlight.push_back(queue.pindex->nHeight);
547 void RegisterNodeSignals(CNodeSignals& nodeSignals)
549 nodeSignals.GetHeight.connect(&GetHeight);
550 nodeSignals.ProcessMessages.connect(&ProcessMessages);
551 nodeSignals.SendMessages.connect(&SendMessages);
552 nodeSignals.InitializeNode.connect(&InitializeNode);
553 nodeSignals.FinalizeNode.connect(&FinalizeNode);
556 void UnregisterNodeSignals(CNodeSignals& nodeSignals)
558 nodeSignals.GetHeight.disconnect(&GetHeight);
559 nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
560 nodeSignals.SendMessages.disconnect(&SendMessages);
561 nodeSignals.InitializeNode.disconnect(&InitializeNode);
562 nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
565 CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
567 // Find the first block the caller has in the main chain
568 BOOST_FOREACH(const uint256& hash, locator.vHave) {
569 BlockMap::iterator mi = mapBlockIndex.find(hash);
570 if (mi != mapBlockIndex.end())
572 CBlockIndex* pindex = (*mi).second;
573 if (pindex != 0 && chain.Contains(pindex))
575 if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
580 return chain.Genesis();
583 CCoinsViewCache *pcoinsTip = NULL;
584 CBlockTreeDB *pblocktree = NULL;
591 UniValue komodo_snapshot()
595 UniValue result(UniValue::VOBJ);
598 if ( pblocktree != 0 ) {
599 result = pblocktree->Snapshot();
601 fprintf(stderr,"null pblocktree start with -addressindex=true\n");
604 fprintf(stderr,"getsnapshot requires -addressindex=true\n");
609 //////////////////////////////////////////////////////////////////////////////
611 // mapOrphanTransactions
614 bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
616 uint256 hash = tx.GetHash();
617 if (mapOrphanTransactions.count(hash))
620 // Ignore big transactions, to avoid a
621 // send-big-orphans memory exhaustion attack. If a peer has a legitimate
622 // large transaction with a missing parent then we assume
623 // it will rebroadcast it later, after the parent transaction(s)
624 // have been mined or received.
625 // 10,000 orphans, each of which is at most 5,000 bytes big is
626 // at most 500 megabytes of orphans:
627 unsigned int sz = tx.GetSerializeSize(SER_NETWORK, tx.nVersion);
630 LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
634 mapOrphanTransactions[hash].tx = tx;
635 mapOrphanTransactions[hash].fromPeer = peer;
636 BOOST_FOREACH(const CTxIn& txin, tx.vin)
637 mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
639 LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
640 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
644 void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
646 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
647 if (it == mapOrphanTransactions.end())
649 BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
651 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
652 if (itPrev == mapOrphanTransactionsByPrev.end())
654 itPrev->second.erase(hash);
655 if (itPrev->second.empty())
656 mapOrphanTransactionsByPrev.erase(itPrev);
658 mapOrphanTransactions.erase(it);
661 void EraseOrphansFor(NodeId peer)
664 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
665 while (iter != mapOrphanTransactions.end())
667 map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
668 if (maybeErase->second.fromPeer == peer)
670 EraseOrphanTx(maybeErase->second.tx.GetHash());
674 if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
678 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
680 unsigned int nEvicted = 0;
681 while (mapOrphanTransactions.size() > nMaxOrphans)
683 // Evict a random orphan:
684 uint256 randomhash = GetRandHash();
685 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
686 if (it == mapOrphanTransactions.end())
687 it = mapOrphanTransactions.begin();
688 EraseOrphanTx(it->first);
695 bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
697 bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
700 // Overwinter standard rules apply
701 if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
702 reason = "overwinter-version";
706 // Sprout standard rules apply
707 if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
713 BOOST_FOREACH(const CTxIn& txin, tx.vin)
715 // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
716 // keys. (remember the 520 byte limit on redeemScript size) That works
717 // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
718 // bytes of scriptSig, which we round off to 1650 bytes for some minor
719 // future-proofing. That's also enough to spend a 20-of-20
720 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
721 // considered standard)
722 if (txin.scriptSig.size() > 1650) {
723 reason = "scriptsig-size";
726 if (!txin.scriptSig.IsPushOnly()) {
727 reason = "scriptsig-not-pushonly";
732 unsigned int v=0,nDataOut = 0;
733 txnouttype whichType;
734 BOOST_FOREACH(const CTxOut& txout, tx.vout)
736 if (!::IsStandard(txout.scriptPubKey, whichType))
738 reason = "scriptpubkey";
739 fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
743 if (whichType == TX_NULL_DATA)
746 //fprintf(stderr,"is OP_RETURN\n");
748 else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
749 reason = "bare-multisig";
751 } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) {
758 // only one OP_RETURN txout is permitted
760 reason = "multi-op-return";
767 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
770 if (tx.nLockTime == 0)
772 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
774 BOOST_FOREACH(const CTxIn& txin, tx.vin)
776 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)) )
780 else if (!txin.IsFinal())
782 //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
789 bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
791 if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
794 return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
797 bool CheckFinalTx(const CTransaction &tx, int flags)
799 AssertLockHeld(cs_main);
801 // By convention a negative value for flags indicates that the
802 // current network-enforced consensus rules should be used. In
803 // a future soft-fork scenario that would mean checking which
804 // rules would be enforced for the next block and setting the
805 // appropriate flags. At the present time no soft-forks are
806 // scheduled, so no flags are set.
807 flags = std::max(flags, 0);
809 // CheckFinalTx() uses chainActive.Height()+1 to evaluate
810 // nLockTime because when IsFinalTx() is called within
811 // CBlock::AcceptBlock(), the height of the block *being*
812 // evaluated is what is used. Thus if we want to know if a
813 // transaction can be part of the *next* block, we need to call
814 // IsFinalTx() with one more than chainActive.Height().
815 const int nBlockHeight = chainActive.Height() + 1;
817 // Timestamps on the other hand don't get any special treatment,
818 // because we can't know what timestamp the next block will have,
819 // and there aren't timestamp applications where it matters.
820 // However this changes once median past time-locks are enforced:
821 const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
822 ? chainActive.Tip()->GetMedianTimePast()
825 return IsFinalTx(tx, nBlockHeight, nBlockTime);
829 * Check transaction inputs to mitigate two
830 * potential denial-of-service attacks:
832 * 1. scriptSigs with extra data stuffed into them,
833 * not consumed by scriptPubKey (or P2SH script)
834 * 2. P2SH scripts with a crazy number of expensive
835 * CHECKSIG/CHECKMULTISIG operations
837 bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
840 return true; // Coinbases don't use vin normally
842 if (tx.IsCoinImport())
843 return tx.vin[0].scriptSig.IsCoinImport();
845 for (unsigned int i = 0; i < tx.vin.size(); i++)
847 const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
849 vector<vector<unsigned char> > vSolutions;
850 txnouttype whichType;
851 // get the scriptPubKey corresponding to this input:
852 const CScript& prevScript = prev.scriptPubKey;
853 if (!Solver(prevScript, whichType, vSolutions))
855 int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
856 if (nArgsExpected < 0)
859 // Transactions with extra stuff in their scriptSigs are
860 // non-standard. Note that this EvalScript() call will
861 // be quick, because if there are any operations
862 // beside "push data" in the scriptSig
863 // IsStandardTx() will have already returned false
864 // and this method isn't called.
865 vector<vector<unsigned char> > stack;
866 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
869 if (whichType == TX_SCRIPTHASH)
873 CScript subscript(stack.back().begin(), stack.back().end());
874 vector<vector<unsigned char> > vSolutions2;
875 txnouttype whichType2;
876 if (Solver(subscript, whichType2, vSolutions2))
878 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
881 nArgsExpected += tmpExpected;
885 // Any other Script with less than 15 sigops OK:
886 unsigned int sigops = subscript.GetSigOpCount(true);
887 // ... extra data left on the stack after execution is OK, too:
888 return (sigops <= MAX_P2SH_SIGOPS);
892 if (stack.size() != (unsigned int)nArgsExpected)
899 unsigned int GetLegacySigOpCount(const CTransaction& tx)
901 unsigned int nSigOps = 0;
902 BOOST_FOREACH(const CTxIn& txin, tx.vin)
904 nSigOps += txin.scriptSig.GetSigOpCount(false);
906 BOOST_FOREACH(const CTxOut& txout, tx.vout)
908 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
913 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
915 if (tx.IsCoinBase() || tx.IsCoinImport())
918 unsigned int nSigOps = 0;
919 for (unsigned int i = 0; i < tx.vin.size(); i++)
921 const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
922 if (prevout.scriptPubKey.IsPayToScriptHash())
923 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
929 * Check a transaction contextually against a set of consensus rules valid at a given block height.
932 * 1. AcceptToMemoryPool calls CheckTransaction and this function.
933 * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
934 * and ContextualCheckBlock (which calls this function).
936 bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, const int nHeight, const int dosLevel)
938 bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
939 bool isSprout = !isOverwinter;
941 // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
942 if (isSprout && tx.fOverwintered) {
943 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter is not active yet"),
944 REJECT_INVALID, "tx-overwinter-not-active");
947 // If Overwinter rules apply:
949 // Reject transactions with valid version but missing overwinter flag
950 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
951 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
952 REJECT_INVALID, "tx-overwinter-flag-not-set");
955 // Reject transactions with invalid version
956 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
957 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
958 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
961 // Reject transactions intended for Sprout
962 if (!tx.fOverwintered) {
963 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
964 REJECT_INVALID, "tx-overwinter-active");
967 // Check that all transactions are unexpired
968 if (IsExpiredTx(tx, nHeight)) {
969 return state.DoS(dosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
973 if (!(tx.IsMint() || tx.vjoinsplit.empty())) {
974 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
975 // Empty output script.
977 uint256 dataToBeSigned;
979 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
980 } catch (std::logic_error ex) {
981 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
982 REJECT_INVALID, "error-computing-signature-hash");
985 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
987 // We rely on libsodium to check that the signature is canonical.
988 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
989 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
990 dataToBeSigned.begin(), 32,
991 tx.joinSplitPubKey.begin()
993 return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"),
994 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1000 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1001 libzcash::ProofVerifier& verifier)
1003 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1004 if ( *(int32_t *)&array[0] == 0 )
1005 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1009 for (k=0; k<numbanned; k++)
1011 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1013 static uint32_t counter;
1014 if ( counter++ < 100 )
1015 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->nHeight,j);
1020 // Don't count coinbase transactions because mining skews the count
1021 if (!tx.IsCoinBase()) {
1022 transactionsValidated.increment();
1025 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1028 // Ensure that zk-SNARKs v|| y
1029 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1030 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1031 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1032 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1039 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1041 // Basic checks that don't depend on any context
1045 * 1. The consensus rule below was:
1046 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1047 * which checked if tx.nVersion fell within the range:
1048 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1049 * 2. The parser allowed tx.nVersion to be negative
1052 * 1. The consensus rule checks to see if tx.Version falls within the range:
1053 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1054 * 2. The previous consensus rule checked for negative values within the range:
1055 * INT32_MIN <= tx.nVersion < 0
1056 * This is unnecessary for Overwinter transactions since the parser now
1057 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1058 * and when Overwinter is not active ContextualCheckTransaction rejects
1059 * transactions with fOverwintered set. When fOverwintered is set,
1060 * this function and ContextualCheckTransaction will together check to
1061 * ensure tx.nVersion avoids the following ranges:
1062 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1063 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1065 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1066 return state.DoS(100, error("CheckTransaction(): version too low"),
1067 REJECT_INVALID, "bad-txns-version-too-low");
1069 else if (tx.fOverwintered) {
1070 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1071 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1072 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1074 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1075 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1076 REJECT_INVALID, "bad-tx-version-group-id");
1078 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1079 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1080 REJECT_INVALID, "bad-tx-expiry-height-too-high");
1084 // Transactions can contain empty `vin` and `vout` so long as
1085 // `vjoinsplit` is non-empty.
1086 // Migrations may also have empty `vin`
1087 if (tx.vin.empty() && tx.vjoinsplit.empty())
1088 return state.DoS(10, error("CheckTransaction(): vin empty"),
1089 REJECT_INVALID, "bad-txns-vin-empty");
1090 if (tx.vout.empty() && tx.vjoinsplit.empty())
1091 return state.DoS(10, error("CheckTransaction(): vout empty"),
1092 REJECT_INVALID, "bad-txns-vout-empty");
1095 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE); // sanity
1096 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE)
1097 return state.DoS(100, error("CheckTransaction(): size limits failed"),
1098 REJECT_INVALID, "bad-txns-oversize");
1100 // Check for negative or overflow output values
1101 CAmount nValueOut = 0;
1102 int32_t iscoinbase = tx.IsCoinBase();
1103 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1105 if (txout.nValue < 0)
1106 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1107 REJECT_INVALID, "bad-txns-vout-negative");
1108 if (txout.nValue > MAX_MONEY)
1110 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1111 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1113 if ( ASSETCHAINS_PRIVATE != 0 )
1115 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
1116 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetJoinSplitValueOut() > 0 )
1117 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
1119 nValueOut += txout.nValue;
1120 if (!MoneyRange(nValueOut))
1121 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1122 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1125 // Ensure that joinsplit values are well-formed
1126 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1128 if ( ASSETCHAINS_PUBLIC != 0 )
1130 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1131 REJECT_INVALID, "bad-txns-acprivacy-chain");
1133 if (joinsplit.vpub_old < 0) {
1134 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1135 REJECT_INVALID, "bad-txns-vpub_old-negative");
1138 if (joinsplit.vpub_new < 0) {
1139 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1140 REJECT_INVALID, "bad-txns-vpub_new-negative");
1143 if (joinsplit.vpub_old > MAX_MONEY) {
1144 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1145 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1148 if (joinsplit.vpub_new > MAX_MONEY) {
1149 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1150 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1153 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1154 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1155 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1158 nValueOut += joinsplit.vpub_old;
1159 if (!MoneyRange(nValueOut)) {
1160 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1161 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1165 // Ensure input values do not exceed MAX_MONEY
1166 // We have not resolved the txin values at this stage,
1167 // but we do know what the joinsplits claim to add
1168 // to the value pool.
1170 CAmount nValueIn = 0;
1171 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1173 nValueIn += it->vpub_new;
1175 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1176 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1177 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1183 // Check for duplicate inputs
1184 set<COutPoint> vInOutPoints;
1185 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1187 if (vInOutPoints.count(txin.prevout))
1188 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1189 REJECT_INVALID, "bad-txns-inputs-duplicate");
1190 vInOutPoints.insert(txin.prevout);
1193 // Check for duplicate joinsplit nullifiers in this transaction
1194 set<uint256> vJoinSplitNullifiers;
1195 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1197 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1199 if (vJoinSplitNullifiers.count(nf))
1200 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1201 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1203 vJoinSplitNullifiers.insert(nf);
1209 // There should be no joinsplits in a coinbase transaction
1210 if (tx.vjoinsplit.size() > 0)
1211 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1212 REJECT_INVALID, "bad-cb-has-joinsplits");
1214 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1215 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1216 REJECT_INVALID, "bad-cb-length");
1220 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1221 if (txin.prevout.IsNull())
1222 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1223 REJECT_INVALID, "bad-txns-prevout-null");
1229 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1231 extern int32_t KOMODO_ON_DEMAND;
1234 uint256 hash = tx.GetHash();
1235 double dPriorityDelta = 0;
1236 CAmount nFeeDelta = 0;
1237 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1238 if (dPriorityDelta > 0 || nFeeDelta > 0)
1242 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1246 // There is a free transaction area in blocks created by most miners,
1247 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1248 // to be considered to fall into this category. We don't want to encourage sending
1249 // multiple transactions instead of one big transaction to avoid fees.
1250 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1254 if (!MoneyRange(nMinFee))
1255 nMinFee = MAX_MONEY;
1260 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
1262 AssertLockHeld(cs_main);
1263 if (pfMissingInputs)
1264 *pfMissingInputs = false;
1266 int nextBlockHeight = chainActive.Height() + 1;
1267 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1269 // Node operator can choose to reject tx by number of transparent inputs
1270 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1271 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1273 size_t n = tx.vin.size();
1275 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1280 auto verifier = libzcash::ProofVerifier::Strict();
1281 if ( komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
1283 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1284 return error("AcceptToMemoryPool: komodo_validate_interest failed");
1286 if (!CheckTransaction(tx, state, verifier))
1289 return error("AcceptToMemoryPool: CheckTransaction failed");
1291 // DoS level set to 10 to be more forgiving.
1292 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1293 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10))
1295 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1298 // Coinbase is only valid in a block, not as a loose transaction
1299 if (tx.IsCoinBase())
1301 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1302 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1304 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1306 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1308 fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
1309 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1311 // Only accept nLockTime-using transactions that can be mined in the next
1312 // block; we don't want our mempool filled up with transactions that can't
1314 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1316 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1317 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1319 // is it already in the memory pool?
1320 uint256 hash = tx.GetHash();
1321 if (pool.exists(hash))
1323 //fprintf(stderr,"already in mempool\n");
1324 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
1327 // Check for conflicts with in-memory transactions
1329 LOCK(pool.cs); // protect pool.mapNextTx
1330 for (unsigned int i = 0; i < tx.vin.size(); i++)
1332 COutPoint outpoint = tx.vin[i].prevout;
1333 if (pool.mapNextTx.count(outpoint))
1335 //static uint32_t counter;
1336 // Disable replacement feature for now
1337 //if ( counter++ < 100 )
1338 //fprintf(stderr,"Disable replacement feature for now\n");
1342 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
1344 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
1346 if (pool.mapNullifiers.count(nf))
1348 fprintf(stderr,"pool.mapNullifiers.count\n");
1357 CCoinsViewCache view(&dummy);
1359 CAmount nValueIn = 0;
1362 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1363 view.SetBackend(viewMemPool);
1365 // do we already have it?
1366 if (view.HaveCoins(hash))
1368 //fprintf(stderr,"view.HaveCoins(hash) error\n");
1369 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
1372 if (tx.IsCoinImport())
1374 // Inverse of normal case; if input exists, it's been spent
1375 if (ExistsImportTombstone(tx, view))
1376 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
1380 // do all inputs exist?
1381 // Note that this does not check for the presence of actual outputs (see the next check for that),
1382 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1383 BOOST_FOREACH(const CTxIn txin, tx.vin)
1385 if (!view.HaveCoins(txin.prevout.hash))
1387 if (pfMissingInputs)
1388 *pfMissingInputs = true;
1389 //fprintf(stderr,"missing inputs\n");
1394 // are the actual inputs available?
1395 if (!view.HaveInputs(tx))
1397 //fprintf(stderr,"accept failure.1\n");
1398 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1401 // are the joinsplit's requirements met?
1402 if (!view.HaveJoinSplitRequirements(tx))
1404 //fprintf(stderr,"accept failure.2\n");
1405 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1408 // Bring the best block into scope
1409 view.GetBestBlock();
1411 nValueIn = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime);
1412 if ( 0 && interest != 0 )
1413 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1414 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1415 view.SetBackend(dummy);
1418 // Check for non-standard pay-to-script-hash in inputs
1419 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1420 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1422 // Check that the transaction doesn't have an excessive number of
1423 // sigops, making it impossible to mine. Since the coinbase transaction
1424 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1425 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1426 // merely non-standard transaction.
1427 unsigned int nSigOps = GetLegacySigOpCount(tx);
1428 nSigOps += GetP2SHSigOpCount(tx, view);
1429 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1431 fprintf(stderr,"accept failure.4\n");
1432 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");
1435 CAmount nValueOut = tx.GetValueOut();
1436 CAmount nFees = nValueIn-nValueOut;
1437 double dPriority = view.GetPriority(tx, chainActive.Height());
1439 // Keep track of transactions that spend a coinbase, which we re-scan
1440 // during reorgs to ensure COINBASE_MATURITY is still met.
1441 bool fSpendsCoinbase = false;
1442 if (!tx.IsCoinImport()) {
1443 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1444 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1445 if (coins->IsCoinBase()) {
1446 fSpendsCoinbase = true;
1452 // Grab the branch ID we expect this transaction to commit to. We don't
1453 // yet know if it does, but if the entry gets added to the mempool, then
1454 // it has passed ContextualCheckInputs and therefore this is correct.
1455 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1457 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1458 unsigned int nSize = entry.GetTxSize();
1460 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1461 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1462 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1464 // Don't accept it if it can't get into a block
1465 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1466 if (fLimitFree && nFees < txMinFee)
1468 //fprintf(stderr,"accept failure.5\n");
1469 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1473 // Require that free transactions have sufficient priority to be mined in the next block.
1474 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1475 fprintf(stderr,"accept failure.6\n");
1476 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1479 // Continuously rate-limit free (really, very-low-fee) transactions
1480 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1481 // be annoying or make others' transactions take longer to confirm.
1482 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1484 static CCriticalSection csFreeLimiter;
1485 static double dFreeCount;
1486 static int64_t nLastTime;
1487 int64_t nNow = GetTime();
1489 LOCK(csFreeLimiter);
1491 // Use an exponentially decaying ~10-minute window:
1492 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1494 // -limitfreerelay unit is thousand-bytes-per-minute
1495 // At default rate it would take over a month to fill 1GB
1496 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1498 fprintf(stderr,"accept failure.7\n");
1499 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1501 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1502 dFreeCount += nSize;
1505 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19 )
1507 fprintf(stderr,"accept failure.8\n");
1508 return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1511 // Check against previous transactions
1512 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1513 PrecomputedTransactionData txdata(tx);
1514 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1516 //fprintf(stderr,"accept failure.9\n");
1517 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1520 // Check again against just the consensus-critical mandatory script
1521 // verification flags, in case of bugs in the standard flags that cause
1522 // transactions to pass as valid when they're actually invalid. For
1523 // instance the STRICTENC flag was incorrectly allowing certain
1524 // CHECKSIG NOT scripts to pass, even though they were invalid.
1526 // There is a similar check in CreateNewBlock() to prevent creating
1527 // invalid blocks, however allowing such transactions into the mempool
1528 // can be exploited as a DoS attack.
1529 // XXX: is this neccesary for CryptoConditions?
1530 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1532 fprintf(stderr,"accept failure.10\n");
1533 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1536 // Store transaction in memory
1537 if ( komodo_is_notarytx(tx) == 0 )
1539 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1541 // Add memory address index
1542 if (fAddressIndex) {
1543 pool.addAddressIndex(entry, view);
1546 // Add memory spent index
1548 pool.addSpentIndex(entry, view);
1552 SyncWithWallets(tx, NULL);
1557 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1559 if (!fTimestampIndex)
1560 return error("Timestamp index not enabled");
1562 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1563 return error("Unable to get hashes for timestamps");
1568 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1573 if (mempool.getSpentIndex(key, value))
1576 if (!pblocktree->ReadSpentIndex(key, value))
1582 bool GetAddressIndex(uint160 addressHash, int type,
1583 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1586 return error("address index not enabled");
1588 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1589 return error("unable to get txids for address");
1594 bool GetAddressUnspent(uint160 addressHash, int type,
1595 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1598 return error("address index not enabled");
1600 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1601 return error("unable to get txids for address");
1606 bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1608 // need a GetTransaction without lock so the validation code for assets can run without deadlock
1610 //fprintf(stderr,"check mempool\n");
1611 if (mempool.lookup(hash, txOut))
1613 //fprintf(stderr,"found in mempool\n");
1617 //fprintf(stderr,"check disk\n");
1621 //fprintf(stderr,"ReadTxIndex\n");
1622 if (pblocktree->ReadTxIndex(hash, postx)) {
1623 //fprintf(stderr,"OpenBlockFile\n");
1624 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1626 return error("%s: OpenBlockFile failed", __func__);
1627 CBlockHeader header;
1628 //fprintf(stderr,"seek and read\n");
1631 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1633 } catch (const std::exception& e) {
1634 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1636 hashBlock = header.GetHash();
1637 if (txOut.GetHash() != hash)
1638 return error("%s: txid mismatch", __func__);
1639 //fprintf(stderr,"found on disk\n");
1643 //fprintf(stderr,"not found\n");
1647 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1648 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1650 CBlockIndex *pindexSlow = NULL;
1654 if (mempool.lookup(hash, txOut))
1661 if (pblocktree->ReadTxIndex(hash, postx)) {
1662 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1664 return error("%s: OpenBlockFile failed", __func__);
1665 CBlockHeader header;
1668 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1670 } catch (const std::exception& e) {
1671 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1673 hashBlock = header.GetHash();
1674 if (txOut.GetHash() != hash)
1675 return error("%s: txid mismatch", __func__);
1680 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1683 CCoinsViewCache &view = *pcoinsTip;
1684 const CCoins* coins = view.AccessCoins(hash);
1686 nHeight = coins->nHeight;
1689 pindexSlow = chainActive[nHeight];
1694 if (ReadBlockFromDisk(block, pindexSlow,1)) {
1695 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1696 if (tx.GetHash() == hash) {
1698 hashBlock = pindexSlow->GetBlockHash();
1708 /*char *komodo_getspendscript(uint256 hash,int32_t n)
1710 CTransaction tx; uint256 hashBlock;
1711 if ( !GetTransaction(hash,tx,hashBlock,true) )
1713 printf("null GetTransaction\n");
1716 if ( n >= 0 && n < tx.vout.size() )
1717 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
1718 else printf("getspendscript illegal n.%d\n",n);
1723 //////////////////////////////////////////////////////////////////////////////
1725 // CBlock and CBlockIndex
1728 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
1730 // Open history file to append
1731 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
1732 if (fileout.IsNull())
1733 return error("WriteBlockToDisk: OpenBlockFile failed");
1735 // Write index header
1736 unsigned int nSize = fileout.GetSerializeSize(block);
1737 fileout << FLATDATA(messageStart) << nSize;
1740 long fileOutPos = ftell(fileout.Get());
1742 return error("WriteBlockToDisk: ftell failed");
1743 pos.nPos = (unsigned int)fileOutPos;
1749 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
1751 uint8_t pubkey33[33];
1754 // Open history file to read
1755 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
1756 if (filein.IsNull())
1758 //fprintf(stderr,"readblockfromdisk err A\n");
1759 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
1766 catch (const std::exception& e) {
1767 fprintf(stderr,"readblockfromdisk err B\n");
1768 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
1771 if ( 0 && checkPOW != 0 )
1773 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
1774 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(height,pubkey33,block.GetHash(), block.nBits, Params().GetConsensus(),block.nTime)))
1776 int32_t i; for (i=0; i<33; i++)
1777 fprintf(stderr,"%02x",pubkey33[i]);
1778 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
1780 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
1786 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
1790 if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW))
1792 if (block.GetHash() != pindex->GetBlockHash())
1793 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
1794 pindex->ToString(), pindex->GetBlockPos().ToString());
1798 //uint64_t komodo_moneysupply(int32_t height);
1799 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
1800 extern uint32_t ASSETCHAINS_MAGIC;
1801 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
1802 extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
1804 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
1806 static uint64_t cached_subsidy; static int32_t cached_numhalvings;
1807 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
1808 if ( ASSETCHAINS_SYMBOL[0] == 0 )
1811 return(100000000 * COIN); // ICO allocation
1812 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
1820 if ( ASSETCHAINS_STAKED == 0 || strcmp("VRSC",ASSETCHAINS_SYMBOL) == 0 )
1821 return(ASSETCHAINS_SUPPLY * COIN + (ASSETCHAINS_MAGIC & 0xffffff));
1822 else return(ASSETCHAINS_SUPPLY * COIN + ASSETCHAINS_MAGIC);
1824 else if ( ASSETCHAINS_ENDSUBSIDY == 0 || nHeight < ASSETCHAINS_ENDSUBSIDY )
1826 if ( ASSETCHAINS_REWARD == 0 )
1828 else if ( ASSETCHAINS_ENDSUBSIDY != 0 && nHeight >= ASSETCHAINS_ENDSUBSIDY )
1832 nSubsidy = ASSETCHAINS_REWARD;
1833 if ( ASSETCHAINS_HALVING != 0 )
1835 if ( (numhalvings= (nHeight / ASSETCHAINS_HALVING)) > 0 )
1837 if ( numhalvings >= 64 && ASSETCHAINS_DECAY == 0 )
1839 if ( ASSETCHAINS_DECAY == 0 )
1840 nSubsidy >>= numhalvings;
1841 else if ( ASSETCHAINS_DECAY == 100000000 && ASSETCHAINS_ENDSUBSIDY != 0 )
1843 numerator = (ASSETCHAINS_ENDSUBSIDY - nHeight);
1844 nSubsidy = (nSubsidy * numerator) / ASSETCHAINS_ENDSUBSIDY;
1848 if ( cached_subsidy > 0 && cached_numhalvings == numhalvings )
1849 nSubsidy = cached_subsidy;
1852 for (i=0; i<numhalvings&&nSubsidy!=0; i++)
1853 nSubsidy = (nSubsidy * ASSETCHAINS_DECAY) / 100000000;
1854 cached_subsidy = nSubsidy;
1855 cached_numhalvings = numhalvings;
1865 // Mining slow start
1866 // The subsidy is ramped up linearly, skipping the middle payout of
1867 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
1868 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
1869 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
1870 nSubsidy *= nHeight;
1872 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
1873 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
1874 nSubsidy *= (nHeight+1);
1878 assert(nHeight > consensusParams.SubsidySlowStartShift());
1879 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
1880 // Force block reward to zero when right shift is undefined.
1881 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
1882 //if (halvings >= 64)
1885 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
1886 //nSubsidy >>= halvings;
1890 bool IsInitialBlockDownload()
1892 const CChainParams& chainParams = Params();
1894 if (fImporting || fReindex)
1896 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
1899 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
1901 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload\n");
1904 static bool lockIBDState = false;
1907 //fprintf(stderr,"lockIBDState true %d < %d\n",chainActive.Height(),pindexBestHeader->nHeight - 10);
1910 bool state; CBlockIndex *ptr = chainActive.Tip();
1912 ptr = pindexBestHeader;
1913 else if ( pindexBestHeader != 0 && pindexBestHeader->nHeight > ptr->nHeight )
1914 ptr = pindexBestHeader;
1915 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
1916 state = ((chainActive.Height() < ptr->nHeight - 24*60) ||
1917 ptr->GetBlockTime() < (GetTime() - chainParams.MaxTipAge()));
1918 //else state = (chainActive.Height() < ptr->nHeight - 24*60);
1919 //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()));
1922 lockIBDState = true;
1927 bool fLargeWorkForkFound = false;
1928 bool fLargeWorkInvalidChainFound = false;
1929 CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
1931 void CheckForkWarningConditions()
1933 AssertLockHeld(cs_main);
1934 // Before we get past initial download, we cannot reliably alert about forks
1935 // (we assume we don't get stuck on a fork before the last checkpoint)
1936 if (IsInitialBlockDownload())
1939 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
1940 // of our head, drop it
1941 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 288)
1942 pindexBestForkTip = NULL;
1944 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.LastTip()->nChainWork + (GetBlockProof(*chainActive.LastTip()) * 6)))
1946 if (!fLargeWorkForkFound && pindexBestForkBase)
1948 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
1949 pindexBestForkBase->phashBlock->ToString() + std::string("'");
1950 CAlert::Notify(warning, true);
1952 if (pindexBestForkTip && pindexBestForkBase)
1954 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__,
1955 pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
1956 pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
1957 fLargeWorkForkFound = true;
1961 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
1962 LogPrintf("%s: %s\n", warning.c_str(), __func__);
1963 CAlert::Notify(warning, true);
1964 fLargeWorkInvalidChainFound = true;
1969 fLargeWorkForkFound = false;
1970 fLargeWorkInvalidChainFound = false;
1974 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
1976 AssertLockHeld(cs_main);
1977 // If we are on a fork that is sufficiently large, set a warning flag
1978 CBlockIndex* pfork = pindexNewForkTip;
1979 CBlockIndex* plonger = chainActive.LastTip();
1980 while (pfork && pfork != plonger)
1982 while (plonger && plonger->nHeight > pfork->nHeight)
1983 plonger = plonger->pprev;
1984 if (pfork == plonger)
1986 pfork = pfork->pprev;
1989 // We define a condition where we should warn the user about as a fork of at least 7 blocks
1990 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
1991 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
1992 // hash rate operating on the fork.
1993 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
1994 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
1995 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
1996 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
1997 pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
1998 chainActive.Height() - pindexNewForkTip->nHeight < 72)
2000 pindexBestForkTip = pindexNewForkTip;
2001 pindexBestForkBase = pfork;
2004 CheckForkWarningConditions();
2007 // Requires cs_main.
2008 void Misbehaving(NodeId pnode, int howmuch)
2013 CNodeState *state = State(pnode);
2017 state->nMisbehavior += howmuch;
2018 int banscore = GetArg("-banscore", 101);
2019 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
2021 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2022 state->fShouldBan = true;
2024 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2027 void static InvalidChainFound(CBlockIndex* pindexNew)
2029 if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
2030 pindexBestInvalid = pindexNew;
2032 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
2033 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
2034 log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
2035 pindexNew->GetBlockTime()));
2036 CBlockIndex *tip = chainActive.LastTip();
2038 LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
2039 tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
2040 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
2041 CheckForkWarningConditions();
2044 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2046 if (state.IsInvalid(nDoS)) {
2047 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2048 if (it != mapBlockSource.end() && State(it->second)) {
2049 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
2050 State(it->second)->rejects.push_back(reject);
2052 Misbehaving(it->second, nDoS);
2055 if (!state.CorruptionPossible()) {
2056 pindex->nStatus |= BLOCK_FAILED_VALID;
2057 setDirtyBlockIndex.insert(pindex);
2058 setBlockIndexCandidates.erase(pindex);
2059 InvalidChainFound(pindex);
2063 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
2065 if (!tx.IsMint()) // mark inputs spent
2067 txundo.vprevout.reserve(tx.vin.size());
2068 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
2069 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2070 unsigned nPos = txin.prevout.n;
2072 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2074 // mark an outpoint spent, and construct undo information
2075 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2077 if (coins->vout.size() == 0) {
2078 CTxInUndo& undo = txundo.vprevout.back();
2079 undo.nHeight = coins->nHeight;
2080 undo.fCoinBase = coins->fCoinBase;
2081 undo.nVersion = coins->nVersion;
2085 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { // spend nullifiers
2086 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
2087 inputs.SetNullifier(nf, true);
2090 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2093 if (tx.IsCoinImport()) {
2094 // add a tombstone for the burnTx
2095 AddImportTombstone(tx, inputs, nHeight);
2100 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2103 UpdateCoins(tx, inputs, txundo, nHeight);
2106 bool CScriptCheck::operator()() {
2107 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2108 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2109 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
2110 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2115 int GetSpendHeight(const CCoinsViewCache& inputs)
2118 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2119 return pindexPrev->nHeight + 1;
2122 namespace Consensus {
2123 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2125 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2126 // for an attacker to attempt to split the network.
2127 if (!inputs.HaveInputs(tx))
2128 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2130 // are the JoinSplit's requirements met?
2131 if (!inputs.HaveJoinSplitRequirements(tx))
2132 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2134 CAmount nValueIn = 0;
2136 for (unsigned int i = 0; i < tx.vin.size(); i++)
2138 const COutPoint &prevout = tx.vin[i].prevout;
2139 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2142 if (coins->IsCoinBase()) {
2143 // Ensure that coinbases are matured
2144 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2145 return state.Invalid(
2146 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2147 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2150 // Ensure that coinbases cannot be spent to transparent outputs
2151 // Disabled on regtest
2152 if (fCoinbaseEnforcedProtectionEnabled &&
2153 consensusParams.fCoinbaseMustBeProtected &&
2155 return state.Invalid(
2156 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2157 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2161 // Check for negative or overflow input values
2162 nValueIn += coins->vout[prevout.n].nValue;
2163 #ifdef KOMODO_ENABLE_INTEREST
2164 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight >= 60000 )
2166 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2168 int64_t interest; int32_t txheight; uint32_t locktime;
2169 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2171 //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.LastTip()->nTime);
2172 nValueIn += interest;
2177 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2178 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2179 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2183 nValueIn += tx.GetJoinSplitValueIn();
2184 if (!MoneyRange(nValueIn))
2185 return state.DoS(100, error("CheckInputs(): vpub_old values out of range"),
2186 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2188 if (nValueIn < tx.GetValueOut())
2190 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2191 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2192 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2194 // Tally transaction fees
2195 CAmount nTxFee = nValueIn - tx.GetValueOut();
2197 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2198 REJECT_INVALID, "bad-txns-fee-negative");
2200 if (!MoneyRange(nFees))
2201 return state.DoS(100, error("CheckInputs(): nFees out of range"),
2202 REJECT_INVALID, "bad-txns-fee-outofrange");
2205 }// namespace Consensus
2207 bool ContextualCheckInputs(
2208 const CTransaction& tx,
2209 CValidationState &state,
2210 const CCoinsViewCache &inputs,
2214 PrecomputedTransactionData& txdata,
2215 const Consensus::Params& consensusParams,
2216 uint32_t consensusBranchId,
2217 std::vector<CScriptCheck> *pvChecks)
2221 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2226 pvChecks->reserve(tx.vin.size());
2228 // The first loop above does all the inexpensive checks.
2229 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2230 // Helps prevent CPU exhaustion attacks.
2232 // Skip ECDSA signature verification when connecting blocks
2233 // before the last block chain checkpoint. This is safe because block merkle hashes are
2234 // still computed and checked, and any change will be caught at the next checkpoint.
2235 if (fScriptChecks) {
2236 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2237 const COutPoint &prevout = tx.vin[i].prevout;
2238 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2242 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2244 pvChecks->push_back(CScriptCheck());
2245 check.swap(pvChecks->back());
2246 } else if (!check()) {
2247 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2248 // Check whether the failure was caused by a
2249 // non-mandatory script verification check, such as
2250 // non-standard DER encodings or non-null dummy
2251 // arguments; if so, don't trigger DoS protection to
2252 // avoid splitting the network between upgraded and
2253 // non-upgraded nodes.
2254 CScriptCheck check2(*coins, tx, i,
2255 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2257 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2259 // Failures of other flags indicate a transaction that is
2260 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2261 // such nodes as they are not following the protocol. That
2262 // said during an upgrade careful thought should be taken
2263 // as to the correct behavior - we may want to continue
2264 // peering with non-upgraded nodes even after a soft-fork
2265 // super-majority vote has passed.
2266 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2272 if (tx.IsCoinImport())
2274 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2275 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2282 /*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)
2284 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2285 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2289 if (!tx.IsCoinBase())
2291 // While checking, GetBestBlock() refers to the parent block.
2292 // This is also true for mempool checks.
2293 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2294 int nSpendHeight = pindexPrev->nHeight + 1;
2295 for (unsigned int i = 0; i < tx.vin.size(); i++)
2297 const COutPoint &prevout = tx.vin[i].prevout;
2298 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2299 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2303 // If prev is coinbase, check that it's matured
2304 if (coins->IsCoinBase()) {
2305 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2306 COINBASE_MATURITY = _COINBASE_MATURITY;
2307 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2308 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2310 return state.Invalid(
2311 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2322 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2324 // Open history file to append
2325 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2326 if (fileout.IsNull())
2327 return error("%s: OpenUndoFile failed", __func__);
2329 // Write index header
2330 unsigned int nSize = fileout.GetSerializeSize(blockundo);
2331 fileout << FLATDATA(messageStart) << nSize;
2334 long fileOutPos = ftell(fileout.Get());
2336 return error("%s: ftell failed", __func__);
2337 pos.nPos = (unsigned int)fileOutPos;
2338 fileout << blockundo;
2340 // calculate & write checksum
2341 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2342 hasher << hashBlock;
2343 hasher << blockundo;
2344 fileout << hasher.GetHash();
2349 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2351 // Open history file to read
2352 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2353 if (filein.IsNull())
2354 return error("%s: OpenBlockFile failed", __func__);
2357 uint256 hashChecksum;
2359 filein >> blockundo;
2360 filein >> hashChecksum;
2362 catch (const std::exception& e) {
2363 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2366 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2367 hasher << hashBlock;
2368 hasher << blockundo;
2369 if (hashChecksum != hasher.GetHash())
2370 return error("%s: Checksum mismatch", __func__);
2375 /** Abort with a message */
2376 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2378 strMiscWarning = strMessage;
2379 LogPrintf("*** %s\n", strMessage);
2380 uiInterface.ThreadSafeMessageBox(
2381 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2382 "", CClientUIInterface::MSG_ERROR);
2387 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2389 AbortNode(strMessage, userMessage);
2390 return state.Error(strMessage);
2396 * Apply the undo operation of a CTxInUndo to the given chain state.
2397 * @param undo The undo object.
2398 * @param view The coins view to which to apply the changes.
2399 * @param out The out point that corresponds to the tx input.
2400 * @return True on success.
2402 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2406 CCoinsModifier coins = view.ModifyCoins(out.hash);
2407 if (undo.nHeight != 0) {
2408 // undo data contains height: this is the last output of the prevout tx being spent
2409 if (!coins->IsPruned())
2410 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2412 coins->fCoinBase = undo.fCoinBase;
2413 coins->nHeight = undo.nHeight;
2414 coins->nVersion = undo.nVersion;
2416 if (coins->IsPruned())
2417 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2419 if (coins->IsAvailable(out.n))
2420 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2421 if (coins->vout.size() < out.n+1)
2422 coins->vout.resize(out.n+1);
2423 coins->vout[out.n] = undo.txout;
2429 void ConnectNotarisations(const CBlock &block, int height)
2431 // Record Notarisations
2432 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2433 if (notarisations.size() > 0) {
2434 CLevelDBBatch batch;
2435 batch.Write(block.GetHash(), notarisations);
2436 WriteBackNotarisations(notarisations, batch);
2437 pnotarisations->WriteBatch(batch, true);
2438 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2439 notarisations.size(), block.GetHash().GetHex().data());
2444 void DisconnectNotarisations(const CBlock &block)
2446 // Delete from notarisations cache
2447 NotarisationsInBlock nibs;
2448 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2449 CLevelDBBatch batch;
2450 batch.Erase(block.GetHash());
2451 EraseBackNotarisations(nibs, batch);
2452 pnotarisations->WriteBatch(batch, true);
2453 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2454 nibs.size(), block.GetHash().GetHex().data());
2459 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2461 assert(pindex->GetBlockHash() == view.GetBestBlock());
2467 komodo_disconnect(pindex,block);
2468 CBlockUndo blockUndo;
2469 CDiskBlockPos pos = pindex->GetUndoPos();
2471 return error("DisconnectBlock(): no undo data available");
2472 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2473 return error("DisconnectBlock(): failure reading undo data");
2475 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2476 return error("DisconnectBlock(): block and undo data inconsistent");
2477 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2478 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2479 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2481 // undo transactions in reverse order
2482 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2483 const CTransaction &tx = block.vtx[i];
2484 uint256 hash = tx.GetHash();
2485 if (fAddressIndex) {
2487 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2488 const CTxOut &out = tx.vout[k];
2490 if (out.scriptPubKey.IsPayToScriptHash()) {
2491 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2493 // undo receiving activity
2494 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2496 // undo unspent index
2497 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2500 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2501 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2503 // undo receiving activity
2504 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2506 // undo unspent index
2507 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2510 else if (out.scriptPubKey.IsPayToPublicKey()) {
2511 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2513 // undo receiving activity
2514 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2516 // undo unspent index
2517 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2520 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2521 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2523 // undo receiving activity
2524 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2526 // undo unspent index
2527 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2538 // Check that all outputs are available and match the outputs in the block itself
2541 CCoinsModifier outs = view.ModifyCoins(hash);
2542 outs->ClearUnspendable();
2544 CCoins outsBlock(tx, pindex->nHeight);
2545 // The CCoins serialization does not serialize negative numbers.
2546 // No network rules currently depend on the version here, so an inconsistency is harmless
2547 // but it must be corrected before txout nversion ever influences a network rule.
2548 if (outsBlock.nVersion < 0)
2549 outs->nVersion = outsBlock.nVersion;
2550 if (*outs != outsBlock)
2551 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2557 // unspend nullifiers
2558 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
2559 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
2560 view.SetNullifier(nf, false);
2566 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2567 if (txundo.vprevout.size() != tx.vin.size())
2568 return error("DisconnectBlock(): transaction and undo data inconsistent");
2569 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2570 const COutPoint &out = tx.vin[j].prevout;
2571 const CTxInUndo &undo = txundo.vprevout[j];
2572 if (!ApplyTxInUndo(undo, view, out))
2575 const CTxIn input = tx.vin[j];
2578 // undo and delete the spent index
2579 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2582 if (fAddressIndex) {
2583 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2584 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2585 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2587 // undo spending activity
2588 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2590 // restore unspent index
2591 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2595 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2596 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2598 // undo spending activity
2599 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2601 // restore unspent index
2602 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2605 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2606 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2608 // undo spending activity
2609 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2611 // restore unspent index
2612 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2615 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2616 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2618 // undo spending activity
2619 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2621 // restore unspent index
2622 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2631 else if (tx.IsCoinImport())
2633 RemoveImportTombstone(tx, view);
2637 // set the old best anchor back
2638 view.PopAnchor(blockUndo.old_tree_root);
2640 // move best block pointer to prevout block
2641 view.SetBestBlock(pindex->pprev->GetBlockHash());
2648 if (fAddressIndex) {
2649 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2650 return AbortNode(state, "Failed to delete address index");
2652 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2653 return AbortNode(state, "Failed to write address unspent index");
2660 void static FlushBlockFile(bool fFinalize = false)
2662 LOCK(cs_LastBlockFile);
2664 CDiskBlockPos posOld(nLastBlockFile, 0);
2666 FILE *fileOld = OpenBlockFile(posOld);
2669 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2670 FileCommit(fileOld);
2674 fileOld = OpenUndoFile(posOld);
2677 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2678 FileCommit(fileOld);
2683 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
2685 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
2687 void ThreadScriptCheck() {
2688 RenameThread("zcash-scriptch");
2689 scriptcheckqueue.Thread();
2693 // Called periodically asynchronously; alerts if it smells like
2694 // we're being fed a bad chain (blocks being generated much
2695 // too slowly or too quickly).
2697 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2698 int64_t nPowTargetSpacing)
2700 if (bestHeader == NULL || initialDownloadCheck()) return;
2702 static int64_t lastAlertTime = 0;
2703 int64_t now = GetAdjustedTime();
2704 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
2706 const int SPAN_HOURS=4;
2707 const int SPAN_SECONDS=SPAN_HOURS*60*60;
2708 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
2710 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
2712 std::string strWarning;
2713 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
2716 const CBlockIndex* i = bestHeader;
2718 while (i->GetBlockTime() >= startTime) {
2721 if (i == NULL) return; // Ran out of chain, we must not be fully synced
2724 // How likely is it to find that many by chance?
2725 double p = boost::math::pdf(poisson, nBlocks);
2727 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
2728 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
2730 // Aim for one false-positive about every fifty years of normal running:
2731 const int FIFTY_YEARS = 50*365*24*60*60;
2732 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
2734 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
2736 // Many fewer blocks than expected: alert!
2737 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
2738 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
2740 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
2742 // Many more blocks than expected: alert!
2743 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
2744 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
2746 if (!strWarning.empty())
2748 strMiscWarning = strWarning;
2749 CAlert::Notify(strWarning, true);
2750 lastAlertTime = now;
2755 static int64_t nTimeVerify = 0;
2756 static int64_t nTimeConnect = 0;
2757 static int64_t nTimeIndex = 0;
2758 static int64_t nTimeCallbacks = 0;
2759 static int64_t nTimeTotal = 0;
2761 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
2763 const CChainParams& chainparams = Params();
2764 if ( KOMODO_STOPAT != 0 && pindex->nHeight > KOMODO_STOPAT )
2766 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->nHeight);
2767 AssertLockHeld(cs_main);
2768 bool fExpensiveChecks = true;
2769 if (fCheckpointsEnabled) {
2770 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
2771 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
2772 // This block is an ancestor of a checkpoint: disable script checks
2773 fExpensiveChecks = false;
2776 auto verifier = libzcash::ProofVerifier::Strict();
2777 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
2778 int32_t futureblock;
2779 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
2780 if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
2782 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
2786 // verify that the view's current state corresponds to the previous block
2787 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
2788 if ( hashPrevBlock != view.GetBestBlock() )
2790 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
2791 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
2792 REJECT_INVALID, "hashPrevBlock-not-bestblock");
2794 assert(hashPrevBlock == view.GetBestBlock());
2796 // Special case for the genesis block, skipping connection of its transactions
2797 // (its coinbase is unspendable)
2798 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
2800 view.SetBestBlock(pindex->GetBlockHash());
2801 // Before the genesis block, there was an empty tree
2802 ZCIncrementalMerkleTree tree;
2803 pindex->hashAnchor = tree.root();
2804 // The genesis block contained no JoinSplits
2805 pindex->hashAnchorEnd = pindex->hashAnchor;
2810 bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
2811 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->nHeight > KOMODO_TESTNET_EXPIRATION ) // "testnet"
2813 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
2814 // unless those are already completely spent.
2815 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
2816 const CCoins* coins = view.AccessCoins(tx.GetHash());
2817 if (coins && !coins->IsPruned())
2818 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
2819 REJECT_INVALID, "bad-txns-BIP30");
2822 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
2824 // DERSIG (BIP66) is also always enforced, but does not have a flag.
2826 CBlockUndo blockundo;
2828 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
2830 int64_t nTimeStart = GetTimeMicros();
2833 int64_t interest,sum = 0;
2834 unsigned int nSigOps = 0;
2835 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
2836 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2837 vPos.reserve(block.vtx.size());
2838 blockundo.vtxundo.reserve(block.vtx.size() - 1);
2839 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2840 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2841 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2842 // Construct the incremental merkle tree at the current
2844 auto old_tree_root = view.GetBestAnchor();
2845 // saving the top anchor in the block index as we go.
2847 pindex->hashAnchor = old_tree_root;
2849 ZCIncrementalMerkleTree tree;
2850 // This should never fail: we should always be able to get the root
2851 // that is on the tip of our chain
2852 assert(view.GetAnchorAt(old_tree_root, tree));
2855 // Consistency check: the root of the tree we're given should
2856 // match what we asked for.
2857 assert(tree.root() == old_tree_root);
2860 // Grab the consensus branch ID for the block's height
2861 auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus());
2863 std::vector<PrecomputedTransactionData> txdata;
2864 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
2865 for (unsigned int i = 0; i < block.vtx.size(); i++)
2867 const CTransaction &tx = block.vtx[i];
2868 const uint256 txhash = tx.GetHash();
2869 nInputs += tx.vin.size();
2870 nSigOps += GetLegacySigOpCount(tx);
2871 if (nSigOps > MAX_BLOCK_SIGOPS)
2872 return state.DoS(100, error("ConnectBlock(): too many sigops"),
2873 REJECT_INVALID, "bad-blk-sigops");
2874 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->nHeight,tx.nLockTime);
2877 if (!view.HaveInputs(tx))
2879 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
2880 REJECT_INVALID, "bad-txns-inputs-missingorspent");
2882 // are the JoinSplit's requirements met?
2883 if (!view.HaveJoinSplitRequirements(tx))
2884 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
2885 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
2886 if (fAddressIndex || fSpentIndex)
2888 for (size_t j = 0; j < tx.vin.size(); j++) {
2890 const CTxIn input = tx.vin[j];
2891 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2895 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2896 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
2899 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2900 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
2903 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2904 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
2907 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2908 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
2912 hashBytes.SetNull();
2916 if (fAddressIndex && addressType > 0) {
2917 // record spending activity
2918 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
2920 // remove address from unspent index
2921 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
2925 // add the spent index to determine the txid and input that spent an output
2926 // and to find the amount and address from an input
2927 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes)));
2932 // Add in sigops done by pay-to-script-hash inputs;
2933 // this is to prevent a "rogue miner" from creating
2934 // an incredibly-expensive-to-validate block.
2935 nSigOps += GetP2SHSigOpCount(tx, view);
2936 if (nSigOps > MAX_BLOCK_SIGOPS)
2937 return state.DoS(100, error("ConnectBlock(): too many sigops"),
2938 REJECT_INVALID, "bad-blk-sigops");
2941 txdata.emplace_back(tx);
2943 if (!tx.IsCoinBase())
2945 nFees += view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
2948 std::vector<CScriptCheck> vChecks;
2949 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
2951 control.Add(vChecks);
2954 if (fAddressIndex) {
2955 for (unsigned int k = 0; k < tx.vout.size(); k++) {
2956 const CTxOut &out = tx.vout[k];
2957 //fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
2958 if (out.scriptPubKey.IsPayToScriptHash()) {
2959 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2961 // record receiving activity
2962 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
2964 // record unspent output
2965 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
2968 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2969 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2971 // record receiving activity
2972 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
2974 // record unspent output
2975 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
2978 else if (out.scriptPubKey.IsPayToPublicKey()) {
2979 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2981 // record receiving activity
2982 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
2984 // record unspent output
2985 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
2988 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2989 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2991 // record receiving activity
2992 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
2994 // record unspent output
2995 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3005 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3006 // komodo_earned_interest(pindex->nHeight,sum);
3009 blockundo.vtxundo.push_back(CTxUndo());
3011 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
3013 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
3014 BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
3015 // Insert the note commitments into our temporary tree.
3017 tree.append(note_commitment);
3021 vPos.push_back(std::make_pair(tx.GetHash(), pos));
3022 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
3025 view.PushAnchor(tree);
3027 pindex->hashAnchorEnd = tree.root();
3029 blockundo.old_tree_root = old_tree_root;
3031 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3032 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);
3034 CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
3035 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
3037 uint64_t checktoshis;
3038 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
3040 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
3041 blockReward += checktoshis;
3042 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
3045 if ( block.vtx[0].GetValueOut() > blockReward+1 )
3047 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
3049 return state.DoS(100,
3050 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3051 block.vtx[0].GetValueOut(), blockReward),
3052 REJECT_INVALID, "bad-cb-amount");
3053 } else if ( IS_KOMODO_NOTARY != 0 )
3054 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));
3056 if (!control.Wait())
3057 return state.DoS(100, false);
3058 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3059 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);
3064 // Write undo information to disk
3065 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
3067 if (pindex->GetUndoPos().IsNull()) {
3069 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
3070 return error("ConnectBlock(): FindUndoPos failed");
3071 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
3072 return AbortNode(state, "Failed to write undo data");
3074 // update nUndoPos in block index
3075 pindex->nUndoPos = pos.nPos;
3076 pindex->nStatus |= BLOCK_HAVE_UNDO;
3079 // Now that all consensus rules have been validated, set nCachedBranchId.
3080 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3081 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
3082 "nCachedBranchId must be set after all consensus rules have been validated.");
3083 if (IsActivationHeightForAnyUpgrade(pindex->nHeight, Params().GetConsensus())) {
3084 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
3085 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus());
3086 } else if (pindex->pprev) {
3087 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
3090 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
3091 setDirtyBlockIndex.insert(pindex);
3094 ConnectNotarisations(block, pindex->nHeight);
3097 if (!pblocktree->WriteTxIndex(vPos))
3098 return AbortNode(state, "Failed to write transaction index");
3099 if (fAddressIndex) {
3100 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3101 return AbortNode(state, "Failed to write address index");
3104 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3105 return AbortNode(state, "Failed to write address unspent index");
3110 if (!pblocktree->UpdateSpentIndex(spentIndex))
3111 return AbortNode(state, "Failed to write transaction index");
3113 if (fTimestampIndex) {
3114 unsigned int logicalTS = pindex->nTime;
3115 unsigned int prevLogicalTS = 0;
3117 // retrieve logical timestamp of the previous block
3119 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3120 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3122 if (logicalTS <= prevLogicalTS) {
3123 logicalTS = prevLogicalTS + 1;
3124 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3127 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3128 return AbortNode(state, "Failed to write timestamp index");
3130 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3131 return AbortNode(state, "Failed to write blockhash index");
3134 // add this block to the view's block chain
3135 view.SetBestBlock(pindex->GetBlockHash());
3137 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3138 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
3140 // Watch for changes to the previous coinbase transaction.
3141 static uint256 hashPrevBestCoinBase;
3142 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
3143 hashPrevBestCoinBase = block.vtx[0].GetHash();
3145 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3146 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
3148 //FlushStateToDisk();
3149 komodo_connectblock(pindex,*(CBlock *)&block);
3153 enum FlushStateMode {
3155 FLUSH_STATE_IF_NEEDED,
3156 FLUSH_STATE_PERIODIC,
3161 * Update the on-disk chain state.
3162 * The caches and indexes are flushed depending on the mode we're called with
3163 * if they're too large, if it's been a while since the last write,
3164 * or always and in all cases if we're in prune mode and are deleting files.
3166 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
3167 LOCK2(cs_main, cs_LastBlockFile);
3168 static int64_t nLastWrite = 0;
3169 static int64_t nLastFlush = 0;
3170 static int64_t nLastSetChain = 0;
3171 std::set<int> setFilesToPrune;
3172 bool fFlushForPrune = false;
3174 if (fPruneMode && fCheckForPruning && !fReindex) {
3175 FindFilesToPrune(setFilesToPrune);
3176 fCheckForPruning = false;
3177 if (!setFilesToPrune.empty()) {
3178 fFlushForPrune = true;
3180 pblocktree->WriteFlag("prunedblockfiles", true);
3185 int64_t nNow = GetTimeMicros();
3186 // Avoid writing/flushing immediately after startup.
3187 if (nLastWrite == 0) {
3190 if (nLastFlush == 0) {
3193 if (nLastSetChain == 0) {
3194 nLastSetChain = nNow;
3196 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3197 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3198 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3199 // The cache is over the limit, we have to write now.
3200 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3201 // 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.
3202 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3203 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3204 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3205 // Combine all conditions that result in a full cache flush.
3206 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3207 // Write blocks and block index to disk.
3208 if (fDoFullFlush || fPeriodicWrite) {
3209 // Depend on nMinDiskSpace to ensure we can write block index
3210 if (!CheckDiskSpace(0))
3211 return state.Error("out of disk space");
3212 // First make sure all block and undo data is flushed to disk.
3214 // Then update all block file information (which may refer to block and undo files).
3216 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3217 vFiles.reserve(setDirtyFileInfo.size());
3218 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3219 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3220 setDirtyFileInfo.erase(it++);
3222 std::vector<const CBlockIndex*> vBlocks;
3223 vBlocks.reserve(setDirtyBlockIndex.size());
3224 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3225 vBlocks.push_back(*it);
3226 setDirtyBlockIndex.erase(it++);
3228 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3229 return AbortNode(state, "Files to write to block index database");
3232 // Finally remove any pruned files
3234 UnlinkPrunedFiles(setFilesToPrune);
3237 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3239 // Typical CCoins structures on disk are around 128 bytes in size.
3240 // Pushing a new one to the database can cause it to be written
3241 // twice (once in the log, and once in the tables). This is already
3242 // an overestimation, as most will delete an existing entry or
3243 // overwrite one. Still, use a conservative safety factor of 2.
3244 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3245 return state.Error("out of disk space");
3246 // Flush the chainstate (which may refer to block index entries).
3247 if (!pcoinsTip->Flush())
3248 return AbortNode(state, "Failed to write to coin database");
3251 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3252 // Update best block in wallet (so we can detect restored wallets).
3253 GetMainSignals().SetBestChain(chainActive.GetLocator());
3254 nLastSetChain = nNow;
3256 } catch (const std::runtime_error& e) {
3257 return AbortNode(state, std::string("System error while flushing: ") + e.what());
3262 void FlushStateToDisk() {
3263 CValidationState state;
3264 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3267 void PruneAndFlush() {
3268 CValidationState state;
3269 fCheckForPruning = true;
3270 FlushStateToDisk(state, FLUSH_STATE_NONE);
3273 /** Update chainActive and related internal data structures. */
3274 void static UpdateTip(CBlockIndex *pindexNew) {
3275 const CChainParams& chainParams = Params();
3276 chainActive.SetTip(pindexNew);
3279 nTimeBestReceived = GetTime();
3280 mempool.AddTransactionsUpdated(1);
3283 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
3284 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
3286 int32_t longestchain = komodo_longestchain();
3287 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
3290 LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
3291 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3292 log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.LastTip()->nChainTx,
3293 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
3294 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3296 cvBlockChange.notify_all();
3298 // Check the version of the last 100 blocks to see if we need to upgrade:
3299 static bool fWarned = false;
3300 if (!IsInitialBlockDownload() && !fWarned)
3303 const CBlockIndex* pindex = chainActive.Tip();
3304 for (int i = 0; i < 100 && pindex != NULL; i++)
3306 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3308 pindex = pindex->pprev;
3311 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3312 if (nUpgraded > 100/2)
3314 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3315 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3316 CAlert::Notify(strMiscWarning, true);
3323 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3324 * mempool.removeWithoutBranchId after this, with cs_main held.
3326 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3327 CBlockIndex *pindexDelete = chainActive.Tip();
3328 assert(pindexDelete);
3329 // Read block from disk.
3331 if (!ReadBlockFromDisk(block, pindexDelete,1))
3332 return AbortNode(state, "Failed to read block");
3333 // Apply the block atomically to the chain state.
3334 uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
3335 int64_t nStart = GetTimeMicros();
3337 CCoinsViewCache view(pcoinsTip);
3338 if (!DisconnectBlock(block, state, pindexDelete, view))
3339 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3340 assert(view.Flush());
3341 DisconnectNotarisations(block);
3343 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3344 uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor();
3345 // Write the chain state to disk, if necessary.
3346 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3351 // Resurrect mempool transactions from the disconnected block.
3352 //BOOST_FOREACH(const CTransaction &tx, block.vtx) {
3353 for (int i = 0; i < block.vtx.size(); i++)
3355 CTransaction &tx = block.vtx[i];
3356 // ignore validation errors in resurrected transactions
3357 list<CTransaction> removed;
3358 CValidationState stateDummy;
3359 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3360 mempool.remove(tx, removed, true);
3362 if (anchorBeforeDisconnect != anchorAfterDisconnect) {
3363 // The anchor may not change between block disconnects,
3364 // in which case we don't want to evict from the mempool yet!
3365 mempool.removeWithAnchor(anchorBeforeDisconnect);
3369 // Update chainActive and related variables.
3370 UpdateTip(pindexDelete->pprev);
3371 // Get the current commitment tree
3372 ZCIncrementalMerkleTree newTree;
3373 assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), newTree));
3374 // Let wallets know transactions went from 1-confirmed to
3375 // 0-confirmed or conflicted:
3376 //BOOST_FOREACH(const CTransaction &tx, block.vtx) {
3377 // SyncWithWallets(tx, NULL);
3379 // Update cached incremental witnesses
3380 //fprintf(stderr,"chaintip false\n");
3381 for (int i = 0; i < block.vtx.size(); i++)
3383 CTransaction &tx = block.vtx[i];
3384 if ( (i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0 )
3386 EraseFromWallets(tx.GetHash());
3390 SyncWithWallets(tx, NULL);
3393 GetMainSignals().ChainTip(pindexDelete, &block, newTree, false);
3397 static int64_t nTimeReadFromDisk = 0;
3398 static int64_t nTimeConnectTotal = 0;
3399 static int64_t nTimeFlush = 0;
3400 static int64_t nTimeChainState = 0;
3401 static int64_t nTimePostConnect = 0;
3404 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3405 * corresponding to pindexNew, to bypass loading it again from disk.
3406 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3408 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3410 assert(pindexNew->pprev == chainActive.Tip());
3411 // Read block from disk.
3412 int64_t nTime1 = GetTimeMicros();
3415 if (!ReadBlockFromDisk(block, pindexNew,1))
3416 return AbortNode(state, "Failed to read block");
3419 // Get the current commitment tree
3420 ZCIncrementalMerkleTree oldTree;
3421 assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree));
3422 // Apply the block atomically to the chain state.
3423 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3425 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3427 CCoinsViewCache view(pcoinsTip);
3428 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3429 GetMainSignals().BlockChecked(*pblock, state);
3431 if (state.IsInvalid())
3432 InvalidBlockFound(pindexNew, state);
3433 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3435 mapBlockSource.erase(pindexNew->GetBlockHash());
3436 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3437 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3438 assert(view.Flush());
3440 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3441 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3442 // Write the chain state to disk, if necessary.
3443 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3445 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3446 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3447 // Remove conflicting transactions from the mempool.
3448 list<CTransaction> txConflicted;
3449 mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
3451 // Remove transactions that expire at new block height from mempool
3452 mempool.removeExpired(pindexNew->nHeight);
3454 // Update chainActive & related variables.
3455 UpdateTip(pindexNew);
3456 // Tell wallet about transactions that went from mempool
3458 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3459 SyncWithWallets(tx, NULL);
3461 // ... and about transactions that got confirmed:
3462 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3463 SyncWithWallets(tx, pblock);
3465 // Update cached incremental witnesses
3466 //fprintf(stderr,"chaintip true\n");
3467 GetMainSignals().ChainTip(pindexNew, pblock, oldTree, true);
3469 EnforceNodeDeprecation(pindexNew->nHeight);
3471 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3472 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3473 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3474 if ( ASSETCHAINS_SYMBOL[0] == 0 )
3475 komodo_broadcast(pblock,8);
3480 * Return the tip of the chain with the most work in it, that isn't
3481 * known to be invalid (it's however far from certain to be valid).
3483 static CBlockIndex* FindMostWorkChain() {
3485 CBlockIndex *pindexNew = NULL;
3487 // Find the best candidate header.
3489 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3490 if (it == setBlockIndexCandidates.rend())
3495 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3496 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3497 CBlockIndex *pindexTest = pindexNew;
3498 bool fInvalidAncestor = false;
3499 while (pindexTest && !chainActive.Contains(pindexTest)) {
3500 assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
3502 // Pruned nodes may have entries in setBlockIndexCandidates for
3503 // which block files have been deleted. Remove those as candidates
3504 // for the most work chain if we come across them; we can't switch
3505 // to a chain unless we have all the non-active-chain parent blocks.
3506 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3507 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3508 if (fFailedChain || fMissingData) {
3509 // Candidate chain is not usable (either invalid or missing data)
3510 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
3511 pindexBestInvalid = pindexNew;
3512 CBlockIndex *pindexFailed = pindexNew;
3513 // Remove the entire chain from the set.
3514 while (pindexTest != pindexFailed) {
3516 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3517 } else if (fMissingData) {
3518 // If we're missing data, then add back to mapBlocksUnlinked,
3519 // so that if the block arrives in the future we can try adding
3520 // to setBlockIndexCandidates again.
3521 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3523 setBlockIndexCandidates.erase(pindexFailed);
3524 pindexFailed = pindexFailed->pprev;
3526 setBlockIndexCandidates.erase(pindexTest);
3527 fInvalidAncestor = true;
3530 pindexTest = pindexTest->pprev;
3532 if (!fInvalidAncestor)
3537 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3538 static void PruneBlockIndexCandidates() {
3539 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3540 // reorganization to a better block fails.
3541 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3542 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
3543 setBlockIndexCandidates.erase(it++);
3545 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3546 assert(!setBlockIndexCandidates.empty());
3550 * Try to make some progress towards making pindexMostWork the active block.
3551 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3553 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3554 AssertLockHeld(cs_main);
3555 bool fInvalidFound = false;
3556 const CBlockIndex *pindexOldTip = chainActive.Tip();
3557 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3559 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3560 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3561 // then pindexFork will be null, and we would need to remove the entire chain including
3562 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3563 auto reorgLength = pindexOldTip ? pindexOldTip->nHeight - (pindexFork ? pindexFork->nHeight : -1) : 0;
3564 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3565 if (reorgLength > MAX_REORG_LENGTH) {
3566 auto msg = strprintf(_(
3567 "A block chain reorganization has been detected that would roll back %d blocks! "
3568 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3569 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3570 _("Reorganization details") + ":\n" +
3571 "- " + strprintf(_("Current tip: %s, height %d, work %s"),
3572 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" +
3573 "- " + strprintf(_("New tip: %s, height %d, work %s"),
3574 pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" +
3575 "- " + strprintf(_("Fork point: %s %s, height %d"),
3576 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" +
3577 _("Please help, human!");
3578 LogPrintf("*** %s\n", msg);
3579 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3584 // Disconnect active blocks which are no longer in the best chain.
3585 bool fBlocksDisconnected = false;
3586 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3587 if (!DisconnectTip(state))
3589 fBlocksDisconnected = true;
3591 if ( KOMODO_REWIND != 0 )
3593 CBlockIndex *tipindex;
3594 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->nHeight,KOMODO_REWIND);
3595 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->nHeight > KOMODO_REWIND )
3597 fBlocksDisconnected = true;
3598 fprintf(stderr,"%d ",(int32_t)tipindex->nHeight);
3599 InvalidateBlock(state,tipindex);
3600 if ( !DisconnectTip(state) )
3603 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3605 fprintf(stderr,"resuming normal operations\n");
3609 // Build list of new blocks to connect.
3610 std::vector<CBlockIndex*> vpindexToConnect;
3611 bool fContinue = true;
3612 int nHeight = pindexFork ? pindexFork->nHeight : -1;
3613 while (fContinue && nHeight != pindexMostWork->nHeight) {
3614 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3615 // a few blocks along the way.
3616 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
3617 vpindexToConnect.clear();
3618 vpindexToConnect.reserve(nTargetHeight - nHeight);
3619 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3620 while (pindexIter && pindexIter->nHeight != nHeight) {
3621 vpindexToConnect.push_back(pindexIter);
3622 pindexIter = pindexIter->pprev;
3624 nHeight = nTargetHeight;
3626 // Connect new blocks.
3627 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
3628 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
3629 if (state.IsInvalid()) {
3630 // The block violates a consensus rule.
3631 if (!state.CorruptionPossible())
3632 InvalidChainFound(vpindexToConnect.back());
3633 state = CValidationState();
3634 fInvalidFound = true;
3638 // A system error occurred (disk space, database error, ...).
3642 PruneBlockIndexCandidates();
3643 if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
3644 // We're in a better position than we were. Return temporarily to release the lock.
3652 if (fBlocksDisconnected) {
3653 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3655 mempool.removeWithoutBranchId(
3656 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3657 mempool.check(pcoinsTip);
3659 // Callbacks/notifications for a new best chain.
3661 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
3663 CheckForkWarningConditions();
3669 * Make the best chain active, in multiple steps. The result is either failure
3670 * or an activated best chain. pblock is either NULL or a pointer to a block
3671 * that is already loaded (to avoid loading it again from disk).
3673 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
3674 CBlockIndex *pindexNewTip = NULL;
3675 CBlockIndex *pindexMostWork = NULL;
3676 const CChainParams& chainParams = Params();
3678 boost::this_thread::interruption_point();
3680 bool fInitialDownload;
3683 pindexMostWork = FindMostWorkChain();
3685 // Whether we have anything to do at all.
3686 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
3689 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
3691 pindexNewTip = chainActive.Tip();
3692 fInitialDownload = IsInitialBlockDownload();
3694 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
3696 // Notifications/callbacks that can run without cs_main
3697 if (!fInitialDownload) {
3698 uint256 hashNewTip = pindexNewTip->GetBlockHash();
3699 // Relay inventory, but don't relay old inventory during initial block download.
3700 int nBlockEstimate = 0;
3701 if (fCheckpointsEnabled)
3702 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
3703 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
3704 // in a stalled download if the block file is pruned before the request.
3705 if (nLocalServices & NODE_NETWORK) {
3707 BOOST_FOREACH(CNode* pnode, vNodes)
3708 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
3709 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
3711 // Notify external listeners about the new tip.
3712 GetMainSignals().UpdatedBlockTip(pindexNewTip);
3713 uiInterface.NotifyBlockTip(hashNewTip);
3714 } //else fprintf(stderr,"initial download skips propagation\n");
3715 } while(pindexMostWork != chainActive.Tip());
3718 // Write changes periodically to disk, after relay.
3719 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
3726 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
3727 AssertLockHeld(cs_main);
3729 // Mark the block itself as invalid.
3730 pindex->nStatus |= BLOCK_FAILED_VALID;
3731 setDirtyBlockIndex.insert(pindex);
3732 setBlockIndexCandidates.erase(pindex);
3734 while (chainActive.Contains(pindex)) {
3735 CBlockIndex *pindexWalk = chainActive.Tip();
3736 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
3737 setDirtyBlockIndex.insert(pindexWalk);
3738 setBlockIndexCandidates.erase(pindexWalk);
3739 // ActivateBestChain considers blocks already in chainActive
3740 // unconditionally valid already, so force disconnect away from it.
3741 if (!DisconnectTip(state)) {
3742 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3743 mempool.removeWithoutBranchId(
3744 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3748 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
3750 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
3752 BlockMap::iterator it = mapBlockIndex.begin();
3753 while (it != mapBlockIndex.end() && it->second != 0 ) {
3754 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
3755 setBlockIndexCandidates.insert(it->second);
3760 InvalidChainFound(pindex);
3761 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3762 mempool.removeWithoutBranchId(
3763 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3767 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
3768 AssertLockHeld(cs_main);
3770 int nHeight = pindex->nHeight;
3772 // Remove the invalidity flag from this block and all its descendants.
3773 BlockMap::iterator it = mapBlockIndex.begin();
3774 while (it != mapBlockIndex.end()) {
3775 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
3776 it->second->nStatus &= ~BLOCK_FAILED_MASK;
3777 setDirtyBlockIndex.insert(it->second);
3778 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
3779 setBlockIndexCandidates.insert(it->second);
3781 if (it->second == pindexBestInvalid) {
3782 // Reset invalid block marker if it was pointing to one of those.
3783 pindexBestInvalid = NULL;
3789 // Remove the invalidity flag from all ancestors too.
3790 while (pindex != NULL) {
3791 if (pindex->nStatus & BLOCK_FAILED_MASK) {
3792 pindex->nStatus &= ~BLOCK_FAILED_MASK;
3793 setDirtyBlockIndex.insert(pindex);
3795 pindex = pindex->pprev;
3800 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
3802 // Check for duplicate
3803 uint256 hash = block.GetHash();
3804 BlockMap::iterator it = mapBlockIndex.find(hash);
3805 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
3806 if (it != mapBlockIndex.end())
3808 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
3810 // 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
3811 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
3814 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
3816 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
3817 return(0); // return here to avoid the state of pindex->nHeight not set and pprev NULL
3820 // Construct new block index object
3821 CBlockIndex* pindexNew = new CBlockIndex(block);
3823 // We assign the sequence id to blocks only when the full data is available,
3824 // to avoid miners withholding blocks but broadcasting headers, to get a
3825 // competitive advantage.
3826 pindexNew->nSequenceId = 0;
3827 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
3828 pindexNew->phashBlock = &((*mi).first);
3829 if (miPrev != mapBlockIndex.end())
3831 if ( (pindexNew->pprev= (*miPrev).second) != 0 )
3832 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
3833 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
3834 pindexNew->BuildSkip();
3836 pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
3837 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
3838 if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
3839 pindexBestHeader = pindexNew;
3841 setDirtyBlockIndex.insert(pindexNew);
3842 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
3843 mi->second = pindexNew;
3847 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
3848 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
3850 pindexNew->nTx = block.vtx.size();
3851 pindexNew->nChainTx = 0;
3852 CAmount sproutValue = 0;
3853 for (auto tx : block.vtx) {
3854 for (auto js : tx.vjoinsplit) {
3855 sproutValue += js.vpub_old;
3856 sproutValue -= js.vpub_new;
3859 pindexNew->nSproutValue = sproutValue;
3860 pindexNew->nChainSproutValue = boost::none;
3861 pindexNew->nFile = pos.nFile;
3862 pindexNew->nDataPos = pos.nPos;
3863 pindexNew->nUndoPos = 0;
3864 pindexNew->nStatus |= BLOCK_HAVE_DATA;
3865 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
3866 setDirtyBlockIndex.insert(pindexNew);
3868 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
3869 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
3870 deque<CBlockIndex*> queue;
3871 queue.push_back(pindexNew);
3873 // Recursively process any descendant blocks that now may be eligible to be connected.
3874 while (!queue.empty()) {
3875 CBlockIndex *pindex = queue.front();
3877 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
3878 if (pindex->pprev) {
3879 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
3880 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
3882 pindex->nChainSproutValue = boost::none;
3885 pindex->nChainSproutValue = pindex->nSproutValue;
3888 LOCK(cs_nBlockSequenceId);
3889 pindex->nSequenceId = nBlockSequenceId++;
3891 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
3892 setBlockIndexCandidates.insert(pindex);
3894 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
3895 while (range.first != range.second) {
3896 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3897 queue.push_back(it->second);
3899 mapBlocksUnlinked.erase(it);
3903 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
3904 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
3911 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
3913 LOCK(cs_LastBlockFile);
3915 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
3916 if (vinfoBlockFile.size() <= nFile) {
3917 vinfoBlockFile.resize(nFile + 1);
3921 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
3923 if (vinfoBlockFile.size() <= nFile) {
3924 vinfoBlockFile.resize(nFile + 1);
3928 pos.nPos = vinfoBlockFile[nFile].nSize;
3931 if (nFile != nLastBlockFile) {
3933 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
3935 FlushBlockFile(!fKnown);
3936 nLastBlockFile = nFile;
3939 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
3941 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3943 vinfoBlockFile[nFile].nSize += nAddSize;
3946 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3947 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3948 if (nNewChunks > nOldChunks) {
3950 fCheckForPruning = true;
3951 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
3952 FILE *file = OpenBlockFile(pos);
3954 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
3955 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
3960 return state.Error("out of disk space");
3964 setDirtyFileInfo.insert(nFile);
3968 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
3972 LOCK(cs_LastBlockFile);
3974 unsigned int nNewSize;
3975 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
3976 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
3977 setDirtyFileInfo.insert(nFile);
3979 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3980 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3981 if (nNewChunks > nOldChunks) {
3983 fCheckForPruning = true;
3984 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
3985 FILE *file = OpenUndoFile(pos);
3987 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
3988 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
3993 return state.Error("out of disk space");
3999 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
4004 uint256 hash; int32_t i;
4005 hash = blockhdr.GetHash();
4006 for (i=31; i>=0; i--)
4007 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4008 fprintf(stderr," <- CheckBlockHeader\n");
4009 if ( chainActive.LastTip() != 0 )
4011 hash = chainActive.LastTip()->GetBlockHash();
4012 for (i=31; i>=0; i--)
4013 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4014 fprintf(stderr," <- chainTip\n");
4018 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
4020 CBlockIndex *tipindex;
4021 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
4022 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
4024 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
4025 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4027 //fprintf(stderr,"now its valid\n");
4031 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4033 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
4034 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4037 // Check block version
4038 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
4039 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
4041 // Check Equihash solution is valid
4044 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4045 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4047 // Check proof of work matches claimed amount
4048 /*komodo_index2pubkey33(pubkey33,pindex,height);
4049 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
4050 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
4054 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
4055 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
4057 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
4058 libzcash::ProofVerifier& verifier,
4059 bool fCheckPOW, bool fCheckMerkleRoot)
4061 uint8_t pubkey33[33]; uint256 hash;
4062 // These are checks that are independent of context.
4063 hash = block.GetHash();
4064 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
4065 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
4067 if ( *futureblockp == 0 )
4069 LogPrintf("CheckBlock header error");
4075 //if ( !CheckEquihashSolution(&block, Params()) )
4076 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4077 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
4078 if ( !CheckProofOfWork(height,pubkey33,hash,block.nBits,Params().GetConsensus(),block.nTime) )
4080 int32_t z; for (z=31; z>=0; z--)
4081 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
4082 fprintf(stderr," failed hash ht.%d\n",height);
4083 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
4085 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
4086 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4088 // Check the merkle root.
4089 if (fCheckMerkleRoot) {
4091 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4092 if (block.hashMerkleRoot != hashMerkleRoot2)
4093 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
4094 REJECT_INVALID, "bad-txnmrklroot", true);
4096 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4097 // of transactions in a block without affecting the merkle root of a block,
4098 // while still invalidating it.
4100 return state.DoS(100, error("CheckBlock: duplicate transaction"),
4101 REJECT_INVALID, "bad-txns-duplicate", true);
4104 // All potential-corruption validation must be done before we do any
4105 // transaction validation, as otherwise we may mark the header as invalid
4106 // because we receive the wrong transactions for it.
4109 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
4110 return state.DoS(100, error("CheckBlock: size limits failed"),
4111 REJECT_INVALID, "bad-blk-length");
4113 // First transaction must be coinbase, the rest must not be
4114 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
4115 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
4116 REJECT_INVALID, "bad-cb-missing");
4117 for (unsigned int i = 1; i < block.vtx.size(); i++)
4118 if (block.vtx[i].IsCoinBase())
4119 return state.DoS(100, error("CheckBlock: more than one coinbase"),
4120 REJECT_INVALID, "bad-cb-multiple");
4122 // Check transactions
4123 if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order
4125 CValidationState stateDummy;
4126 fprintf(stderr,"put block's tx into mempool\n");
4127 for (int i = 0; i < block.vtx.size(); i++)
4129 const CTransaction &tx = block.vtx[i];
4130 if (tx.IsCoinBase() != 0 )
4132 else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0 )
4134 AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL);
4136 fprintf(stderr,"done putting block's tx into mempool\n");
4138 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4140 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
4141 return error("CheckBlock: komodo_validate_interest failed");
4142 if (!CheckTransaction(tx, state, verifier))
4143 return error("CheckBlock: CheckTransaction failed");
4145 unsigned int nSigOps = 0;
4146 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4148 nSigOps += GetLegacySigOpCount(tx);
4150 if (nSigOps > MAX_BLOCK_SIGOPS)
4151 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
4152 REJECT_INVALID, "bad-blk-sigops", true);
4153 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
4155 //static uint32_t counter;
4156 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
4157 // fprintf(stderr,"check deposit rejection\n");
4158 LogPrintf("CheckBlockHeader komodo_check_deposit error");
4164 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4166 const CChainParams& chainParams = Params();
4167 const Consensus::Params& consensusParams = chainParams.GetConsensus();
4168 uint256 hash = block.GetHash();
4169 if (hash == consensusParams.hashGenesisBlock)
4174 int nHeight = pindexPrev->nHeight+1;
4176 // Check proof of work
4177 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
4179 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << endl;
4180 return state.DoS(100, error("%s: incorrect proof of work", __func__),
4181 REJECT_INVALID, "bad-diffbits");
4184 // Check timestamp against prev
4185 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
4186 return state.Invalid(error("%s: block's timestamp is too early", __func__),
4187 REJECT_INVALID, "time-too-old");
4189 if (fCheckpointsEnabled)
4191 // Check that the block chain matches the known block chain up to a checkpoint
4192 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
4194 /*CBlockIndex *heightblock = chainActive[nHeight];
4195 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4197 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4200 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
4202 // Don't accept any forks from the main chain prior to last checkpoint
4203 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
4204 int32_t notarized_height;
4205 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight > 1 )
4207 CBlockIndex *heightblock = chainActive[nHeight];
4208 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4210 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
4214 if ( pcheckpoint != 0 && nHeight < pcheckpoint->nHeight )
4215 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->nHeight));
4216 if ( komodo_checkpoint(¬arized_height,nHeight,hash) < 0 )
4218 CBlockIndex *heightblock = chainActive[nHeight];
4219 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4221 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4223 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4227 // Reject block.nVersion < 4 blocks
4228 if (block.nVersion < 4)
4229 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4230 REJECT_OBSOLETE, "bad-version");
4235 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4237 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
4238 const Consensus::Params& consensusParams = Params().GetConsensus();
4240 // Check that all transactions are finalized
4241 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
4243 // Check transaction contextually against consensus rules at block height
4244 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4245 return false; // Failure reason has been set in validation state object
4248 int nLockTimeFlags = 0;
4249 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4250 ? pindexPrev->GetMedianTimePast()
4251 : block.GetBlockTime();
4252 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4253 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4257 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4258 // In Zcash this has been enforced since launch, except that the genesis
4259 // block didn't include the height in the coinbase (see Zcash protocol spec
4260 // section '6.8 Bitcoin Improvement Proposals').
4263 CScript expect = CScript() << nHeight;
4264 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4265 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4266 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4273 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4275 static uint256 zero;
4276 const CChainParams& chainparams = Params();
4277 AssertLockHeld(cs_main);
4279 // Check for duplicate
4280 uint256 hash = block.GetHash();
4281 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4282 CBlockIndex *pindex = NULL;
4283 if (miSelf != mapBlockIndex.end())
4285 // Block header is already known.
4286 if ( (pindex= miSelf->second) == 0 )
4287 miSelf->second = pindex = AddToBlockIndex(block);
4290 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4291 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4292 /*if ( pindex != 0 && hash == komodo_requestedhash )
4294 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4295 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4296 komodo_requestedcount = 0;
4299 //if ( pindex == 0 )
4300 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4303 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
4305 if ( *futureblockp == 0 )
4307 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4311 // Get prev block index
4312 CBlockIndex* pindexPrev = NULL;
4313 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4315 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4316 if (mi == mapBlockIndex.end())
4318 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4320 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4322 pindexPrev = (*mi).second;
4323 if (pindexPrev == 0 )
4325 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4328 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4329 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4331 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4333 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4334 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4339 if ( (pindex= AddToBlockIndex(block)) != 0 )
4341 miSelf = mapBlockIndex.find(hash);
4342 if (miSelf != mapBlockIndex.end())
4343 miSelf->second = pindex;
4344 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4349 /*if ( pindex != 0 && hash == komodo_requestedhash )
4351 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4352 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4353 komodo_requestedcount = 0;
4358 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4360 const CChainParams& chainparams = Params();
4361 AssertLockHeld(cs_main);
4363 CBlockIndex *&pindex = *ppindex;
4364 if (!AcceptBlockHeader(futureblockp,block, state, &pindex))
4366 if ( *futureblockp == 0 )
4368 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4374 LogPrintf("AcceptBlock null pindex error\n");
4377 //fprintf(stderr,"acceptblockheader passed\n");
4378 // Try to process all requested blocks that we don't have, but only
4379 // process an unrequested block if it's new and has enough work to
4380 // advance our tip, and isn't too many blocks ahead.
4381 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4382 bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
4383 // Blocks that are too out-of-order needlessly limit the effectiveness of
4384 // pruning, because pruning will not delete block files that contain any
4385 // blocks which are too close in height to the tip. Apply this test
4386 // regardless of whether pruning is enabled; it should generally be safe to
4387 // not process unrequested blocks.
4388 bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4390 // TODO: deal better with return value and error conditions for duplicate
4391 // and unrequested blocks.
4392 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4393 if (fAlreadyHave) return true;
4394 if (!fRequested) { // If we didn't ask for it:
4395 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4396 if (!fHasMoreWork) return true; // Don't process less-work chains
4397 if (fTooFarAhead) return true; // Block height is too high
4400 // See method docstring for why this is always disabled
4401 auto verifier = libzcash::ProofVerifier::Disabled();
4402 if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4404 if ( *futureblockp == 0 )
4406 if (state.IsInvalid() && !state.CorruptionPossible()) {
4407 pindex->nStatus |= BLOCK_FAILED_VALID;
4408 setDirtyBlockIndex.insert(pindex);
4410 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4415 int nHeight = pindex->nHeight;
4416 // Write block to history file
4418 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4419 CDiskBlockPos blockPos;
4422 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4423 return error("AcceptBlock(): FindBlockPos failed");
4425 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4426 AbortNode(state, "Failed to write block");
4427 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4428 return error("AcceptBlock(): ReceivedBlockTransactions failed");
4429 } catch (const std::runtime_error& e) {
4430 return AbortNode(state, std::string("System error: ") + e.what());
4433 if (fCheckForPruning)
4434 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4435 if ( *futureblockp == 0 )
4437 LogPrintf("AcceptBlock block from future error\n");
4441 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4443 unsigned int nFound = 0;
4444 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4446 if (pstart->nVersion >= minVersion)
4448 pstart = pstart->pprev;
4450 return (nFound >= nRequired);
4453 void komodo_currentheight_set(int32_t height);
4455 CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4457 CBlockIndex *pindex = 0;
4458 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4459 if ( miSelf != mapBlockIndex.end() )
4461 if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4463 miSelf->second = AddToBlockIndex(*pblock);
4464 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4466 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4468 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4469 if ( miSelf != mapBlockIndex.end() )
4471 if ( miSelf->second == 0 )
4473 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4474 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4482 CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
4484 CBlockIndex *pindex=0,*previndex=0;
4485 if ( (pindex= mapBlockIndex[hash]) == 0 )
4487 pindex = new CBlockIndex();
4489 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4490 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4491 pindex->phashBlock = &((*mi).first);
4493 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4494 if ( miSelf == mapBlockIndex.end() )
4496 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4499 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4503 pindex = AddToBlockIndex(*pblock);
4504 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4508 miSelf->second = pindex;
4509 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4510 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4512 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4514 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4515 if ( miSelf == mapBlockIndex.end() )
4516 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4517 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4519 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4521 if ( previndex == 0 )
4522 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4523 if ( previndex != 0 )
4525 miSelf->second = previndex;
4526 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4527 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4529 } else LogPrintf("komodo_ensure unexpected null miprev\n");
4535 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
4537 // Preliminary checks
4538 bool checked; uint256 hash; int32_t futureblock=0;
4539 auto verifier = libzcash::ProofVerifier::Disabled();
4540 hash = pblock->GetHash();
4541 fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight);
4542 if ( chainActive.LastTip() != 0 )
4543 komodo_currentheight_set(chainActive.LastTip()->nHeight);
4544 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
4547 bool fRequested = MarkBlockAsReceived(hash);
4548 fRequested |= fForceProcessing;
4549 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
4552 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
4554 if (!checked && futureblock == 0)
4558 Misbehaving(pfrom->GetId(), 1);
4560 return error("%s: CheckBlock FAILED", __func__);
4563 CBlockIndex *pindex = NULL;
4566 // 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
4567 komodo_ensure(pblock,hash);
4569 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
4570 if (pindex && pfrom) {
4571 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
4574 if (!ret && futureblock == 0)
4575 return error("%s: AcceptBlock FAILED", __func__);
4576 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
4579 if (futureblock == 0 && !ActivateBestChain(state, pblock))
4580 return error("%s: ActivateBestChain failed", __func__);
4581 fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight);
4586 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4588 AssertLockHeld(cs_main);
4589 assert(pindexPrev == chainActive.Tip());
4591 CCoinsViewCache viewNew(pcoinsTip);
4592 CBlockIndex indexDummy(block);
4593 indexDummy.pprev = pindexPrev;
4594 indexDummy.nHeight = pindexPrev->nHeight + 1;
4595 // JoinSplit proofs are verified in ConnectBlock
4596 auto verifier = libzcash::ProofVerifier::Disabled();
4597 // NOTE: CheckBlockHeader is called by CheckBlock
4598 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4600 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
4603 int32_t futureblock;
4604 if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
4606 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
4609 if (!ContextualCheckBlock(block, state, pindexPrev))
4611 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
4614 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
4616 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
4619 assert(state.IsValid());
4620 if ( futureblock != 0 )
4626 * BLOCK PRUNING CODE
4629 /* Calculate the amount of disk space the block & undo files currently use */
4630 uint64_t CalculateCurrentUsage()
4632 uint64_t retval = 0;
4633 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
4634 retval += file.nSize + file.nUndoSize;
4639 /* Prune a block file (modify associated database entries)*/
4640 void PruneOneBlockFile(const int fileNumber)
4642 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
4643 CBlockIndex* pindex = it->second;
4644 if (pindex->nFile == fileNumber) {
4645 pindex->nStatus &= ~BLOCK_HAVE_DATA;
4646 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
4648 pindex->nDataPos = 0;
4649 pindex->nUndoPos = 0;
4650 setDirtyBlockIndex.insert(pindex);
4652 // Prune from mapBlocksUnlinked -- any block we prune would have
4653 // to be downloaded again in order to consider its chain, at which
4654 // point it would be considered as a candidate for
4655 // mapBlocksUnlinked or setBlockIndexCandidates.
4656 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
4657 while (range.first != range.second) {
4658 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
4660 if (it->second == pindex) {
4661 mapBlocksUnlinked.erase(it);
4667 vinfoBlockFile[fileNumber].SetNull();
4668 setDirtyFileInfo.insert(fileNumber);
4672 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
4674 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
4675 CDiskBlockPos pos(*it, 0);
4676 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
4677 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
4678 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
4682 /* Calculate the block/rev files that should be deleted to remain under target*/
4683 void FindFilesToPrune(std::set<int>& setFilesToPrune)
4685 LOCK2(cs_main, cs_LastBlockFile);
4686 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
4689 if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
4692 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
4693 uint64_t nCurrentUsage = CalculateCurrentUsage();
4694 // We don't check to prune until after we've allocated new space for files
4695 // So we should leave a buffer under our target to account for another allocation
4696 // before the next pruning.
4697 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
4698 uint64_t nBytesToPrune;
4701 if (nCurrentUsage + nBuffer >= nPruneTarget) {
4702 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4703 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
4705 if (vinfoBlockFile[fileNumber].nSize == 0)
4708 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
4711 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
4712 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
4715 PruneOneBlockFile(fileNumber);
4716 // Queue up the files for removal
4717 setFilesToPrune.insert(fileNumber);
4718 nCurrentUsage -= nBytesToPrune;
4723 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
4724 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
4725 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4726 nLastBlockWeCanPrune, count);
4729 bool CheckDiskSpace(uint64_t nAdditionalBytes)
4731 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
4733 // Check for nMinDiskSpace bytes (currently 50MB)
4734 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
4735 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
4740 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
4742 static int32_t didinit[64];
4745 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
4746 boost::filesystem::create_directories(path.parent_path());
4747 FILE* file = fopen(path.string().c_str(), "rb+");
4748 if (!file && !fReadOnly)
4749 file = fopen(path.string().c_str(), "wb+");
4751 LogPrintf("Unable to open file %s\n", path.string());
4754 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
4756 komodo_prefetch(file);
4757 didinit[pos.nFile] = 1;
4760 if (fseek(file, pos.nPos, SEEK_SET)) {
4761 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
4769 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
4770 return OpenDiskFile(pos, "blk", fReadOnly);
4773 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
4774 return OpenDiskFile(pos, "rev", fReadOnly);
4777 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
4779 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
4782 CBlockIndex * InsertBlockIndex(uint256 hash)
4788 BlockMap::iterator mi = mapBlockIndex.find(hash);
4789 if (mi != mapBlockIndex.end())
4790 return (*mi).second;
4793 CBlockIndex* pindexNew = new CBlockIndex();
4795 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
4796 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4797 pindexNew->phashBlock = &((*mi).first);
4798 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
4803 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
4805 bool static LoadBlockIndexDB()
4807 const CChainParams& chainparams = Params();
4808 LogPrintf("%s: start loading guts\n", __func__);
4809 if (!pblocktree->LoadBlockIndexGuts())
4811 LogPrintf("%s: loaded guts\n", __func__);
4812 boost::this_thread::interruption_point();
4814 // Calculate nChainWork
4815 vector<pair<int, CBlockIndex*> > vSortedByHeight;
4816 vSortedByHeight.reserve(mapBlockIndex.size());
4817 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4819 CBlockIndex* pindex = item.second;
4820 vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
4821 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4823 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
4824 sort(vSortedByHeight.begin(), vSortedByHeight.end());
4825 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
4826 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
4828 CBlockIndex* pindex = item.second;
4829 pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
4830 // We can link the chain of blocks for which we've received transactions at some point.
4831 // Pruned nodes may have deleted the block.
4832 if (pindex->nTx > 0) {
4833 if (pindex->pprev) {
4834 if (pindex->pprev->nChainTx) {
4835 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
4836 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4837 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4839 pindex->nChainSproutValue = boost::none;
4842 pindex->nChainTx = 0;
4843 pindex->nChainSproutValue = boost::none;
4844 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
4847 pindex->nChainTx = pindex->nTx;
4848 pindex->nChainSproutValue = pindex->nSproutValue;
4851 // Construct in-memory chain of branch IDs.
4852 // Relies on invariant: a block that does not activate a network upgrade
4853 // will always be valid under the same consensus rules as its parent.
4854 // Genesis block has a branch ID of zero by definition, but has no
4855 // validity status because it is side-loaded into a fresh chain.
4856 // Activation blocks will have branch IDs set (read from disk).
4857 if (pindex->pprev) {
4858 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
4859 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
4862 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
4864 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
4865 setBlockIndexCandidates.insert(pindex);
4866 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
4867 pindexBestInvalid = pindex;
4869 pindex->BuildSkip();
4870 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
4871 pindexBestHeader = pindex;
4872 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4874 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
4876 // Load block file info
4877 pblocktree->ReadLastBlockFile(nLastBlockFile);
4878 vinfoBlockFile.resize(nLastBlockFile + 1);
4879 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
4880 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4881 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4883 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
4884 for (int nFile = nLastBlockFile + 1; true; nFile++) {
4885 CBlockFileInfo info;
4886 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
4887 vinfoBlockFile.push_back(info);
4893 // Check presence of blk files
4894 LogPrintf("Checking all blk files are present...\n");
4895 set<int> setBlkDataFiles;
4896 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4898 CBlockIndex* pindex = item.second;
4899 if (pindex->nStatus & BLOCK_HAVE_DATA) {
4900 setBlkDataFiles.insert(pindex->nFile);
4902 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4904 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
4905 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
4907 CDiskBlockPos pos(*it, 0);
4908 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
4913 // Check whether we have ever pruned block & undo files
4914 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
4916 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
4918 // Check whether we need to continue reindexing
4919 bool fReindexing = false;
4920 pblocktree->ReadReindexing(fReindexing);
4921 fReindex |= fReindexing;
4923 // Check whether we have a transaction index
4924 pblocktree->ReadFlag("txindex", fTxIndex);
4925 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
4926 // Check whether we have an address index
4927 pblocktree->ReadFlag("addressindex", fAddressIndex);
4928 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
4930 // Check whether we have a timestamp index
4931 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
4932 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
4934 // Check whether we have a spent index
4935 pblocktree->ReadFlag("spentindex", fSpentIndex);
4936 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
4938 // Fill in-memory data
4939 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4941 CBlockIndex* pindex = item.second;
4942 // - This relationship will always be true even if pprev has multiple
4943 // children, because hashAnchor is technically a property of pprev,
4944 // not its children.
4945 // - This will miss chain tips; we handle the best tip below, and other
4946 // tips will be handled by ConnectTip during a re-org.
4947 if (pindex->pprev) {
4948 pindex->pprev->hashAnchorEnd = pindex->hashAnchor;
4950 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
4953 // Load pointer to end of best chain
4954 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
4955 if (it == mapBlockIndex.end())
4957 chainActive.SetTip(it->second);
4958 // Set hashAnchorEnd for the end of best chain
4959 it->second->hashAnchorEnd = pcoinsTip->GetBestAnchor();
4961 PruneBlockIndexCandidates();
4964 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
4965 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
4967 int32_t longestchain = komodo_longestchain();
4968 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
4969 // runs, which makes it return 0, so we guess 50% for now
4970 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
4973 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
4974 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
4975 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
4978 EnforceNodeDeprecation(chainActive.Height(), true);
4983 CVerifyDB::CVerifyDB()
4985 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
4988 CVerifyDB::~CVerifyDB()
4990 uiInterface.ShowProgress("", 100);
4993 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
4996 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
4999 // Verify blocks in the best chain
5000 if (nCheckDepth <= 0)
5001 nCheckDepth = 1000000000; // suffices until the year 19000
5002 if (nCheckDepth > chainActive.Height())
5003 nCheckDepth = chainActive.Height();
5004 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
5005 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
5006 CCoinsViewCache coins(coinsview);
5007 CBlockIndex* pindexState = chainActive.Tip();
5008 CBlockIndex* pindexFailure = NULL;
5009 int nGoodTransactions = 0;
5010 CValidationState state;
5011 // No need to verify JoinSplits twice
5012 auto verifier = libzcash::ProofVerifier::Disabled();
5013 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
5014 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
5016 boost::this_thread::interruption_point();
5017 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
5018 if (pindex->nHeight < chainActive.Height()-nCheckDepth)
5021 // check level 0: read from disk
5022 if (!ReadBlockFromDisk(block, pindex,0))
5023 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5024 // check level 1: verify block validity
5025 int32_t futureblock;
5026 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0) )
5027 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
5028 // check level 2: verify undo validity
5029 if (nCheckLevel >= 2 && pindex) {
5031 CDiskBlockPos pos = pindex->GetUndoPos();
5032 if (!pos.IsNull()) {
5033 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5034 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
5037 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
5038 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
5040 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5041 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5042 pindexState = pindex->pprev;
5044 nGoodTransactions = 0;
5045 pindexFailure = pindex;
5047 nGoodTransactions += block.vtx.size();
5049 if (ShutdownRequested())
5052 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
5054 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
5056 // check level 4: try reconnecting blocks
5057 if (nCheckLevel >= 4) {
5058 CBlockIndex *pindex = pindexState;
5059 while (pindex != chainActive.Tip()) {
5060 boost::this_thread::interruption_point();
5061 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
5062 pindex = chainActive.Next(pindex);
5064 if (!ReadBlockFromDisk(block, pindex,0))
5065 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5066 if (!ConnectBlock(block, state, pindex, coins,false, true))
5067 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5071 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
5076 bool RewindBlockIndex(const CChainParams& params)
5080 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
5081 // index will have nCachedBranchId set based on the values previously persisted
5082 // to disk. By definition, a set nCachedBranchId means that the block was
5083 // fully-validated under the corresponding consensus rules. Thus we can quickly
5084 // identify whether the current active chain matches our expected sequence of
5085 // consensus rule changes, with two checks:
5087 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
5088 // - nCachedBranchId for each block matches what we expect.
5089 auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) {
5090 auto consensus = params.GetConsensus();
5091 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5092 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus);
5093 return fFlagSet == fFlagExpected &&
5094 pindex->nCachedBranchId &&
5095 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->nHeight, consensus);
5099 while (nHeight <= chainActive.Height()) {
5100 if (!sufficientlyValidated(chainActive[nHeight])) {
5106 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
5107 auto rewindLength = chainActive.Height() - nHeight;
5108 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH) {
5109 auto pindexOldTip = chainActive.Tip();
5110 auto pindexRewind = chainActive[nHeight - 1];
5111 auto msg = strprintf(_(
5112 "A block chain rewind has been detected that would roll back %d blocks! "
5113 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5114 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5115 _("Rewind details") + ":\n" +
5116 "- " + strprintf(_("Current tip: %s, height %d"),
5117 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
5118 "- " + strprintf(_("Rewinding to: %s, height %d"),
5119 pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
5120 _("Please help, human!");
5121 LogPrintf("*** %s\n", msg);
5122 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5127 CValidationState state;
5128 CBlockIndex* pindex = chainActive.Tip();
5129 while (chainActive.Height() >= nHeight) {
5130 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5131 // If pruning, don't try rewinding past the HAVE_DATA point;
5132 // since older blocks can't be served anyway, there's
5133 // no need to walk further, and trying to DisconnectTip()
5134 // will fail (and require a needless reindex/redownload
5135 // of the blockchain).
5138 if (!DisconnectTip(state, true)) {
5139 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
5141 // Occasionally flush state to disk.
5142 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5146 // Reduce validity flag and have-data flags.
5147 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5148 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5149 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5150 CBlockIndex* pindexIter = it->second;
5152 // Note: If we encounter an insufficiently validated block that
5153 // is on chainActive, it must be because we are a pruning node, and
5154 // this block or some successor doesn't HAVE_DATA, so we were unable to
5155 // rewind all the way. Blocks remaining on chainActive at this point
5156 // must not have their validity reduced.
5157 if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
5159 pindexIter->nStatus =
5160 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5161 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
5162 // Remove have-data flags
5163 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
5165 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
5166 pindexIter->nCachedBranchId = boost::none;
5167 // Remove storage location
5168 pindexIter->nFile = 0;
5169 pindexIter->nDataPos = 0;
5170 pindexIter->nUndoPos = 0;
5171 // Remove various other things
5172 pindexIter->nTx = 0;
5173 pindexIter->nChainTx = 0;
5174 pindexIter->nSproutValue = boost::none;
5175 pindexIter->nChainSproutValue = boost::none;
5176 pindexIter->nSequenceId = 0;
5177 // Make sure it gets written
5178 setDirtyBlockIndex.insert(pindexIter);
5179 if (pindexIter == pindexBestInvalid)
5181 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
5182 pindexBestInvalid = NULL;
5186 setBlockIndexCandidates.erase(pindexIter);
5187 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
5188 while (ret.first != ret.second) {
5189 if (ret.first->second == pindexIter) {
5190 mapBlocksUnlinked.erase(ret.first++);
5195 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5196 setBlockIndexCandidates.insert(pindexIter);
5200 PruneBlockIndexCandidates();
5204 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5211 void UnloadBlockIndex()
5214 setBlockIndexCandidates.clear();
5215 chainActive.SetTip(NULL);
5216 pindexBestInvalid = NULL;
5217 pindexBestHeader = NULL;
5219 mapOrphanTransactions.clear();
5220 mapOrphanTransactionsByPrev.clear();
5222 mapBlocksUnlinked.clear();
5223 vinfoBlockFile.clear();
5225 nBlockSequenceId = 1;
5226 mapBlockSource.clear();
5227 mapBlocksInFlight.clear();
5228 nQueuedValidatedHeaders = 0;
5229 nPreferredDownload = 0;
5230 setDirtyBlockIndex.clear();
5231 setDirtyFileInfo.clear();
5232 mapNodeState.clear();
5233 recentRejects.reset(NULL);
5235 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5236 delete entry.second;
5238 mapBlockIndex.clear();
5239 fHavePruned = false;
5242 bool LoadBlockIndex()
5244 // Load block index from databases
5245 KOMODO_LOADINGBLOCKS = 1;
5246 if (!fReindex && !LoadBlockIndexDB())
5248 KOMODO_LOADINGBLOCKS = 0;
5251 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5256 bool InitBlockIndex() {
5257 const CChainParams& chainparams = Params();
5260 // Initialize global variables that cannot be constructed at startup.
5261 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5263 // Check whether we're already initialized
5264 if (chainActive.Genesis() != NULL)
5267 // Use the provided setting for -txindex in the new database
5268 fTxIndex = GetBoolArg("-txindex", true);
5269 pblocktree->WriteFlag("txindex", fTxIndex);
5270 // Use the provided setting for -addressindex in the new database
5271 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5272 pblocktree->WriteFlag("addressindex", fAddressIndex);
5274 // Use the provided setting for -timestampindex in the new database
5275 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5276 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5278 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5279 pblocktree->WriteFlag("spentindex", fSpentIndex);
5280 LogPrintf("Initializing databases...\n");
5282 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5285 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5286 // Start new block file
5287 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5288 CDiskBlockPos blockPos;
5289 CValidationState state;
5290 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5291 return error("LoadBlockIndex(): FindBlockPos failed");
5292 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5293 return error("LoadBlockIndex(): writing genesis block to disk failed");
5294 CBlockIndex *pindex = AddToBlockIndex(block);
5296 return error("LoadBlockIndex(): couldnt add to block index");
5297 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5298 return error("LoadBlockIndex(): genesis block not accepted");
5299 if (!ActivateBestChain(state, &block))
5300 return error("LoadBlockIndex(): genesis block cannot be activated");
5301 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5302 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5303 } catch (const std::runtime_error& e) {
5304 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5313 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5315 const CChainParams& chainparams = Params();
5316 // Map of disk positions for blocks with unknown parent (only used for reindex)
5317 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5318 int64_t nStart = GetTimeMillis();
5322 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5323 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5324 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5325 uint64_t nRewind = blkdat.GetPos();
5326 while (!blkdat.eof()) {
5327 boost::this_thread::interruption_point();
5329 blkdat.SetPos(nRewind);
5330 nRewind++; // start one byte further next time, in case of failure
5331 blkdat.SetLimit(); // remove former limit
5332 unsigned int nSize = 0;
5335 unsigned char buf[MESSAGE_START_SIZE];
5336 blkdat.FindByte(Params().MessageStart()[0]);
5337 nRewind = blkdat.GetPos()+1;
5338 blkdat >> FLATDATA(buf);
5339 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5343 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5345 } catch (const std::exception&) {
5346 // no valid block header found; don't complain
5351 uint64_t nBlockPos = blkdat.GetPos();
5353 dbp->nPos = nBlockPos;
5354 blkdat.SetLimit(nBlockPos + nSize);
5355 blkdat.SetPos(nBlockPos);
5358 nRewind = blkdat.GetPos();
5360 // detect out of order blocks, and store them for later
5361 uint256 hash = block.GetHash();
5362 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5363 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5364 block.hashPrevBlock.ToString());
5366 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5370 // process in case the block isn't known yet
5371 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5372 CValidationState state;
5373 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5375 if (state.IsError())
5377 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
5378 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
5381 // Recursively process earlier encountered successors of this block
5382 deque<uint256> queue;
5383 queue.push_back(hash);
5384 while (!queue.empty()) {
5385 uint256 head = queue.front();
5387 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5388 while (range.first != range.second) {
5389 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5390 if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1))
5392 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5394 CValidationState dummy;
5395 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5398 queue.push_back(block.GetHash());
5402 mapBlocksUnknownParent.erase(it);
5405 } catch (const std::exception& e) {
5406 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5409 } catch (const std::runtime_error& e) {
5410 AbortNode(std::string("System error: ") + e.what());
5413 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5417 void static CheckBlockIndex()
5419 const Consensus::Params& consensusParams = Params().GetConsensus();
5420 if (!fCheckBlockIndex) {
5426 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5427 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5428 // iterating the block tree require that chainActive has been initialized.)
5429 if (chainActive.Height() < 0) {
5430 assert(mapBlockIndex.size() <= 1);
5434 // Build forward-pointing map of the entire block tree.
5435 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5436 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5437 if ( it->second != 0 )
5438 forward.insert(std::make_pair(it->second->pprev, it->second));
5440 if ( Params().NetworkIDString() != "regtest" )
5441 assert(forward.size() == mapBlockIndex.size());
5443 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5444 CBlockIndex *pindex = rangeGenesis.first->second;
5445 rangeGenesis.first++;
5446 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5448 // Iterate over the entire block tree, using depth-first search.
5449 // Along the way, remember whether there are blocks on the path from genesis
5450 // block being explored which are the first to have certain properties.
5453 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5454 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5455 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5456 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5457 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5458 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5459 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5460 while (pindex != NULL) {
5462 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5463 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5464 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5465 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5466 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5467 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5468 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5470 // Begin: actual consistency checks.
5471 if (pindex->pprev == NULL) {
5472 // Genesis block checks.
5473 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5474 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5476 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
5477 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5478 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5480 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5481 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5482 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5484 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5485 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5487 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5488 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5489 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5490 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5491 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5492 assert(pindex->nHeight == nHeight); // nHeight must be consistent.
5493 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.
5494 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5495 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5496 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5497 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5498 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5499 if (pindexFirstInvalid == NULL) {
5500 // Checks for not-invalid blocks.
5501 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5503 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5504 if (pindexFirstInvalid == NULL) {
5505 // If this block sorts at least as good as the current tip and
5506 // is valid and we have all data for its parents, it must be in
5507 // setBlockIndexCandidates. chainActive.Tip() must also be there
5508 // even if some data has been pruned.
5509 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5510 assert(setBlockIndexCandidates.count(pindex));
5512 // If some parent is missing, then it could be that this block was in
5513 // setBlockIndexCandidates but had to be removed because of the missing data.
5514 // In this case it must be in mapBlocksUnlinked -- see test below.
5516 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
5517 assert(setBlockIndexCandidates.count(pindex) == 0);
5519 // Check whether this block is in mapBlocksUnlinked.
5520 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5521 bool foundInUnlinked = false;
5522 while (rangeUnlinked.first != rangeUnlinked.second) {
5523 assert(rangeUnlinked.first->first == pindex->pprev);
5524 if (rangeUnlinked.first->second == pindex) {
5525 foundInUnlinked = true;
5528 rangeUnlinked.first++;
5530 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5531 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5532 assert(foundInUnlinked);
5534 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5535 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5536 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5537 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5538 assert(fHavePruned); // We must have pruned.
5539 // This block may have entered mapBlocksUnlinked if:
5540 // - it has a descendant that at some point had more work than the
5542 // - we tried switching to that descendant but were missing
5543 // data for some intermediate block between chainActive and the
5545 // So if this block is itself better than chainActive.Tip() and it wasn't in
5546 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5547 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5548 if (pindexFirstInvalid == NULL) {
5549 assert(foundInUnlinked);
5553 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5554 // End: actual consistency checks.
5556 // Try descending into the first subnode.
5557 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5558 if (range.first != range.second) {
5559 // A subnode was found.
5560 pindex = range.first->second;
5564 // This is a leaf node.
5565 // Move upwards until we reach a node of which we have not yet visited the last child.
5567 // We are going to either move to a parent or a sibling of pindex.
5568 // If pindex was the first with a certain property, unset the corresponding variable.
5569 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
5570 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
5571 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
5572 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
5573 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
5574 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
5575 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
5577 CBlockIndex* pindexPar = pindex->pprev;
5578 // Find which child we just visited.
5579 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
5580 while (rangePar.first->second != pindex) {
5581 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
5584 // Proceed to the next one.
5586 if (rangePar.first != rangePar.second) {
5587 // Move to the sibling.
5588 pindex = rangePar.first->second;
5599 // Check that we actually traversed the entire map.
5600 assert(nNodes == forward.size());
5603 //////////////////////////////////////////////////////////////////////////////
5608 std::string GetWarnings(const std::string& strFor)
5611 string strStatusBar;
5614 if (!CLIENT_VERSION_IS_RELEASE)
5615 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
5617 if (GetBoolArg("-testsafemode", false))
5618 strStatusBar = strRPC = "testsafemode enabled";
5620 // Misc warnings like out of disk space and clock is wrong
5621 if (strMiscWarning != "")
5624 strStatusBar = strMiscWarning;
5627 if (fLargeWorkForkFound)
5630 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
5632 else if (fLargeWorkInvalidChainFound)
5635 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.");
5641 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
5643 const CAlert& alert = item.second;
5644 if (alert.AppliesToMe() && alert.nPriority > nPriority)
5646 nPriority = alert.nPriority;
5647 strStatusBar = alert.strStatusBar;
5648 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
5649 strRPC = alert.strRPCError;
5655 if (strFor == "statusbar")
5656 return strStatusBar;
5657 else if (strFor == "rpc")
5659 assert(!"GetWarnings(): invalid parameter");
5670 //////////////////////////////////////////////////////////////////////////////
5676 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
5682 assert(recentRejects);
5683 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
5685 // If the chain tip has changed previously rejected transactions
5686 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
5687 // or a double-spend. Reset the rejects filter and give those
5688 // txs a second chance.
5689 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
5690 recentRejects->reset();
5693 return recentRejects->contains(inv.hash) ||
5694 mempool.exists(inv.hash) ||
5695 mapOrphanTransactions.count(inv.hash) ||
5696 pcoinsTip->HaveCoins(inv.hash);
5699 return mapBlockIndex.count(inv.hash);
5701 // Don't know what it is, just say we already got one
5705 void static ProcessGetData(CNode* pfrom)
5707 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
5709 vector<CInv> vNotFound;
5713 while (it != pfrom->vRecvGetData.end()) {
5714 // Don't bother if send buffer is too full to respond anyway
5715 if (pfrom->nSendSize >= SendBufferSize())
5718 const CInv &inv = *it;
5720 boost::this_thread::interruption_point();
5723 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5726 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
5727 if (mi != mapBlockIndex.end())
5729 if (chainActive.Contains(mi->second)) {
5732 static const int nOneMonth = 30 * 24 * 60 * 60;
5733 // To prevent fingerprinting attacks, only send blocks outside of the active
5734 // chain if they are valid, and no more than a month older (both in time, and in
5735 // best equivalent proof of work) than the best header chain we know about.
5736 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
5737 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
5738 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
5740 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
5744 // Pruned nodes may have deleted the block, so check whether
5745 // it's available before trying to send.
5746 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
5748 // Send block from disk
5750 if (!ReadBlockFromDisk(block, (*mi).second,1))
5752 assert(!"cannot load block from disk");
5756 if (inv.type == MSG_BLOCK)
5758 //uint256 hash; int32_t z;
5759 //hash = block.GetHash();
5760 //for (z=31; z>=0; z--)
5761 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
5762 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
5763 pfrom->PushMessage("block", block);
5765 else // MSG_FILTERED_BLOCK)
5767 LOCK(pfrom->cs_filter);
5770 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
5771 pfrom->PushMessage("merkleblock", merkleBlock);
5772 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
5773 // This avoids hurting performance by pointlessly requiring a round-trip
5774 // Note that there is currently no way for a node to request any single transactions we didn't send here -
5775 // they must either disconnect and retry or request the full block.
5776 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
5777 // however we MUST always provide at least what the remote peer needs
5778 typedef std::pair<unsigned int, uint256> PairType;
5779 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
5780 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
5781 pfrom->PushMessage("tx", block.vtx[pair.first]);
5787 // Trigger the peer node to send a getblocks request for the next batch of inventory
5788 if (inv.hash == pfrom->hashContinue)
5790 // Bypass PushInventory, this must send even if redundant,
5791 // and we want it right after the last block so they don't
5792 // wait for other stuff first.
5794 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
5795 pfrom->PushMessage("inv", vInv);
5796 pfrom->hashContinue.SetNull();
5800 else if (inv.IsKnownType())
5802 // Send stream from relay memory
5803 bool pushed = false;
5806 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
5807 if (mi != mapRelay.end()) {
5808 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
5812 if (!pushed && inv.type == MSG_TX) {
5814 if (mempool.lookup(inv.hash, tx)) {
5815 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
5818 pfrom->PushMessage("tx", ss);
5823 vNotFound.push_back(inv);
5827 // Track requests for our stuff.
5828 GetMainSignals().Inventory(inv.hash);
5830 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5835 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
5837 if (!vNotFound.empty()) {
5838 // Let the peer know that we didn't find what it asked for, so it doesn't
5839 // have to wait around forever. Currently only SPV clients actually care
5840 // about this message: it's needed when they are recursively walking the
5841 // dependencies of relevant unconfirmed transactions. SPV clients want to
5842 // do that because they want to know about (and store and rebroadcast and
5843 // risk analyze) the dependencies of transactions relevant to them, without
5844 // having to download the entire memory pool.
5845 pfrom->PushMessage("notfound", vNotFound);
5849 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
5851 const CChainParams& chainparams = Params();
5852 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
5853 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
5854 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
5856 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
5863 if (strCommand == "version")
5865 // Each connection can only send one version message
5866 if (pfrom->nVersion != 0)
5868 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
5869 Misbehaving(pfrom->GetId(), 1);
5876 uint64_t nNonce = 1;
5877 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
5878 if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
5880 // disconnect from peers older than this proto version
5881 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5882 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5883 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
5884 pfrom->fDisconnect = true;
5888 // When Overwinter is active, reject incoming connections from non-Overwinter nodes
5889 const Consensus::Params& params = Params().GetConsensus();
5890 if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER)
5891 && pfrom->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)
5893 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5894 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5895 strprintf("Version must be %d or greater",
5896 params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
5897 pfrom->fDisconnect = true;
5901 if (pfrom->nVersion == 10300)
5902 pfrom->nVersion = 300;
5904 vRecv >> addrFrom >> nNonce;
5905 if (!vRecv.empty()) {
5906 vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
5907 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
5910 vRecv >> pfrom->nStartingHeight;
5912 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
5914 pfrom->fRelayTxes = true;
5916 // Disconnect if we connected to ourself
5917 if (nNonce == nLocalHostNonce && nNonce > 1)
5919 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
5920 pfrom->fDisconnect = true;
5924 pfrom->addrLocal = addrMe;
5925 if (pfrom->fInbound && addrMe.IsRoutable())
5930 // Be shy and don't send version until we hear
5931 if (pfrom->fInbound)
5932 pfrom->PushVersion();
5934 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
5936 // Potentially mark this peer as a preferred download peer.
5937 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
5940 pfrom->PushMessage("verack");
5941 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
5943 if (!pfrom->fInbound)
5945 // Advertise our address
5946 if (fListen && !IsInitialBlockDownload())
5948 CAddress addr = GetLocalAddress(&pfrom->addr);
5949 if (addr.IsRoutable())
5951 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
5952 pfrom->PushAddress(addr);
5953 } else if (IsPeerAddrLocalGood(pfrom)) {
5954 addr.SetIP(pfrom->addrLocal);
5955 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
5956 pfrom->PushAddress(addr);
5960 // Get recent addresses
5961 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
5963 pfrom->PushMessage("getaddr");
5964 pfrom->fGetAddr = true;
5966 addrman.Good(pfrom->addr);
5968 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
5970 addrman.Add(addrFrom, addrFrom);
5971 addrman.Good(addrFrom);
5978 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
5979 item.second.RelayTo(pfrom);
5982 pfrom->fSuccessfullyConnected = true;
5986 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
5988 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
5989 pfrom->cleanSubVer, pfrom->nVersion,
5990 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
5993 int64_t nTimeOffset = nTime - GetTime();
5994 pfrom->nTimeOffset = nTimeOffset;
5995 AddTimeData(pfrom->addr, nTimeOffset);
5999 else if (pfrom->nVersion == 0)
6001 // Must have a version message before anything else
6002 Misbehaving(pfrom->GetId(), 1);
6007 else if (strCommand == "verack")
6009 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6011 // Mark this node as currently connected, so we update its timestamp later.
6012 if (pfrom->fNetworkNode) {
6014 State(pfrom->GetId())->fCurrentlyConnected = true;
6019 // Disconnect existing peer connection when:
6020 // 1. The version message has been received
6021 // 2. Overwinter is active
6022 // 3. Peer version is pre-Overwinter
6023 else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
6024 && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
6026 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6027 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6028 strprintf("Version must be %d or greater",
6029 chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
6030 pfrom->fDisconnect = true;
6035 else if (strCommand == "addr")
6037 vector<CAddress> vAddr;
6040 // Don't want addr from older versions unless seeding
6041 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
6043 if (vAddr.size() > 1000)
6045 Misbehaving(pfrom->GetId(), 20);
6046 return error("message addr size() = %u", vAddr.size());
6049 // Store the new addresses
6050 vector<CAddress> vAddrOk;
6051 int64_t nNow = GetAdjustedTime();
6052 int64_t nSince = nNow - 10 * 60;
6053 BOOST_FOREACH(CAddress& addr, vAddr)
6055 boost::this_thread::interruption_point();
6057 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6058 addr.nTime = nNow - 5 * 24 * 60 * 60;
6059 pfrom->AddAddressKnown(addr);
6060 bool fReachable = IsReachable(addr);
6061 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
6063 // Relay to a limited number of other nodes
6066 // Use deterministic randomness to send to the same nodes for 24 hours
6067 // at a time so the addrKnowns of the chosen nodes prevent repeats
6068 static uint256 hashSalt;
6069 if (hashSalt.IsNull())
6070 hashSalt = GetRandHash();
6071 uint64_t hashAddr = addr.GetHash();
6072 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
6073 hashRand = Hash(BEGIN(hashRand), END(hashRand));
6074 multimap<uint256, CNode*> mapMix;
6075 BOOST_FOREACH(CNode* pnode, vNodes)
6077 if (pnode->nVersion < CADDR_TIME_VERSION)
6079 unsigned int nPointer;
6080 memcpy(&nPointer, &pnode, sizeof(nPointer));
6081 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
6082 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6083 mapMix.insert(make_pair(hashKey, pnode));
6085 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
6086 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6087 ((*mi).second)->PushAddress(addr);
6090 // Do not store addresses outside our network
6092 vAddrOk.push_back(addr);
6094 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
6095 if (vAddr.size() < 1000)
6096 pfrom->fGetAddr = false;
6097 if (pfrom->fOneShot)
6098 pfrom->fDisconnect = true;
6102 else if (strCommand == "inv")
6106 if (vInv.size() > MAX_INV_SZ)
6108 Misbehaving(pfrom->GetId(), 20);
6109 return error("message inv size() = %u", vInv.size());
6114 std::vector<CInv> vToFetch;
6116 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
6118 const CInv &inv = vInv[nInv];
6120 boost::this_thread::interruption_point();
6121 pfrom->AddInventoryKnown(inv);
6123 bool fAlreadyHave = AlreadyHave(inv);
6124 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
6126 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6129 if (inv.type == MSG_BLOCK) {
6130 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
6131 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
6132 // First request the headers preceding the announced block. In the normal fully-synced
6133 // case where a new block is announced that succeeds the current tip (no reorganization),
6134 // there are no such headers.
6135 // Secondly, and only when we are close to being synced, we request the announced block directly,
6136 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6137 // time the block arrives, the header chain leading up to it is already validated. Not
6138 // doing this will result in the received block being rejected as an orphan in case it is
6139 // not a direct successor.
6140 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
6141 CNodeState *nodestate = State(pfrom->GetId());
6142 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
6143 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6144 vToFetch.push_back(inv);
6145 // Mark block as in flight already, even though the actual "getdata" message only goes out
6146 // later (within the same cs_main lock, though).
6147 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
6149 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
6153 // Track requests for our stuff
6154 GetMainSignals().Inventory(inv.hash);
6156 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6157 Misbehaving(pfrom->GetId(), 50);
6158 return error("send buffer size() = %u", pfrom->nSendSize);
6162 if (!vToFetch.empty())
6163 pfrom->PushMessage("getdata", vToFetch);
6167 else if (strCommand == "getdata")
6171 if (vInv.size() > MAX_INV_SZ)
6173 Misbehaving(pfrom->GetId(), 20);
6174 return error("message getdata size() = %u", vInv.size());
6177 if (fDebug || (vInv.size() != 1))
6178 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
6180 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
6181 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
6183 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6184 ProcessGetData(pfrom);
6188 else if (strCommand == "getblocks")
6190 CBlockLocator locator;
6192 vRecv >> locator >> hashStop;
6196 // Find the last block the caller has in the main chain
6197 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
6199 // Send the rest of the chain
6201 pindex = chainActive.Next(pindex);
6203 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
6204 for (; pindex; pindex = chainActive.Next(pindex))
6206 if (pindex->GetBlockHash() == hashStop)
6208 LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
6211 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6214 // When this block is requested, we'll send an inv that'll
6215 // trigger the peer to getblocks the next batch of inventory.
6216 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
6217 pfrom->hashContinue = pindex->GetBlockHash();
6224 else if (strCommand == "getheaders")
6226 CBlockLocator locator;
6228 vRecv >> locator >> hashStop;
6232 if (IsInitialBlockDownload())
6235 CBlockIndex* pindex = NULL;
6236 if (locator.IsNull())
6238 // If locator is null, return the hashStop block
6239 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6240 if (mi == mapBlockIndex.end())
6242 pindex = (*mi).second;
6246 // Find the last block the caller has in the main chain
6247 pindex = FindForkInGlobalIndex(chainActive, locator);
6249 pindex = chainActive.Next(pindex);
6252 // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
6253 vector<CBlock> vHeaders;
6254 int nLimit = MAX_HEADERS_RESULTS;
6255 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
6256 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) )// no need to ever suppress this
6258 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->nHeight : -1);
6259 for (; pindex; pindex = chainActive.Next(pindex))
6261 vHeaders.push_back(pindex->GetBlockHeader());
6262 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6265 pfrom->PushMessage("headers", vHeaders);
6267 /*else if ( IS_KOMODO_NOTARY != 0 )
6269 static uint32_t counter;
6270 if ( counter++ < 3 )
6271 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);
6276 else if (strCommand == "tx")
6278 vector<uint256> vWorkQueue;
6279 vector<uint256> vEraseQueue;
6283 CInv inv(MSG_TX, tx.GetHash());
6284 pfrom->AddInventoryKnown(inv);
6288 bool fMissingInputs = false;
6289 CValidationState state;
6291 pfrom->setAskFor.erase(inv.hash);
6292 mapAlreadyAskedFor.erase(inv);
6294 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6296 mempool.check(pcoinsTip);
6297 RelayTransaction(tx);
6298 vWorkQueue.push_back(inv.hash);
6300 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6301 pfrom->id, pfrom->cleanSubVer,
6302 tx.GetHash().ToString(),
6303 mempool.mapTx.size());
6305 // Recursively process any orphan transactions that depended on this one
6306 set<NodeId> setMisbehaving;
6307 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6309 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6310 if (itByPrev == mapOrphanTransactionsByPrev.end())
6312 for (set<uint256>::iterator mi = itByPrev->second.begin();
6313 mi != itByPrev->second.end();
6316 const uint256& orphanHash = *mi;
6317 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6318 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6319 bool fMissingInputs2 = false;
6320 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6321 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6322 // anyone relaying LegitTxX banned)
6323 CValidationState stateDummy;
6326 if (setMisbehaving.count(fromPeer))
6328 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6330 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
6331 RelayTransaction(orphanTx);
6332 vWorkQueue.push_back(orphanHash);
6333 vEraseQueue.push_back(orphanHash);
6335 else if (!fMissingInputs2)
6338 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6340 // Punish peer that gave us an invalid orphan tx
6341 Misbehaving(fromPeer, nDos);
6342 setMisbehaving.insert(fromPeer);
6343 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6345 // Has inputs but not accepted to mempool
6346 // Probably non-standard or insufficient fee/priority
6347 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
6348 vEraseQueue.push_back(orphanHash);
6349 assert(recentRejects);
6350 recentRejects->insert(orphanHash);
6352 mempool.check(pcoinsTip);
6356 BOOST_FOREACH(uint256 hash, vEraseQueue)
6357 EraseOrphanTx(hash);
6359 // TODO: currently, prohibit joinsplits from entering mapOrphans
6360 else if (fMissingInputs && tx.vjoinsplit.size() == 0)
6362 AddOrphanTx(tx, pfrom->GetId());
6364 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6365 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6366 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6368 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6370 assert(recentRejects);
6371 recentRejects->insert(tx.GetHash());
6373 if (pfrom->fWhitelisted) {
6374 // Always relay transactions received from whitelisted peers, even
6375 // if they were already in the mempool or rejected from it due
6376 // to policy, allowing the node to function as a gateway for
6377 // nodes hidden behind it.
6379 // Never relay transactions that we would assign a non-zero DoS
6380 // score for, as we expect peers to do the same with us in that
6383 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6384 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6385 RelayTransaction(tx);
6387 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6388 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6393 if (state.IsInvalid(nDoS))
6395 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6396 pfrom->id, pfrom->cleanSubVer,
6397 state.GetRejectReason());
6398 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6399 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6401 Misbehaving(pfrom->GetId(), nDoS);
6406 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6408 std::vector<CBlockHeader> headers;
6410 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6411 unsigned int nCount = ReadCompactSize(vRecv);
6412 if (nCount > MAX_HEADERS_RESULTS) {
6413 Misbehaving(pfrom->GetId(), 20);
6414 return error("headers message size = %u", nCount);
6416 headers.resize(nCount);
6417 for (unsigned int n = 0; n < nCount; n++) {
6418 vRecv >> headers[n];
6419 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6425 // Nothing interesting. Stop asking this peers for more headers.
6429 CBlockIndex *pindexLast = NULL;
6430 BOOST_FOREACH(const CBlockHeader& header, headers) {
6431 CValidationState state;
6432 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6433 Misbehaving(pfrom->GetId(), 20);
6434 return error("non-continuous headers sequence");
6436 int32_t futureblock;
6437 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6439 if (state.IsInvalid(nDoS) && futureblock == 0)
6441 if (nDoS > 0 && futureblock == 0)
6442 Misbehaving(pfrom->GetId(), nDoS/nDoS);
6443 return error("invalid header received");
6449 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6451 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6452 // Headers message had its maximum size; the peer may have more headers.
6453 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6454 // from there instead.
6455 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->nHeight != pfrom->sendhdrsreq )
6457 pfrom->sendhdrsreq = (int32_t)pindexLast->nHeight;
6458 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
6459 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6466 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6471 CInv inv(MSG_BLOCK, block.GetHash());
6472 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6474 pfrom->AddInventoryKnown(inv);
6476 CValidationState state;
6477 // Process all blocks from whitelisted peers, even if not requested,
6478 // unless we're still syncing with the network.
6479 // Such an unrequested block may still be processed, subject to the
6480 // conditions in AcceptBlock().
6481 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6482 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
6484 if (state.IsInvalid(nDoS)) {
6485 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6486 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6489 Misbehaving(pfrom->GetId(), nDoS);
6496 // This asymmetric behavior for inbound and outbound connections was introduced
6497 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
6498 // to users' AddrMan and later request them by sending getaddr messages.
6499 // Making nodes which are behind NAT and can only make outgoing connections ignore
6500 // the getaddr message mitigates the attack.
6501 else if ((strCommand == "getaddr") && (pfrom->fInbound))
6503 // Only send one GetAddr response per connection to reduce resource waste
6504 // and discourage addr stamping of INV announcements.
6505 if (pfrom->fSentAddr) {
6506 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6509 pfrom->fSentAddr = true;
6511 pfrom->vAddrToSend.clear();
6512 vector<CAddress> vAddr = addrman.GetAddr();
6513 BOOST_FOREACH(const CAddress &addr, vAddr)
6514 pfrom->PushAddress(addr);
6518 else if (strCommand == "mempool")
6520 LOCK2(cs_main, pfrom->cs_filter);
6522 std::vector<uint256> vtxid;
6523 mempool.queryHashes(vtxid);
6525 BOOST_FOREACH(uint256& hash, vtxid) {
6526 CInv inv(MSG_TX, hash);
6528 bool fInMemPool = mempool.lookup(hash, tx);
6529 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
6530 if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
6532 vInv.push_back(inv);
6533 if (vInv.size() == MAX_INV_SZ) {
6534 pfrom->PushMessage("inv", vInv);
6538 if (vInv.size() > 0)
6539 pfrom->PushMessage("inv", vInv);
6543 else if (strCommand == "ping")
6545 if (pfrom->nVersion > BIP0031_VERSION)
6549 // Echo the message back with the nonce. This allows for two useful features:
6551 // 1) A remote node can quickly check if the connection is operational
6552 // 2) Remote nodes can measure the latency of the network thread. If this node
6553 // is overloaded it won't respond to pings quickly and the remote node can
6554 // avoid sending us more work, like chain download requests.
6556 // The nonce stops the remote getting confused between different pings: without
6557 // it, if the remote node sends a ping once per second and this node takes 5
6558 // seconds to respond to each, the 5th ping the remote sends would appear to
6559 // return very quickly.
6560 pfrom->PushMessage("pong", nonce);
6565 else if (strCommand == "pong")
6567 int64_t pingUsecEnd = nTimeReceived;
6569 size_t nAvail = vRecv.in_avail();
6570 bool bPingFinished = false;
6571 std::string sProblem;
6573 if (nAvail >= sizeof(nonce)) {
6576 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
6577 if (pfrom->nPingNonceSent != 0) {
6578 if (nonce == pfrom->nPingNonceSent) {
6579 // Matching pong received, this ping is no longer outstanding
6580 bPingFinished = true;
6581 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
6582 if (pingUsecTime > 0) {
6583 // Successful ping time measurement, replace previous
6584 pfrom->nPingUsecTime = pingUsecTime;
6585 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
6587 // This should never happen
6588 sProblem = "Timing mishap";
6591 // Nonce mismatches are normal when pings are overlapping
6592 sProblem = "Nonce mismatch";
6594 // This is most likely a bug in another implementation somewhere; cancel this ping
6595 bPingFinished = true;
6596 sProblem = "Nonce zero";
6600 sProblem = "Unsolicited pong without ping";
6603 // This is most likely a bug in another implementation somewhere; cancel this ping
6604 bPingFinished = true;
6605 sProblem = "Short payload";
6608 if (!(sProblem.empty())) {
6609 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
6613 pfrom->nPingNonceSent,
6617 if (bPingFinished) {
6618 pfrom->nPingNonceSent = 0;
6623 else if (fAlerts && strCommand == "alert")
6628 uint256 alertHash = alert.GetHash();
6629 if (pfrom->setKnown.count(alertHash) == 0)
6631 if (alert.ProcessAlert(Params().AlertKey()))
6634 pfrom->setKnown.insert(alertHash);
6637 BOOST_FOREACH(CNode* pnode, vNodes)
6638 alert.RelayTo(pnode);
6642 // Small DoS penalty so peers that send us lots of
6643 // duplicate/expired/invalid-signature/whatever alerts
6644 // eventually get banned.
6645 // This isn't a Misbehaving(100) (immediate ban) because the
6646 // peer might be an older or different implementation with
6647 // a different signature key, etc.
6648 Misbehaving(pfrom->GetId(), 10);
6654 else if (strCommand == "filterload")
6656 CBloomFilter filter;
6659 if (!filter.IsWithinSizeConstraints())
6660 // There is no excuse for sending a too-large filter
6661 Misbehaving(pfrom->GetId(), 100);
6664 LOCK(pfrom->cs_filter);
6665 delete pfrom->pfilter;
6666 pfrom->pfilter = new CBloomFilter(filter);
6667 pfrom->pfilter->UpdateEmptyFull();
6669 pfrom->fRelayTxes = true;
6673 else if (strCommand == "filteradd")
6675 vector<unsigned char> vData;
6678 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
6679 // and thus, the maximum size any matched object can have) in a filteradd message
6680 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
6682 Misbehaving(pfrom->GetId(), 100);
6684 LOCK(pfrom->cs_filter);
6686 pfrom->pfilter->insert(vData);
6688 Misbehaving(pfrom->GetId(), 100);
6693 else if (strCommand == "filterclear")
6695 LOCK(pfrom->cs_filter);
6696 delete pfrom->pfilter;
6697 pfrom->pfilter = new CBloomFilter();
6698 pfrom->fRelayTxes = true;
6702 else if (strCommand == "reject")
6706 string strMsg; unsigned char ccode; string strReason;
6707 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
6710 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
6712 if (strMsg == "block" || strMsg == "tx")
6716 ss << ": hash " << hash.ToString();
6718 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
6719 } catch (const std::ios_base::failure&) {
6720 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
6721 LogPrint("net", "Unparseable reject message received\n");
6725 else if (strCommand == "notfound") {
6726 // We do not care about the NOTFOUND message, but logging an Unknown Command
6727 // message would be undesirable as we transmit it ourselves.
6731 // Ignore unknown commands for extensibility
6732 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
6740 // requires LOCK(cs_vRecvMsg)
6741 bool ProcessMessages(CNode* pfrom)
6744 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
6748 // (4) message start
6756 if (!pfrom->vRecvGetData.empty())
6757 ProcessGetData(pfrom);
6759 // this maintains the order of responses
6760 if (!pfrom->vRecvGetData.empty()) return fOk;
6762 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
6763 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
6764 // Don't bother if send buffer is too full to respond anyway
6765 if (pfrom->nSendSize >= SendBufferSize())
6769 CNetMessage& msg = *it;
6772 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
6773 // msg.hdr.nMessageSize, msg.vRecv.size(),
6774 // msg.complete() ? "Y" : "N");
6776 // end, if an incomplete message is found
6777 if (!msg.complete())
6780 // at this point, any failure means we can delete the current message
6783 // Scan for message start
6784 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
6785 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
6791 CMessageHeader& hdr = msg.hdr;
6792 if (!hdr.IsValid(Params().MessageStart()))
6794 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
6797 string strCommand = hdr.GetCommand();
6800 unsigned int nMessageSize = hdr.nMessageSize;
6803 CDataStream& vRecv = msg.vRecv;
6804 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
6805 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
6806 if (nChecksum != hdr.nChecksum)
6808 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
6809 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
6817 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
6818 boost::this_thread::interruption_point();
6820 catch (const std::ios_base::failure& e)
6822 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
6823 if (strstr(e.what(), "end of data"))
6825 // Allow exceptions from under-length message on vRecv
6826 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());
6828 else if (strstr(e.what(), "size too large"))
6830 // Allow exceptions from over-long size
6831 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
6835 //PrintExceptionContinue(&e, "ProcessMessages()");
6838 catch (const boost::thread_interrupted&) {
6841 catch (const std::exception& e) {
6842 PrintExceptionContinue(&e, "ProcessMessages()");
6844 PrintExceptionContinue(NULL, "ProcessMessages()");
6848 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
6853 // In case the connection got shut down, its receive buffer was wiped
6854 if (!pfrom->fDisconnect)
6855 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
6861 bool SendMessages(CNode* pto, bool fSendTrickle)
6863 const Consensus::Params& consensusParams = Params().GetConsensus();
6865 // Don't send anything until we get its version message
6866 if (pto->nVersion == 0)
6872 bool pingSend = false;
6873 if (pto->fPingQueued) {
6874 // RPC ping request by user
6877 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
6878 // Ping automatically sent as a latency probe & keepalive.
6883 while (nonce == 0) {
6884 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
6886 pto->fPingQueued = false;
6887 pto->nPingUsecStart = GetTimeMicros();
6888 if (pto->nVersion > BIP0031_VERSION) {
6889 pto->nPingNonceSent = nonce;
6890 pto->PushMessage("ping", nonce);
6892 // Peer is too old to support ping command with nonce, pong will never arrive.
6893 pto->nPingNonceSent = 0;
6894 pto->PushMessage("ping");
6898 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
6902 // Address refresh broadcast
6903 static int64_t nLastRebroadcast;
6904 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
6907 BOOST_FOREACH(CNode* pnode, vNodes)
6909 // Periodically clear addrKnown to allow refresh broadcasts
6910 if (nLastRebroadcast)
6911 pnode->addrKnown.reset();
6913 // Rebroadcast our address
6914 AdvertizeLocal(pnode);
6916 if (!vNodes.empty())
6917 nLastRebroadcast = GetTime();
6925 vector<CAddress> vAddr;
6926 vAddr.reserve(pto->vAddrToSend.size());
6927 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
6929 if (!pto->addrKnown.contains(addr.GetKey()))
6931 pto->addrKnown.insert(addr.GetKey());
6932 vAddr.push_back(addr);
6933 // receiver rejects addr messages larger than 1000
6934 if (vAddr.size() >= 1000)
6936 pto->PushMessage("addr", vAddr);
6941 pto->vAddrToSend.clear();
6943 pto->PushMessage("addr", vAddr);
6946 CNodeState &state = *State(pto->GetId());
6947 if (state.fShouldBan) {
6948 if (pto->fWhitelisted)
6949 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
6951 pto->fDisconnect = true;
6952 if (pto->addr.IsLocal())
6953 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
6956 CNode::Ban(pto->addr);
6959 state.fShouldBan = false;
6962 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
6963 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
6964 state.rejects.clear();
6967 if (pindexBestHeader == NULL)
6968 pindexBestHeader = chainActive.Tip();
6969 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.
6970 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
6971 // Only actively request headers from a single peer, unless we're close to today.
6972 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
6973 state.fSyncStarted = true;
6975 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
6976 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
6977 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
6981 // Resend wallet transactions that haven't gotten in a block yet
6982 // Except during reindex, importing and IBD, when old wallet
6983 // transactions become unconfirmed and spams other nodes.
6984 if (!fReindex && !fImporting && !IsInitialBlockDownload())
6986 GetMainSignals().Broadcast(nTimeBestReceived);
6990 // Message: inventory
6993 vector<CInv> vInvWait;
6995 LOCK(pto->cs_inventory);
6996 vInv.reserve(pto->vInventoryToSend.size());
6997 vInvWait.reserve(pto->vInventoryToSend.size());
6998 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
7000 if (pto->setInventoryKnown.count(inv))
7003 // trickle out tx inv to protect privacy
7004 if (inv.type == MSG_TX && !fSendTrickle)
7006 // 1/4 of tx invs blast to all immediately
7007 static uint256 hashSalt;
7008 if (hashSalt.IsNull())
7009 hashSalt = GetRandHash();
7010 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
7011 hashRand = Hash(BEGIN(hashRand), END(hashRand));
7012 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
7016 vInvWait.push_back(inv);
7021 // returns true if wasn't already contained in the set
7022 if (pto->setInventoryKnown.insert(inv).second)
7024 vInv.push_back(inv);
7025 if (vInv.size() >= 1000)
7027 pto->PushMessage("inv", vInv);
7032 pto->vInventoryToSend = vInvWait;
7035 pto->PushMessage("inv", vInv);
7037 // Detect whether we're stalling
7038 int64_t nNow = GetTimeMicros();
7039 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7040 // Stalling only triggers when the block download window cannot move. During normal steady state,
7041 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7042 // should only happen during initial block download.
7043 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
7044 pto->fDisconnect = true;
7046 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
7047 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7048 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7049 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
7050 // to unreasonably increase our timeout.
7051 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7052 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7053 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7054 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7055 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7056 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7057 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
7058 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
7059 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7060 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7061 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7063 if (queuedBlock.nTimeDisconnect < nNow) {
7064 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7065 pto->fDisconnect = true;
7070 // Message: getdata (blocks)
7072 static uint256 zero;
7073 vector<CInv> vGetData;
7074 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
7075 vector<CBlockIndex*> vToDownload;
7076 NodeId staller = -1;
7077 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7078 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7079 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
7080 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
7081 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
7082 pindex->nHeight, pto->id);
7084 if (state.nBlocksInFlight == 0 && staller != -1) {
7085 if (State(staller)->nStallingSince == 0) {
7086 State(staller)->nStallingSince = nNow;
7087 LogPrint("net", "Stall started peer=%d\n", staller);
7091 /*CBlockIndex *pindex;
7092 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
7094 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7095 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7096 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7097 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
7098 komodo_requestedcount++;
7099 if ( komodo_requestedcount > 16 )
7101 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7102 komodo_requestedcount = 0;
7107 // Message: getdata (non-blocks)
7109 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
7111 const CInv& inv = (*pto->mapAskFor.begin()).second;
7112 if (!AlreadyHave(inv))
7115 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
7116 vGetData.push_back(inv);
7117 if (vGetData.size() >= 1000)
7119 pto->PushMessage("getdata", vGetData);
7123 //If we're not going to ask, don't expect a response.
7124 pto->setAskFor.erase(inv.hash);
7126 pto->mapAskFor.erase(pto->mapAskFor.begin());
7128 if (!vGetData.empty())
7129 pto->PushMessage("getdata", vGetData);
7135 std::string CBlockFileInfo::ToString() const {
7136 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));
7147 BlockMap::iterator it1 = mapBlockIndex.begin();
7148 for (; it1 != mapBlockIndex.end(); it1++)
7149 delete (*it1).second;
7150 mapBlockIndex.clear();
7152 // orphan transactions
7153 mapOrphanTransactions.clear();
7154 mapOrphanTransactionsByPrev.clear();
7156 } instance_of_cmaincleanup;
7158 extern "C" const char* getDataDir()
7160 return GetDataDir().string().c_str();
7164 // Set default values of new CMutableTransaction based on consensus rules at given height.
7165 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7167 CMutableTransaction mtx;
7169 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7170 if (isOverwintered) {
7171 mtx.fOverwintered = true;
7172 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7174 // Expiry height is not set. Only fields required for a parser to treat as a valid Overwinter V3 tx.
7176 // TODO: In future, when moving from Overwinter to Sapling, it will be useful
7177 // to set the expiry height to: min(activation_height - 1, default_expiry_height)