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"
42 #include <unordered_map>
45 #include <boost/algorithm/string/replace.hpp>
46 #include <boost/filesystem.hpp>
47 #include <boost/filesystem/fstream.hpp>
48 #include <boost/math/distributions/poisson.hpp>
49 #include <boost/thread.hpp>
50 #include <boost/static_assert.hpp>
55 # error "Zcash cannot be compiled without assertions."
58 #include "librustzcash.h"
64 CCriticalSection cs_main;
65 extern uint8_t NOTARY_PUBKEY33[33];
66 extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING;
67 int32_t KOMODO_NEWBLOCKS;
68 int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
69 void komodo_broadcast(CBlock *pblock,int32_t limit);
71 BlockMap mapBlockIndex;
73 CBlockIndex *pindexBestHeader = NULL;
74 static int64_t nTimeBestReceived = 0;
75 CWaitableCriticalSection csBestBlock;
76 CConditionVariable cvBlockChange;
77 int nScriptCheckThreads = 0;
78 bool fExperimentalMode = false;
79 bool fImporting = false;
80 bool fReindex = false;
81 bool fTxIndex = false;
82 bool fAddressIndex = false;
83 bool fTimestampIndex = false;
84 bool fSpentIndex = false;
85 bool fHavePruned = false;
86 bool fPruneMode = false;
87 bool fIsBareMultisigStd = true;
88 bool fCheckBlockIndex = false;
89 bool fCheckpointsEnabled = true;
90 bool fCoinbaseEnforcedProtectionEnabled = true;
91 size_t nCoinCacheUsage = 5000 * 300;
92 uint64_t nPruneTarget = 0;
93 bool fAlerts = DEFAULT_ALERTS;
94 /* If the tip is older than this (in seconds), the node is considered to be in initial block download.
96 int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
98 unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
100 /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
101 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
103 CTxMemPool mempool(::minRelayTxFee);
109 map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
110 map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
111 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
114 * Returns true if there are nRequired or more blocks of minVersion or above
115 * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
117 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
118 static void CheckBlockIndex();
120 /** Constant stuff for coinbase transactions we create: */
121 CScript COINBASE_FLAGS;
123 const string strMessageMagic = "Komodo Signed Message:\n";
128 struct CBlockIndexWorkComparator
130 bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
131 // First sort by most total work, ...
132 if (pa->chainPower > pb->chainPower) return false;
133 if (pa->chainPower < pb->chainPower) return true;
135 // ... then by earliest time received, ...
136 if (pa->nSequenceId < pb->nSequenceId) return false;
137 if (pa->nSequenceId > pb->nSequenceId) return true;
139 // Use pointer address as tie breaker (should only happen with blocks
140 // loaded from disk, as those all have id 0).
141 if (pa < pb) return false;
142 if (pa > pb) return true;
149 CBlockIndex *pindexBestInvalid;
152 * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
153 * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
154 * missing the data for the block.
156 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
158 /** Number of nodes with fSyncStarted. */
159 int nSyncStarted = 0;
161 /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
162 * Pruned nodes may have entries where B is missing data.
164 multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
166 CCriticalSection cs_LastBlockFile;
167 std::vector<CBlockFileInfo> vinfoBlockFile;
168 int nLastBlockFile = 0;
169 /** Global flag to indicate we should check to see if there are
170 * block/undo files that should be deleted. Set on startup
171 * or if we allocate more file space when we're in prune mode
173 bool fCheckForPruning = false;
176 * Every received block is assigned a unique and increasing identifier, so we
177 * know which one to give priority in case of a fork.
179 CCriticalSection cs_nBlockSequenceId;
180 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
181 uint32_t nBlockSequenceId = 1;
184 * Sources of received blocks, saved to be able to send them reject
185 * messages or ban them when processing happens afterwards. Protected by
188 map<uint256, NodeId> mapBlockSource;
191 * Filter for transactions that were recently rejected by
192 * AcceptToMemoryPool. These are not rerequested until the chain tip
193 * changes, at which point the entire filter is reset. Protected by
196 * Without this filter we'd be re-requesting txs from each of our peers,
197 * increasing bandwidth consumption considerably. For instance, with 100
198 * peers, half of which relay a tx we don't accept, that might be a 50x
199 * bandwidth increase. A flooding attacker attempting to roll-over the
200 * filter using minimum-sized, 60byte, transactions might manage to send
201 * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
202 * two minute window to send invs to us.
204 * Decreasing the false positive rate is fairly cheap, so we pick one in a
205 * million to make it highly unlikely for users to have issues with this
210 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
211 uint256 hashRecentRejectsChainTip;
213 /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
216 CBlockIndex *pindex; //! Optional.
217 int64_t nTime; //! Time of "getdata" request in microseconds.
218 bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
219 int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
221 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
223 /** Number of blocks in flight with validated headers. */
224 int nQueuedValidatedHeaders = 0;
226 /** Number of preferable block download peers. */
227 int nPreferredDownload = 0;
229 /** Dirty block index entries. */
230 set<CBlockIndex*> setDirtyBlockIndex;
232 /** Dirty block file entries. */
233 set<int> setDirtyFileInfo;
236 //////////////////////////////////////////////////////////////////////////////
238 // Registration of network node signals.
243 struct CBlockReject {
244 unsigned char chRejectCode;
245 string strRejectReason;
250 * Maintain validation-specific state about nodes, protected by cs_main, instead
251 * by CNode's own locks. This simplifies asynchronous operation, where
252 * processing of incoming data is done after the ProcessMessage call returns,
253 * and we're no longer holding the node's locks.
256 //! The peer's address
258 //! Whether we have a fully established connection.
259 bool fCurrentlyConnected;
260 //! Accumulated misbehaviour score for this peer.
262 //! Whether this peer should be disconnected and banned (unless whitelisted).
264 //! String name of this peer (debugging/logging purposes).
266 //! List of asynchronously-determined block rejections to notify this peer about.
267 std::vector<CBlockReject> rejects;
268 //! The best known block we know this peer has announced.
269 CBlockIndex *pindexBestKnownBlock;
270 //! The hash of the last unknown block this peer has announced.
271 uint256 hashLastUnknownBlock;
272 //! The last full block we both have.
273 CBlockIndex *pindexLastCommonBlock;
274 //! Whether we've started headers synchronization with this peer.
276 //! Since when we're stalling block download progress (in microseconds), or 0.
277 int64_t nStallingSince;
278 list<QueuedBlock> vBlocksInFlight;
280 int nBlocksInFlightValidHeaders;
281 //! Whether we consider this a preferred download peer.
282 bool fPreferredDownload;
285 fCurrentlyConnected = false;
288 pindexBestKnownBlock = NULL;
289 hashLastUnknownBlock.SetNull();
290 pindexLastCommonBlock = NULL;
291 fSyncStarted = false;
294 nBlocksInFlightValidHeaders = 0;
295 fPreferredDownload = false;
299 /** Map maintaining per-node state. Requires cs_main. */
300 map<NodeId, CNodeState> mapNodeState;
303 CNodeState *State(NodeId pnode) {
304 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
305 if (it == mapNodeState.end())
312 return chainActive.LastTip()->GetHeight();
315 void UpdatePreferredDownload(CNode* node, CNodeState* state)
317 nPreferredDownload -= state->fPreferredDownload;
319 // Whether this node should be marked as a preferred download node.
320 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
322 nPreferredDownload += state->fPreferredDownload;
325 // Returns time at which to timeout block request (nTime in microseconds)
326 int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
328 return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
331 void InitializeNode(NodeId nodeid, const CNode *pnode) {
333 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
334 state.name = pnode->addrName;
335 state.address = pnode->addr;
338 void FinalizeNode(NodeId nodeid) {
340 CNodeState *state = State(nodeid);
342 if (state->fSyncStarted)
345 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
346 AddressCurrentlyConnected(state->address);
349 BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
350 mapBlocksInFlight.erase(entry.hash);
351 EraseOrphansFor(nodeid);
352 nPreferredDownload -= state->fPreferredDownload;
354 mapNodeState.erase(nodeid);
357 void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
359 /* int expired = pool.Expire(GetTime() - age);
361 LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
363 std::vector<uint256> vNoSpendsRemaining;
364 pool.TrimToSize(limit, &vNoSpendsRemaining);
365 BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
366 pcoinsTip->Uncache(removed);*/
370 // Returns a bool indicating whether we requested this block.
371 bool MarkBlockAsReceived(const uint256& hash) {
372 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
373 if (itInFlight != mapBlocksInFlight.end()) {
374 CNodeState *state = State(itInFlight->second.first);
375 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
376 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
377 state->vBlocksInFlight.erase(itInFlight->second.second);
378 state->nBlocksInFlight--;
379 state->nStallingSince = 0;
380 mapBlocksInFlight.erase(itInFlight);
387 void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
388 CNodeState *state = State(nodeid);
389 assert(state != NULL);
391 // Make sure it's not listed somewhere already.
392 MarkBlockAsReceived(hash);
394 int64_t nNow = GetTimeMicros();
395 QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
396 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
397 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
398 state->nBlocksInFlight++;
399 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
400 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
403 /** Check whether the last unknown block a peer advertized is not yet known. */
404 void ProcessBlockAvailability(NodeId nodeid) {
405 CNodeState *state = State(nodeid);
406 assert(state != NULL);
408 if (!state->hashLastUnknownBlock.IsNull()) {
409 BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
410 if (itOld != mapBlockIndex.end() && itOld->second != 0 && (itOld->second->chainPower > CChainPower()))
412 if (state->pindexBestKnownBlock == NULL || itOld->second->chainPower >= state->pindexBestKnownBlock->chainPower)
413 state->pindexBestKnownBlock = itOld->second;
414 state->hashLastUnknownBlock.SetNull();
419 /** Update tracking information about which blocks a peer is assumed to have. */
420 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
421 CNodeState *state = State(nodeid);
422 assert(state != NULL);
424 /*ProcessBlockAvailability(nodeid);
426 BlockMap::iterator it = mapBlockIndex.find(hash);
427 if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
428 // An actually better block was announced.
429 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
430 state->pindexBestKnownBlock = it->second;
433 // An unknown block was announced; just assume that the latest one is the best one.
434 state->hashLastUnknownBlock = hash;
438 /** Find the last common ancestor two blocks have.
439 * Both pa and pb must be non-NULL. */
440 CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
441 if (pa->GetHeight() > pb->GetHeight()) {
442 pa = pa->GetAncestor(pb->GetHeight());
443 } else if (pb->GetHeight() > pa->GetHeight()) {
444 pb = pb->GetAncestor(pa->GetHeight());
447 while (pa != pb && pa && pb) {
452 // Eventually all chain branches meet at the genesis block.
457 /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
458 * at most count entries. */
459 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
463 vBlocks.reserve(vBlocks.size() + count);
464 CNodeState *state = State(nodeid);
465 assert(state != NULL);
467 // Make sure pindexBestKnownBlock is up to date, we'll need it.
468 ProcessBlockAvailability(nodeid);
470 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->chainPower < chainActive.Tip()->chainPower) {
471 // This peer has nothing interesting.
475 if (state->pindexLastCommonBlock == NULL) {
476 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
477 // Guessing wrong in either direction is not a problem.
478 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->GetHeight(), chainActive.Height())];
481 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
482 // of its current tip anymore. Go back enough to fix that.
483 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
484 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
487 std::vector<CBlockIndex*> vToFetch;
488 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
489 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
490 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
491 // download that next block if the window were 1 larger.
492 int nWindowEnd = state->pindexLastCommonBlock->GetHeight() + BLOCK_DOWNLOAD_WINDOW;
493 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->GetHeight(), nWindowEnd + 1);
494 NodeId waitingfor = -1;
495 while (pindexWalk->GetHeight() < nMaxHeight) {
496 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
497 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
498 // as iterating over ~100 CBlockIndex* entries anyway.
499 int nToFetch = std::min(nMaxHeight - pindexWalk->GetHeight(), std::max<int>(count - vBlocks.size(), 128));
500 vToFetch.resize(nToFetch);
501 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->GetHeight() + nToFetch);
502 vToFetch[nToFetch - 1] = pindexWalk;
503 for (unsigned int i = nToFetch - 1; i > 0; i--) {
504 vToFetch[i - 1] = vToFetch[i]->pprev;
507 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
508 // are not yet downloaded and not in flight to vBlocks. In the meantime, update
509 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
510 // already part of our chain (and therefore don't need it even if pruned).
511 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
512 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
513 // We consider the chain that this peer is on invalid.
516 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
517 if (pindex->nChainTx)
518 state->pindexLastCommonBlock = pindex;
519 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
520 // The block is not already downloaded, and not yet in flight.
521 if (pindex->GetHeight() > nWindowEnd) {
522 // We reached the end of the window.
523 if (vBlocks.size() == 0 && waitingfor != nodeid) {
524 // We aren't able to fetch anything, but we would be if the download window was one larger.
525 nodeStaller = waitingfor;
529 vBlocks.push_back(pindex);
530 if (vBlocks.size() == count) {
533 } else if (waitingfor == -1) {
534 // This is the first already-in-flight block.
535 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
543 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
545 CNodeState *state = State(nodeid);
548 stats.nMisbehavior = state->nMisbehavior;
549 stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->GetHeight() : -1;
550 stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->GetHeight() : -1;
551 BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
553 stats.vHeightInFlight.push_back(queue.pindex->GetHeight());
558 void RegisterNodeSignals(CNodeSignals& nodeSignals)
560 nodeSignals.GetHeight.connect(&GetHeight);
561 nodeSignals.ProcessMessages.connect(&ProcessMessages);
562 nodeSignals.SendMessages.connect(&SendMessages);
563 nodeSignals.InitializeNode.connect(&InitializeNode);
564 nodeSignals.FinalizeNode.connect(&FinalizeNode);
567 void UnregisterNodeSignals(CNodeSignals& nodeSignals)
569 nodeSignals.GetHeight.disconnect(&GetHeight);
570 nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
571 nodeSignals.SendMessages.disconnect(&SendMessages);
572 nodeSignals.InitializeNode.disconnect(&InitializeNode);
573 nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
576 CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
578 // Find the first block the caller has in the main chain
579 BOOST_FOREACH(const uint256& hash, locator.vHave) {
580 BlockMap::iterator mi = mapBlockIndex.find(hash);
581 if (mi != mapBlockIndex.end())
583 CBlockIndex* pindex = (*mi).second;
584 if (pindex != 0 && chain.Contains(pindex))
586 if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
591 return chain.Genesis();
594 CCoinsViewCache *pcoinsTip = NULL;
595 CBlockTreeDB *pblocktree = NULL;
602 UniValue komodo_snapshot(int top)
606 UniValue result(UniValue::VOBJ);
609 if ( pblocktree != 0 ) {
610 result = pblocktree->Snapshot(top);
612 fprintf(stderr,"null pblocktree start with -addressindex=1\n");
615 fprintf(stderr,"getsnapshot requires -addressindex=1\n");
620 //////////////////////////////////////////////////////////////////////////////
622 // mapOrphanTransactions
625 bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
627 uint256 hash = tx.GetHash();
628 if (mapOrphanTransactions.count(hash))
631 // Ignore big transactions, to avoid a
632 // send-big-orphans memory exhaustion attack. If a peer has a legitimate
633 // large transaction with a missing parent then we assume
634 // it will rebroadcast it later, after the parent transaction(s)
635 // have been mined or received.
636 // 10,000 orphans, each of which is at most 5,000 bytes big is
637 // at most 500 megabytes of orphans:
638 unsigned int sz = GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
641 LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
645 mapOrphanTransactions[hash].tx = tx;
646 mapOrphanTransactions[hash].fromPeer = peer;
647 BOOST_FOREACH(const CTxIn& txin, tx.vin)
648 mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
650 LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
651 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
655 void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
657 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
658 if (it == mapOrphanTransactions.end())
660 BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
662 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
663 if (itPrev == mapOrphanTransactionsByPrev.end())
665 itPrev->second.erase(hash);
666 if (itPrev->second.empty())
667 mapOrphanTransactionsByPrev.erase(itPrev);
669 mapOrphanTransactions.erase(it);
672 void EraseOrphansFor(NodeId peer)
675 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
676 while (iter != mapOrphanTransactions.end())
678 map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
679 if (maybeErase->second.fromPeer == peer)
681 EraseOrphanTx(maybeErase->second.tx.GetHash());
685 if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
689 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
691 unsigned int nEvicted = 0;
692 while (mapOrphanTransactions.size() > nMaxOrphans)
694 // Evict a random orphan:
695 uint256 randomhash = GetRandHash();
696 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
697 if (it == mapOrphanTransactions.end())
698 it = mapOrphanTransactions.begin();
699 EraseOrphanTx(it->first);
706 bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
708 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
709 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
712 // Sapling standard rules apply
713 if (tx.nVersion > CTransaction::SAPLING_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SAPLING_MIN_CURRENT_VERSION) {
714 reason = "sapling-version";
717 } else if (overwinterActive) {
718 // Overwinter standard rules apply
719 if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
720 reason = "overwinter-version";
724 // Sprout standard rules apply
725 if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
731 BOOST_FOREACH(const CTxIn& txin, tx.vin)
733 // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
734 // keys. (remember the 520 byte limit on redeemScript size) That works
735 // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
736 // bytes of scriptSig, which we round off to 1650 bytes for some minor
737 // future-proofing. That's also enough to spend a 20-of-20
738 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
739 // considered standard)
740 if (txin.scriptSig.size() > 1650) {
741 reason = "scriptsig-size";
744 if (!txin.scriptSig.IsPushOnly()) {
745 reason = "scriptsig-not-pushonly";
750 unsigned int v=0,nDataOut = 0;
751 txnouttype whichType;
752 BOOST_FOREACH(const CTxOut& txout, tx.vout)
754 if (!::IsStandard(txout.scriptPubKey, whichType))
756 reason = "scriptpubkey";
757 //fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
761 if (whichType == TX_NULL_DATA)
763 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
765 reason = "opreturn too big";
769 //fprintf(stderr,"is OP_RETURN\n");
771 else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
772 reason = "bare-multisig";
774 } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) {
781 // only one OP_RETURN txout is permitted
783 reason = "multi-op-return";
790 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
793 if (tx.nLockTime == 0)
795 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
797 BOOST_FOREACH(const CTxIn& txin, tx.vin)
799 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)) )
803 else if (!txin.IsFinal())
805 //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
812 bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
814 if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
817 return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
820 bool CheckFinalTx(const CTransaction &tx, int flags)
822 AssertLockHeld(cs_main);
824 // By convention a negative value for flags indicates that the
825 // current network-enforced consensus rules should be used. In
826 // a future soft-fork scenario that would mean checking which
827 // rules would be enforced for the next block and setting the
828 // appropriate flags. At the present time no soft-forks are
829 // scheduled, so no flags are set.
830 flags = std::max(flags, 0);
832 // CheckFinalTx() uses chainActive.Height()+1 to evaluate
833 // nLockTime because when IsFinalTx() is called within
834 // CBlock::AcceptBlock(), the height of the block *being*
835 // evaluated is what is used. Thus if we want to know if a
836 // transaction can be part of the *next* block, we need to call
837 // IsFinalTx() with one more than chainActive.Height().
838 const int nBlockHeight = chainActive.Height() + 1;
840 // Timestamps on the other hand don't get any special treatment,
841 // because we can't know what timestamp the next block will have,
842 // and there aren't timestamp applications where it matters.
843 // However this changes once median past time-locks are enforced:
844 const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
845 ? chainActive.Tip()->GetMedianTimePast()
848 return IsFinalTx(tx, nBlockHeight, nBlockTime);
852 * Check transaction inputs to mitigate two
853 * potential denial-of-service attacks:
855 * 1. scriptSigs with extra data stuffed into them,
856 * not consumed by scriptPubKey (or P2SH script)
857 * 2. P2SH scripts with a crazy number of expensive
858 * CHECKSIG/CHECKMULTISIG operations
860 bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
863 return true; // Coinbases don't use vin normally
865 if (tx.IsCoinImport())
866 return tx.vin[0].scriptSig.IsCoinImport();
868 for (unsigned int i = 0; i < tx.vin.size(); i++)
870 const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
872 vector<vector<unsigned char> > vSolutions;
873 txnouttype whichType;
874 // get the scriptPubKey corresponding to this input:
875 const CScript& prevScript = prev.scriptPubKey;
876 //printf("Previous script: %s\n", prevScript.ToString().c_str());
878 if (!Solver(prevScript, whichType, vSolutions))
880 int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
881 if (nArgsExpected < 0)
884 // Transactions with extra stuff in their scriptSigs are
885 // non-standard. Note that this EvalScript() call will
886 // be quick, because if there are any operations
887 // beside "push data" in the scriptSig
888 // IsStandardTx() will have already returned false
889 // and this method isn't called.
890 vector<vector<unsigned char> > stack;
891 //printf("Checking script: %s\n", tx.vin[i].scriptSig.ToString().c_str());
892 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
895 if (whichType == TX_SCRIPTHASH)
899 CScript subscript(stack.back().begin(), stack.back().end());
900 vector<vector<unsigned char> > vSolutions2;
901 txnouttype whichType2;
902 if (Solver(subscript, whichType2, vSolutions2))
904 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
907 nArgsExpected += tmpExpected;
911 // Any other Script with less than 15 sigops OK:
912 unsigned int sigops = subscript.GetSigOpCount(true);
913 // ... extra data left on the stack after execution is OK, too:
914 return (sigops <= MAX_P2SH_SIGOPS);
918 if (stack.size() != (unsigned int)nArgsExpected)
925 unsigned int GetLegacySigOpCount(const CTransaction& tx)
927 unsigned int nSigOps = 0;
928 BOOST_FOREACH(const CTxIn& txin, tx.vin)
930 nSigOps += txin.scriptSig.GetSigOpCount(false);
932 BOOST_FOREACH(const CTxOut& txout, tx.vout)
934 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
939 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
941 if (tx.IsCoinBase() || tx.IsCoinImport())
944 unsigned int nSigOps = 0;
945 for (unsigned int i = 0; i < tx.vin.size(); i++)
947 const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
948 if (prevout.scriptPubKey.IsPayToScriptHash())
949 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
955 * Ensure that a coinbase transaction is structured according to the consensus rules of the
958 bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight)
960 // if time locks are on, ensure that this coin base is time locked exactly as it should be
961 if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) ||
962 (((nHeight >= 31680) || strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE))
964 CScriptID scriptHash;
966 // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that
967 // holds the full output script, which may include multisig, etc., but starts with
968 // the time lock verify of the correct time lock for this block height
969 if (tx.vout.size() == 2 &&
970 CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) &&
971 tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
972 tx.vout[1].scriptPubKey[0] == OP_RETURN)
975 std::vector<uint8_t> opretData = std::vector<uint8_t>();
976 CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
977 if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
979 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
982 CScriptExt opretScript = CScriptExt(&opretData[1], &opretData[opretData.size()]);
984 if (CScriptID(opretScript) == scriptHash &&
985 opretScript.IsCheckLockTimeVerify(&unlocktime) &&
986 komodo_block_unlocktime(nHeight) == unlocktime)
999 * Check a transaction contextually against a set of consensus rules valid at a given block height.
1002 * 1. AcceptToMemoryPool calls CheckTransaction and this function.
1003 * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
1004 * and ContextualCheckBlock (which calls this function).
1005 * 3. The isInitBlockDownload argument is only to assist with testing.
1007 bool ContextualCheckTransaction(
1008 const CTransaction& tx,
1009 CValidationState &state,
1012 bool (*isInitBlockDownload)())
1014 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
1015 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
1016 bool isSprout = !overwinterActive;
1018 // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
1019 if (isSprout && tx.fOverwintered) {
1020 return state.DoS(isInitBlockDownload() ? 0 : dosLevel,
1021 error("ContextualCheckTransaction(): ht.%d activates.%d dosLevel.%d overwinter is not active yet",
1022 nHeight, Params().GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight, dosLevel),
1023 REJECT_INVALID, "tx-overwinter-not-active");
1026 if (saplingActive) {
1027 // Reject transactions with valid version but missing overwintered flag
1028 if (tx.nVersion >= SAPLING_MIN_TX_VERSION && !tx.fOverwintered) {
1029 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwintered flag must be set"),
1030 REJECT_INVALID, "tx-overwintered-flag-not-set");
1033 // Reject transactions with non-Sapling version group ID
1034 if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1035 return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),
1036 REJECT_INVALID, "bad-sapling-tx-version-group-id");
1039 // Reject transactions with invalid version
1040 if (tx.fOverwintered && tx.nVersion < SAPLING_MIN_TX_VERSION ) {
1041 return state.DoS(100, error("CheckTransaction(): Sapling version too low"),
1042 REJECT_INVALID, "bad-tx-sapling-version-too-low");
1045 // Reject transactions with invalid version
1046 if (tx.fOverwintered && tx.nVersion > SAPLING_MAX_TX_VERSION ) {
1047 return state.DoS(100, error("CheckTransaction(): Sapling version too high"),
1048 REJECT_INVALID, "bad-tx-sapling-version-too-high");
1050 } else if (overwinterActive) {
1051 // Reject transactions with valid version but missing overwinter flag
1052 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
1053 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
1054 REJECT_INVALID, "tx-overwinter-flag-not-set");
1057 // Reject transactions with non-Overwinter version group ID
1058 if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1059 return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),
1060 REJECT_INVALID, "bad-overwinter-tx-version-group-id");
1063 // Reject transactions with invalid version
1064 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
1065 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
1066 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
1070 // Rules that apply to Overwinter or later:
1071 if (overwinterActive) {
1072 // Reject transactions intended for Sprout
1073 if (!tx.fOverwintered) {
1074 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
1075 REJECT_INVALID, "tx-overwinter-active");
1078 // Check that all transactions are unexpired
1079 if (IsExpiredTx(tx, nHeight)) {
1080 // Don't increase banscore if the transaction only just expired
1081 int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? (dosLevel > 10 ? dosLevel : 10) : 0;
1082 return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
1086 // Rules that apply before Sapling:
1087 if (!saplingActive) {
1089 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1090 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_BEFORE_SAPLING)
1091 return state.DoS(100, error("ContextualCheckTransaction(): size limits failed"),
1092 REJECT_INVALID, "bad-txns-oversize");
1095 uint256 dataToBeSigned;
1098 (!tx.vjoinsplit.empty() ||
1099 !tx.vShieldedSpend.empty() ||
1100 !tx.vShieldedOutput.empty()))
1102 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
1103 // Empty output script.
1106 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1107 } catch (std::logic_error ex) {
1108 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
1109 REJECT_INVALID, "error-computing-signature-hash");
1114 if (!(tx.IsMint() || tx.vjoinsplit.empty()))
1116 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
1118 // We rely on libsodium to check that the signature is canonical.
1119 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1120 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1121 dataToBeSigned.begin(), 32,
1122 tx.joinSplitPubKey.begin()
1124 return state.DoS(isInitBlockDownload() ? 0 : 100,
1125 error("CheckTransaction(): invalid joinsplit signature"),
1126 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1130 if (tx.IsCoinBase())
1132 if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1133 return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1134 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
1137 if (!tx.vShieldedSpend.empty() ||
1138 !tx.vShieldedOutput.empty())
1140 auto ctx = librustzcash_sapling_verification_ctx_init();
1142 for (const SpendDescription &spend : tx.vShieldedSpend) {
1143 if (!librustzcash_sapling_check_spend(
1146 spend.anchor.begin(),
1147 spend.nullifier.begin(),
1149 spend.zkproof.begin(),
1150 spend.spendAuthSig.begin(),
1151 dataToBeSigned.begin()
1154 librustzcash_sapling_verification_ctx_free(ctx);
1155 return state.DoS(100, error("ContextualCheckTransaction(): Sapling spend description invalid"),
1156 REJECT_INVALID, "bad-txns-sapling-spend-description-invalid");
1160 for (const OutputDescription &output : tx.vShieldedOutput) {
1161 if (!librustzcash_sapling_check_output(
1165 output.ephemeralKey.begin(),
1166 output.zkproof.begin()
1169 librustzcash_sapling_verification_ctx_free(ctx);
1170 return state.DoS(100, error("ContextualCheckTransaction(): Sapling output description invalid"),
1171 REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
1175 if (!librustzcash_sapling_final_check(
1178 tx.bindingSig.begin(),
1179 dataToBeSigned.begin()
1182 librustzcash_sapling_verification_ctx_free(ctx);
1183 return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
1184 REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
1187 librustzcash_sapling_verification_ctx_free(ctx);
1192 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1193 libzcash::ProofVerifier& verifier)
1195 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1196 if ( *(int32_t *)&array[0] == 0 )
1197 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1201 for (k=0; k<numbanned; k++)
1203 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1205 static uint32_t counter;
1206 if ( counter++ < 100 )
1207 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->GetHeight(),j);
1212 // Don't count coinbase transactions because mining skews the count
1213 if (!tx.IsCoinBase()) {
1214 transactionsValidated.increment();
1217 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1220 // Ensure that zk-SNARKs v|| y
1221 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1222 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1223 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1224 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1231 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1233 // Basic checks that don't depend on any context
1237 * 1. The consensus rule below was:
1238 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1239 * which checked if tx.nVersion fell within the range:
1240 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1241 * 2. The parser allowed tx.nVersion to be negative
1244 * 1. The consensus rule checks to see if tx.Version falls within the range:
1245 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1246 * 2. The previous consensus rule checked for negative values within the range:
1247 * INT32_MIN <= tx.nVersion < 0
1248 * This is unnecessary for Overwinter transactions since the parser now
1249 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1250 * and when Overwinter is not active ContextualCheckTransaction rejects
1251 * transactions with fOverwintered set. When fOverwintered is set,
1252 * this function and ContextualCheckTransaction will together check to
1253 * ensure tx.nVersion avoids the following ranges:
1254 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1255 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1257 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1258 return state.DoS(100, error("CheckTransaction(): version too low"),
1259 REJECT_INVALID, "bad-txns-version-too-low");
1261 else if (tx.fOverwintered) {
1262 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1263 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1264 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1266 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID &&
1267 tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1268 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1269 REJECT_INVALID, "bad-tx-version-group-id");
1271 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1272 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1273 REJECT_INVALID, "bad-tx-expiry-height-too-high");
1277 // Transactions containing empty `vin` must have either non-empty
1278 // `vjoinsplit` or non-empty `vShieldedSpend`.
1279 if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
1280 return state.DoS(10, error("CheckTransaction(): vin empty"),
1281 REJECT_INVALID, "bad-txns-vin-empty");
1282 // Transactions containing empty `vout` must have either non-empty
1283 // `vjoinsplit` or non-empty `vShieldedOutput`.
1284 if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
1285 return state.DoS(10, error("CheckTransaction(): vout empty"),
1286 REJECT_INVALID, "bad-txns-vout-empty");
1289 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE >= MAX_TX_SIZE_AFTER_SAPLING); // sanity
1290 BOOST_STATIC_ASSERT(MAX_TX_SIZE_AFTER_SAPLING > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1291 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_AFTER_SAPLING)
1292 return state.DoS(100, error("CheckTransaction(): size limits failed"),
1293 REJECT_INVALID, "bad-txns-oversize");
1295 // Check for negative or overflow output values
1296 CAmount nValueOut = 0;
1297 int32_t iscoinbase = tx.IsCoinBase();
1298 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1300 if (txout.nValue < 0)
1301 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1302 REJECT_INVALID, "bad-txns-vout-negative");
1303 if (txout.nValue > MAX_MONEY)
1305 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1306 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1308 if ( ASSETCHAINS_PRIVATE != 0 )
1310 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
1311 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetValueOut() > 0 )
1312 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
1314 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
1315 return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative");
1316 nValueOut += txout.nValue;
1317 if (!MoneyRange(nValueOut))
1318 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1319 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1322 // Check for non-zero valueBalance when there are no Sapling inputs or outputs
1323 if (tx.vShieldedSpend.empty() && tx.vShieldedOutput.empty() && tx.valueBalance != 0) {
1324 return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"),
1325 REJECT_INVALID, "bad-txns-valuebalance-nonzero");
1328 // Check for overflow valueBalance
1329 if (tx.valueBalance > MAX_MONEY || tx.valueBalance < -MAX_MONEY) {
1330 return state.DoS(100, error("CheckTransaction(): abs(tx.valueBalance) too large"),
1331 REJECT_INVALID, "bad-txns-valuebalance-toolarge");
1334 if (tx.valueBalance <= 0) {
1335 // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
1336 nValueOut += -tx.valueBalance;
1338 if (!MoneyRange(nValueOut)) {
1339 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1340 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1344 // Ensure that joinsplit values are well-formed
1345 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1347 if ( ASSETCHAINS_PUBLIC != 0 )
1349 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1350 REJECT_INVALID, "bad-txns-acprivacy-chain");
1352 if (joinsplit.vpub_old < 0) {
1353 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1354 REJECT_INVALID, "bad-txns-vpub_old-negative");
1357 if (joinsplit.vpub_new < 0) {
1358 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1359 REJECT_INVALID, "bad-txns-vpub_new-negative");
1362 if (joinsplit.vpub_old > MAX_MONEY) {
1363 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1364 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1367 if (joinsplit.vpub_new > MAX_MONEY) {
1368 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1369 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1372 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1373 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1374 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1377 nValueOut += joinsplit.vpub_old;
1378 if (!MoneyRange(nValueOut)) {
1379 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1380 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1384 // Ensure input values do not exceed MAX_MONEY
1385 // We have not resolved the txin values at this stage,
1386 // but we do know what the joinsplits claim to add
1387 // to the value pool.
1389 CAmount nValueIn = 0;
1390 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1392 nValueIn += it->vpub_new;
1394 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1395 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1396 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1400 // Also check for Sapling
1401 if (tx.valueBalance >= 0) {
1402 // NB: positive valueBalance "adds" money to the transparent value pool, just as inputs do
1403 nValueIn += tx.valueBalance;
1405 if (!MoneyRange(nValueIn)) {
1406 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1407 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1412 // Check for duplicate inputs
1413 set<COutPoint> vInOutPoints;
1414 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1416 if (vInOutPoints.count(txin.prevout))
1417 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1418 REJECT_INVALID, "bad-txns-inputs-duplicate");
1419 vInOutPoints.insert(txin.prevout);
1422 // Check for duplicate joinsplit nullifiers in this transaction
1424 set<uint256> vJoinSplitNullifiers;
1425 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1427 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1429 if (vJoinSplitNullifiers.count(nf))
1430 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1431 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1433 vJoinSplitNullifiers.insert(nf);
1438 // Check for duplicate sapling nullifiers in this transaction
1440 set<uint256> vSaplingNullifiers;
1441 BOOST_FOREACH(const SpendDescription& spend_desc, tx.vShieldedSpend)
1443 if (vSaplingNullifiers.count(spend_desc.nullifier))
1444 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1445 REJECT_INVALID, "bad-spend-description-nullifiers-duplicate");
1447 vSaplingNullifiers.insert(spend_desc.nullifier);
1453 // There should be no joinsplits in a coinbase transaction
1454 if (tx.vjoinsplit.size() > 0)
1455 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1456 REJECT_INVALID, "bad-cb-has-joinsplits");
1458 // A coinbase transaction cannot have spend descriptions or output descriptions
1459 if (tx.vShieldedSpend.size() > 0)
1460 return state.DoS(100, error("CheckTransaction(): coinbase has spend descriptions"),
1461 REJECT_INVALID, "bad-cb-has-spend-description");
1462 if (tx.vShieldedOutput.size() > 0)
1463 return state.DoS(100, error("CheckTransaction(): coinbase has output descriptions"),
1464 REJECT_INVALID, "bad-cb-has-output-description");
1466 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1467 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1468 REJECT_INVALID, "bad-cb-length");
1472 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1473 if (txin.prevout.IsNull())
1474 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1475 REJECT_INVALID, "bad-txns-prevout-null");
1481 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1483 extern int32_t KOMODO_ON_DEMAND;
1486 uint256 hash = tx.GetHash();
1487 double dPriorityDelta = 0;
1488 CAmount nFeeDelta = 0;
1489 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1490 if (dPriorityDelta > 0 || nFeeDelta > 0)
1494 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1498 // There is a free transaction area in blocks created by most miners,
1499 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1500 // to be considered to fall into this category. We don't want to encourage sending
1501 // multiple transactions instead of one big transaction to avoid fees.
1502 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1506 if (!MoneyRange(nMinFee))
1507 nMinFee = MAX_MONEY;
1512 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel)
1514 AssertLockHeld(cs_main);
1515 if (pfMissingInputs)
1516 *pfMissingInputs = false;
1518 int flag=0,nextBlockHeight = chainActive.Height() + 1;
1519 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1521 // Node operator can choose to reject tx by number of transparent inputs
1522 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1523 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1524 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
1528 size_t n = tx.vin.size();
1530 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1535 auto verifier = libzcash::ProofVerifier::Strict();
1536 if ( komodo_validate_interest(tx,chainActive.LastTip()->GetHeight()+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
1538 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1539 return error("AcceptToMemoryPool: komodo_validate_interest failed");
1541 if (!CheckTransaction(tx, state, verifier))
1543 return error("AcceptToMemoryPool: CheckTransaction failed");
1545 // DoS level set to 10 to be more forgiving.
1546 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1547 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel))
1549 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1551 // Coinbase is only valid in a block, not as a loose transaction
1552 if (tx.IsCoinBase())
1554 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1555 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1557 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1559 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1562 //fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\nscriptPubKey: %s\n",reason.c_str(),tx.vout[0].scriptPubKey.ToString().c_str());
1563 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1565 // Only accept nLockTime-using transactions that can be mined in the next
1566 // block; we don't want our mempool filled up with transactions that can't
1568 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1570 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1571 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1574 // if this is a valid stake transaction, don't put it in the mempool
1576 if (ValidateStakeTransaction(tx, p, false))
1578 return state.DoS(0, error("AcceptToMemoryPool: attempt to add staking transaction to the mempool"),
1579 REJECT_INVALID, "staking");
1582 // is it already in the memory pool?
1583 uint256 hash = tx.GetHash();
1584 if (pool.exists(hash))
1586 //fprintf(stderr,"already in mempool\n");
1587 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
1590 // Check for conflicts with in-memory transactions
1592 LOCK(pool.cs); // protect pool.mapNextTx
1593 for (unsigned int i = 0; i < tx.vin.size(); i++)
1595 COutPoint outpoint = tx.vin[i].prevout;
1596 if (pool.mapNextTx.count(outpoint))
1598 // Disable replacement feature for now
1602 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1603 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
1604 if (pool.nullifierExists(nf, SPROUT)) {
1605 fprintf(stderr,"pool.mapNullifiers.count\n");
1610 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
1611 if (pool.nullifierExists(spendDescription.nullifier, SAPLING)) {
1619 CCoinsViewCache view(&dummy);
1621 CAmount nValueIn = 0;
1624 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1625 view.SetBackend(viewMemPool);
1627 // do we already have it?
1628 if (view.HaveCoins(hash))
1630 //fprintf(stderr,"view.HaveCoins(hash) error\n");
1631 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
1634 if (tx.IsCoinImport())
1636 // Inverse of normal case; if input exists, it's been spent
1637 if (ExistsImportTombstone(tx, view))
1638 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
1642 // do all inputs exist?
1643 // Note that this does not check for the presence of actual outputs (see the next check for that),
1644 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1645 BOOST_FOREACH(const CTxIn txin, tx.vin)
1647 if (!view.HaveCoins(txin.prevout.hash))
1649 if (pfMissingInputs)
1650 *pfMissingInputs = true;
1651 //fprintf(stderr,"missing inputs\n");
1652 return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
1656 // are the actual inputs available?
1657 if (!view.HaveInputs(tx))
1659 //fprintf(stderr,"accept failure.1\n");
1660 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1663 // are the joinsplit's requirements met?
1664 if (!view.HaveJoinSplitRequirements(tx))
1666 //fprintf(stderr,"accept failure.2\n");
1667 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1670 // Bring the best block into scope
1671 view.GetBestBlock();
1673 nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
1674 if ( 0 && interest != 0 )
1675 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1676 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1677 view.SetBackend(dummy);
1680 // Check for non-standard pay-to-script-hash in inputs
1681 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1682 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1684 // Check that the transaction doesn't have an excessive number of
1685 // sigops, making it impossible to mine. Since the coinbase transaction
1686 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1687 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1688 // merely non-standard transaction.
1689 unsigned int nSigOps = GetLegacySigOpCount(tx);
1690 nSigOps += GetP2SHSigOpCount(tx, view);
1691 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1693 fprintf(stderr,"accept failure.4\n");
1694 return state.DoS(1, error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
1697 CAmount nValueOut = tx.GetValueOut();
1698 CAmount nFees = nValueIn-nValueOut;
1699 double dPriority = view.GetPriority(tx, chainActive.Height());
1701 // Keep track of transactions that spend a coinbase, which we re-scan
1702 // during reorgs to ensure COINBASE_MATURITY is still met.
1703 bool fSpendsCoinbase = false;
1704 if (!tx.IsCoinImport()) {
1705 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1706 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1707 if (coins->IsCoinBase()) {
1708 fSpendsCoinbase = true;
1714 // Grab the branch ID we expect this transaction to commit to. We don't
1715 // yet know if it does, but if the entry gets added to the mempool, then
1716 // it has passed ContextualCheckInputs and therefore this is correct.
1717 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1719 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1720 unsigned int nSize = entry.GetTxSize();
1722 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1723 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1724 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1726 // Don't accept it if it can't get into a block
1727 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1728 if (fLimitFree && nFees < txMinFee)
1730 //fprintf(stderr,"accept failure.5\n");
1731 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1735 // Require that free transactions have sufficient priority to be mined in the next block.
1736 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1737 fprintf(stderr,"accept failure.6\n");
1738 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1741 // Continuously rate-limit free (really, very-low-fee) transactions
1742 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1743 // be annoying or make others' transactions take longer to confirm.
1744 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1746 static CCriticalSection csFreeLimiter;
1747 static double dFreeCount;
1748 static int64_t nLastTime;
1749 int64_t nNow = GetTime();
1751 LOCK(csFreeLimiter);
1753 // Use an exponentially decaying ~10-minute window:
1754 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1756 // -limitfreerelay unit is thousand-bytes-per-minute
1757 // At default rate it would take over a month to fill 1GB
1758 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1760 fprintf(stderr,"accept failure.7\n");
1761 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1763 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1764 dFreeCount += nSize;
1767 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
1769 string errmsg = strprintf("absurdly high fees %s, %d > %d",
1771 nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1772 LogPrint("mempool", errmsg.c_str());
1773 return state.Error("AcceptToMemoryPool: " + errmsg);
1776 // Check against previous transactions
1777 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1778 PrecomputedTransactionData txdata(tx);
1779 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1781 //fprintf(stderr,"accept failure.9\n");
1782 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1785 // Check again against just the consensus-critical mandatory script
1786 // verification flags, in case of bugs in the standard flags that cause
1787 // transactions to pass as valid when they're actually invalid. For
1788 // instance the STRICTENC flag was incorrectly allowing certain
1789 // CHECKSIG NOT scripts to pass, even though they were invalid.
1791 // There is a similar check in CreateNewBlock() to prevent creating
1792 // invalid blocks, however allowing such transactions into the mempool
1793 // can be exploited as a DoS attack.
1794 // XXX: is this neccesary for CryptoConditions?
1795 if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 )
1798 KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
1800 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1803 KOMODO_CONNECTING = -1;
1804 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1807 KOMODO_CONNECTING = -1;
1809 // Store transaction in memory
1810 if ( komodo_is_notarytx(tx) == 0 )
1812 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1814 if (!tx.IsCoinImport())
1816 // Add memory address index
1817 if (fAddressIndex) {
1818 pool.addAddressIndex(entry, view);
1821 // Add memory spent index
1823 pool.addSpentIndex(entry, view);
1828 SyncWithWallets(tx, NULL);
1833 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1835 if (!fTimestampIndex)
1836 return error("Timestamp index not enabled");
1838 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1839 return error("Unable to get hashes for timestamps");
1844 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1849 if (mempool.getSpentIndex(key, value))
1852 if (!pblocktree->ReadSpentIndex(key, value))
1858 bool GetAddressIndex(uint160 addressHash, int type,
1859 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1862 return error("address index not enabled");
1864 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1865 return error("unable to get txids for address");
1870 bool GetAddressUnspent(uint160 addressHash, int type,
1871 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1874 return error("address index not enabled");
1876 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1877 return error("unable to get txids for address");
1882 /*uint64_t myGettxout(uint256 hash,int32_t n)
1885 LOCK2(cs_main,mempool.cs);
1886 CCoinsViewMemPool view(pcoinsTip, mempool);
1887 if (!view.GetCoins(hash, coins))
1889 if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
1891 else return(coins.vout[n].nValue);
1894 bool myAddtomempool(CTransaction &tx, CValidationState *pstate)
1896 CValidationState state;
1899 CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
1900 if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
1901 return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
1905 bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1907 // need a GetTransaction without lock so the validation code for assets can run without deadlock
1909 //fprintf(stderr,"check mempool\n");
1910 if (mempool.lookup(hash, txOut))
1912 //fprintf(stderr,"found in mempool\n");
1916 //fprintf(stderr,"check disk\n");
1920 //fprintf(stderr,"ReadTxIndex\n");
1921 if (pblocktree->ReadTxIndex(hash, postx)) {
1922 //fprintf(stderr,"OpenBlockFile\n");
1923 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1925 return error("%s: OpenBlockFile failed", __func__);
1926 CBlockHeader header;
1927 //fprintf(stderr,"seek and read\n");
1930 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1932 } catch (const std::exception& e) {
1933 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1935 hashBlock = header.GetHash();
1936 if (txOut.GetHash() != hash)
1937 return error("%s: txid mismatch", __func__);
1938 //fprintf(stderr,"found on disk\n");
1942 //fprintf(stderr,"not found\n");
1946 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1947 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1949 CBlockIndex *pindexSlow = NULL;
1953 if (mempool.lookup(hash, txOut))
1960 if (pblocktree->ReadTxIndex(hash, postx)) {
1961 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1963 return error("%s: OpenBlockFile failed", __func__);
1964 CBlockHeader header;
1967 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1969 } catch (const std::exception& e) {
1970 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1972 hashBlock = header.GetHash();
1973 if (txOut.GetHash() != hash)
1974 return error("%s: txid mismatch", __func__);
1979 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1982 CCoinsViewCache &view = *pcoinsTip;
1983 const CCoins* coins = view.AccessCoins(hash);
1985 nHeight = coins->nHeight;
1988 pindexSlow = chainActive[nHeight];
1993 if (ReadBlockFromDisk(block, pindexSlow,1)) {
1994 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1995 if (tx.GetHash() == hash) {
1997 hashBlock = pindexSlow->GetBlockHash();
2007 /*char *komodo_getspendscript(uint256 hash,int32_t n)
2009 CTransaction tx; uint256 hashBlock;
2010 if ( !GetTransaction(hash,tx,hashBlock,true) )
2012 printf("null GetTransaction\n");
2015 if ( n >= 0 && n < tx.vout.size() )
2016 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
2017 else printf("getspendscript illegal n.%d\n",n);
2022 //////////////////////////////////////////////////////////////////////////////
2024 // CBlock and CBlockIndex
2027 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
2029 // Open history file to append
2030 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
2031 if (fileout.IsNull())
2032 return error("WriteBlockToDisk: OpenBlockFile failed");
2034 // Write index header
2035 unsigned int nSize = GetSerializeSize(fileout, block);
2036 fileout << FLATDATA(messageStart) << nSize;
2039 long fileOutPos = ftell(fileout.Get());
2041 return error("WriteBlockToDisk: ftell failed");
2042 pos.nPos = (unsigned int)fileOutPos;
2048 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
2050 uint8_t pubkey33[33];
2053 // Open history file to read
2054 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
2055 if (filein.IsNull())
2057 //fprintf(stderr,"readblockfromdisk err A\n");
2058 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
2065 catch (const std::exception& e) {
2066 fprintf(stderr,"readblockfromdisk err B\n");
2067 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
2070 if ( 0 && checkPOW != 0 )
2072 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
2073 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
2075 int32_t i; for (i=0; i<33; i++)
2076 fprintf(stderr,"%02x",pubkey33[i]);
2077 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
2079 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
2085 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
2089 if (!ReadBlockFromDisk(pindex->GetHeight(),block, pindex->GetBlockPos(),checkPOW))
2091 if (block.GetHash() != pindex->GetBlockHash())
2092 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
2093 pindex->ToString(), pindex->GetBlockPos().ToString());
2097 //uint64_t komodo_moneysupply(int32_t height);
2098 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
2099 extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
2100 extern uint32_t ASSETCHAINS_MAGIC;
2101 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
2102 extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
2104 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
2106 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
2107 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2110 return(100000000 * COIN); // ICO allocation
2111 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
2117 return(komodo_ac_block_subsidy(nHeight));
2120 // Mining slow start
2121 // The subsidy is ramped up linearly, skipping the middle payout of
2122 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
2123 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
2124 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2125 nSubsidy *= nHeight;
2127 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
2128 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2129 nSubsidy *= (nHeight+1);
2133 assert(nHeight > consensusParams.SubsidySlowStartShift());
2134 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
2135 // Force block reward to zero when right shift is undefined.
2136 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
2137 //if (halvings >= 64)
2140 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
2141 //nSubsidy >>= halvings;
2145 bool IsInitialBlockDownload()
2147 const CChainParams& chainParams = Params();
2149 // Once this function has returned false, it must remain false.
2150 static std::atomic<bool> latchToFalse{false};
2151 // Optimization: pre-test latch before taking the lock.
2152 if (latchToFalse.load(std::memory_order_relaxed))
2156 if (latchToFalse.load(std::memory_order_relaxed))
2159 if (fImporting || fReindex)
2161 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2165 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2167 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload - %d blocks\n", Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2172 arith_uint256 bigZero = arith_uint256();
2173 arith_uint256 minWork = UintToArith256(chainParams.GetConsensus().nMinimumChainWork);
2174 CBlockIndex *ptr = chainActive.Tip();
2178 if (ptr->chainPower < CChainPower(ptr, bigZero, minWork))
2181 state = ((chainActive.Height() < ptr->GetHeight() - 24*60) ||
2182 ptr->GetBlockTime() < (GetTime() - nMaxTipAge));
2184 //fprintf(stderr,"state.%d ht.%d vs %d, t.%u %u\n",state,(int32_t)chainActive.Height(),(uint32_t)ptr->GetHeight(),(int32_t)ptr->GetBlockTime(),(uint32_t)(GetTime() - chainParams.MaxTipAge()));
2187 LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
2188 latchToFalse.store(true, std::memory_order_relaxed);
2193 // determine if we are in sync with the best chain
2196 const CChainParams& chainParams = Params();
2199 if (fImporting || fReindex)
2201 //fprintf(stderr,"IsNotInSync: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2204 if (fCheckpointsEnabled)
2206 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2208 //fprintf(stderr,"IsNotInSync: checkpoint -> initialdownload chainActive.Height().%d GetTotalBlocksEstimate(chainParams.Checkpoints().%d\n", chainActive.Height(), Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2213 CBlockIndex *pbi = chainActive.Tip();
2214 int longestchain = komodo_longestchain();
2216 (pindexBestHeader == 0) ||
2217 ((pindexBestHeader->GetHeight() - 1) > pbi->GetHeight()) ||
2218 (longestchain != 0 && longestchain > pbi->GetHeight()) )
2220 return (pbi && pindexBestHeader && (pindexBestHeader->GetHeight() - 1) > pbi->GetHeight()) ?
2221 pindexBestHeader->GetHeight() - pbi->GetHeight() :
2228 static bool fLargeWorkForkFound = false;
2229 static bool fLargeWorkInvalidChainFound = false;
2230 static CBlockIndex *pindexBestForkTip = NULL;
2231 static CBlockIndex *pindexBestForkBase = NULL;
2233 void CheckForkWarningConditions()
2235 AssertLockHeld(cs_main);
2236 // Before we get past initial download, we cannot reliably alert about forks
2237 // (we assume we don't get stuck on a fork before finishing our initial sync)
2238 if (IsInitialBlockDownload())
2241 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
2242 // of our head, drop it
2243 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->GetHeight() >= 288)
2244 pindexBestForkTip = NULL;
2246 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->chainPower > (chainActive.LastTip()->chainPower + (GetBlockProof(*chainActive.LastTip()) * 6))))
2248 if (!fLargeWorkForkFound && pindexBestForkBase)
2250 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
2251 pindexBestForkBase->phashBlock->ToString() + std::string("'");
2252 CAlert::Notify(warning, true);
2254 if (pindexBestForkTip && pindexBestForkBase)
2256 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__,
2257 pindexBestForkBase->GetHeight(), pindexBestForkBase->phashBlock->ToString(),
2258 pindexBestForkTip->GetHeight(), pindexBestForkTip->phashBlock->ToString());
2259 fLargeWorkForkFound = true;
2263 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
2264 LogPrintf("%s: %s\n", warning.c_str(), __func__);
2265 CAlert::Notify(warning, true);
2266 fLargeWorkInvalidChainFound = true;
2271 fLargeWorkForkFound = false;
2272 fLargeWorkInvalidChainFound = false;
2276 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
2278 AssertLockHeld(cs_main);
2279 // If we are on a fork that is sufficiently large, set a warning flag
2280 CBlockIndex* pfork = pindexNewForkTip;
2281 CBlockIndex* plonger = chainActive.LastTip();
2282 while (pfork && pfork != plonger)
2284 while (plonger && plonger->GetHeight() > pfork->GetHeight())
2285 plonger = plonger->pprev;
2286 if (pfork == plonger)
2288 pfork = pfork->pprev;
2291 // We define a condition where we should warn the user about as a fork of at least 7 blocks
2292 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
2293 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
2294 // hash rate operating on the fork.
2295 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
2296 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
2297 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
2298 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->GetHeight() > pindexBestForkTip->GetHeight())) &&
2299 pindexNewForkTip->chainPower - pfork->chainPower > (GetBlockProof(*pfork) * 7) &&
2300 chainActive.Height() - pindexNewForkTip->GetHeight() < 72)
2302 pindexBestForkTip = pindexNewForkTip;
2303 pindexBestForkBase = pfork;
2306 CheckForkWarningConditions();
2309 // Requires cs_main.
2310 void Misbehaving(NodeId pnode, int howmuch)
2315 CNodeState *state = State(pnode);
2319 state->nMisbehavior += howmuch;
2320 int banscore = GetArg("-banscore", 101);
2321 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
2323 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2324 state->fShouldBan = true;
2326 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2329 void static InvalidChainFound(CBlockIndex* pindexNew)
2331 if (!pindexBestInvalid || pindexNew->chainPower > pindexBestInvalid->chainPower)
2332 pindexBestInvalid = pindexNew;
2334 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2335 pindexNew->GetBlockHash().ToString(), pindexNew->GetHeight(),
2336 log(pindexNew->chainPower.chainWork.getdouble())/log(2.0),
2337 log(pindexNew->chainPower.chainStake.getdouble())/log(2.0),
2338 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()));
2339 CBlockIndex *tip = chainActive.LastTip();
2341 LogPrintf("%s: current best=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2342 tip->GetBlockHash().ToString(), chainActive.Height(),
2343 log(tip->chainPower.chainWork.getdouble())/log(2.0),
2344 log(tip->chainPower.chainStake.getdouble())/log(2.0),
2345 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
2346 CheckForkWarningConditions();
2349 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2351 if (state.IsInvalid(nDoS)) {
2352 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2353 if (it != mapBlockSource.end() && State(it->second)) {
2354 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
2355 State(it->second)->rejects.push_back(reject);
2357 Misbehaving(it->second, nDoS);
2360 if (!state.CorruptionPossible()) {
2361 pindex->nStatus |= BLOCK_FAILED_VALID;
2362 setDirtyBlockIndex.insert(pindex);
2363 setBlockIndexCandidates.erase(pindex);
2364 InvalidChainFound(pindex);
2368 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
2370 if (!tx.IsMint()) // mark inputs spent
2372 txundo.vprevout.reserve(tx.vin.size());
2373 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
2374 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2375 unsigned nPos = txin.prevout.n;
2377 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2379 // mark an outpoint spent, and construct undo information
2380 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2382 if (coins->vout.size() == 0) {
2383 CTxInUndo& undo = txundo.vprevout.back();
2384 undo.nHeight = coins->nHeight;
2385 undo.fCoinBase = coins->fCoinBase;
2386 undo.nVersion = coins->nVersion;
2392 inputs.SetNullifiers(tx, true);
2394 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2397 if (tx.IsCoinImport()) {
2398 // add a tombstone for the burnTx
2399 AddImportTombstone(tx, inputs, nHeight);
2403 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2406 UpdateCoins(tx, inputs, txundo, nHeight);
2409 bool CScriptCheck::operator()() {
2410 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2411 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2412 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
2413 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2418 int GetSpendHeight(const CCoinsViewCache& inputs)
2421 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2422 return pindexPrev->GetHeight() + 1;
2425 namespace Consensus {
2426 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2428 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2429 // for an attacker to attempt to split the network.
2430 if (!inputs.HaveInputs(tx))
2431 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2433 // are the JoinSplit's requirements met?
2434 if (!inputs.HaveJoinSplitRequirements(tx))
2435 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2437 CAmount nValueIn = 0;
2439 for (unsigned int i = 0; i < tx.vin.size(); i++)
2441 const COutPoint &prevout = tx.vin[i].prevout;
2442 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2445 if (coins->IsCoinBase()) {
2446 // ensure that output of coinbases are not still time locked
2447 if (coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE)
2449 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2450 if (nSpendHeight < unlockTime) {
2451 return state.DoS(10,
2452 error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2453 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2457 // Ensure that coinbases are matured, no DoS as retry may work later
2458 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2460 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2461 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2464 // Ensure that coinbases cannot be spent to transparent outputs
2465 // Disabled on regtest
2466 if (fCoinbaseEnforcedProtectionEnabled &&
2467 consensusParams.fCoinbaseMustBeProtected &&
2468 !(tx.vout.size() == 0 || (tx.vout.size() == 1 && tx.vout[0].nValue == 0)) &&
2469 (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
2470 return state.DoS(100,
2471 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2472 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2476 // Check for negative or overflow input values
2477 nValueIn += coins->vout[prevout.n].nValue;
2478 #ifdef KOMODO_ENABLE_INTEREST
2479 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() >= 60000 )
2481 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2483 int64_t interest; int32_t txheight; uint32_t locktime;
2484 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2486 //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);
2487 nValueIn += interest;
2492 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2493 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2494 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2498 nValueIn += tx.GetShieldedValueIn();
2499 if (!MoneyRange(nValueIn))
2500 return state.DoS(100, error("CheckInputs(): shielded input to transparent value pool out of range"),
2501 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2503 if (nValueIn < tx.GetValueOut())
2505 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2506 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2507 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2509 // Tally transaction fees
2510 CAmount nTxFee = nValueIn - tx.GetValueOut();
2512 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2513 REJECT_INVALID, "bad-txns-fee-negative");
2515 if (!MoneyRange(nFees))
2516 return state.DoS(100, error("CheckInputs(): nFees out of range"),
2517 REJECT_INVALID, "bad-txns-fee-outofrange");
2520 }// namespace Consensus
2522 bool ContextualCheckInputs(
2523 const CTransaction& tx,
2524 CValidationState &state,
2525 const CCoinsViewCache &inputs,
2529 PrecomputedTransactionData& txdata,
2530 const Consensus::Params& consensusParams,
2531 uint32_t consensusBranchId,
2532 std::vector<CScriptCheck> *pvChecks)
2536 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2541 pvChecks->reserve(tx.vin.size());
2543 // The first loop above does all the inexpensive checks.
2544 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2545 // Helps prevent CPU exhaustion attacks.
2547 // Skip ECDSA signature verification when connecting blocks
2548 // before the last block chain checkpoint. This is safe because block merkle hashes are
2549 // still computed and checked, and any change will be caught at the next checkpoint.
2550 if (fScriptChecks) {
2551 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2552 const COutPoint &prevout = tx.vin[i].prevout;
2553 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2557 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2559 pvChecks->push_back(CScriptCheck());
2560 check.swap(pvChecks->back());
2561 } else if (!check()) {
2562 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2563 // Check whether the failure was caused by a
2564 // non-mandatory script verification check, such as
2565 // non-standard DER encodings or non-null dummy
2566 // arguments; if so, don't trigger DoS protection to
2567 // avoid splitting the network between upgraded and
2568 // non-upgraded nodes.
2569 CScriptCheck check2(*coins, tx, i,
2570 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2572 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2574 // Failures of other flags indicate a transaction that is
2575 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2576 // such nodes as they are not following the protocol. That
2577 // said during an upgrade careful thought should be taken
2578 // as to the correct behavior - we may want to continue
2579 // peering with non-upgraded nodes even after a soft-fork
2580 // super-majority vote has passed.
2581 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2587 if (tx.IsCoinImport())
2589 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2590 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2597 /*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)
2599 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2600 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2604 if (!tx.IsCoinBase())
2606 // While checking, GetBestBlock() refers to the parent block.
2607 // This is also true for mempool checks.
2608 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2609 int nSpendHeight = pindexPrev->GetHeight() + 1;
2610 for (unsigned int i = 0; i < tx.vin.size(); i++)
2612 const COutPoint &prevout = tx.vin[i].prevout;
2613 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2614 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2618 // If prev is coinbase, check that it's matured
2619 if (coins->IsCoinBase()) {
2620 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2621 COINBASE_MATURITY = _COINBASE_MATURITY;
2622 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2623 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2625 return state.Invalid(
2626 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2637 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2639 // Open history file to append
2640 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2641 if (fileout.IsNull())
2642 return error("%s: OpenUndoFile failed", __func__);
2644 // Write index header
2645 unsigned int nSize = GetSerializeSize(fileout, blockundo);
2646 fileout << FLATDATA(messageStart) << nSize;
2649 long fileOutPos = ftell(fileout.Get());
2651 return error("%s: ftell failed", __func__);
2652 pos.nPos = (unsigned int)fileOutPos;
2653 fileout << blockundo;
2655 // calculate & write checksum
2656 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2657 hasher << hashBlock;
2658 hasher << blockundo;
2659 fileout << hasher.GetHash();
2664 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2666 // Open history file to read
2667 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2668 if (filein.IsNull())
2669 return error("%s: OpenBlockFile failed", __func__);
2672 uint256 hashChecksum;
2674 filein >> blockundo;
2675 filein >> hashChecksum;
2677 catch (const std::exception& e) {
2678 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2681 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2682 hasher << hashBlock;
2683 hasher << blockundo;
2684 if (hashChecksum != hasher.GetHash())
2685 return error("%s: Checksum mismatch", __func__);
2690 /** Abort with a message */
2691 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2693 strMiscWarning = strMessage;
2694 LogPrintf("*** %s\n", strMessage);
2695 uiInterface.ThreadSafeMessageBox(
2696 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2697 "", CClientUIInterface::MSG_ERROR);
2702 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2704 AbortNode(strMessage, userMessage);
2705 return state.Error(strMessage);
2711 * Apply the undo operation of a CTxInUndo to the given chain state.
2712 * @param undo The undo object.
2713 * @param view The coins view to which to apply the changes.
2714 * @param out The out point that corresponds to the tx input.
2715 * @return True on success.
2717 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2721 CCoinsModifier coins = view.ModifyCoins(out.hash);
2722 if (undo.nHeight != 0) {
2723 // undo data contains height: this is the last output of the prevout tx being spent
2724 if (!coins->IsPruned())
2725 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2727 coins->fCoinBase = undo.fCoinBase;
2728 coins->nHeight = undo.nHeight;
2729 coins->nVersion = undo.nVersion;
2731 if (coins->IsPruned())
2732 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2734 if (coins->IsAvailable(out.n))
2735 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2736 if (coins->vout.size() < out.n+1)
2737 coins->vout.resize(out.n+1);
2738 coins->vout[out.n] = undo.txout;
2744 void ConnectNotarisations(const CBlock &block, int height)
2746 // Record Notarisations
2747 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2748 if (notarisations.size() > 0) {
2749 CDBBatch batch = CDBBatch(*pnotarisations);
2750 batch.Write(block.GetHash(), notarisations);
2751 WriteBackNotarisations(notarisations, batch);
2752 pnotarisations->WriteBatch(batch, true);
2753 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2754 notarisations.size(), block.GetHash().GetHex().data());
2759 void DisconnectNotarisations(const CBlock &block)
2761 // Delete from notarisations cache
2762 NotarisationsInBlock nibs;
2763 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2764 CDBBatch batch = CDBBatch(*pnotarisations);
2765 batch.Erase(block.GetHash());
2766 EraseBackNotarisations(nibs, batch);
2767 pnotarisations->WriteBatch(batch, true);
2768 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2769 nibs.size(), block.GetHash().GetHex().data());
2774 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2776 assert(pindex->GetBlockHash() == view.GetBestBlock());
2782 komodo_disconnect(pindex,block);
2783 CBlockUndo blockUndo;
2784 CDiskBlockPos pos = pindex->GetUndoPos();
2786 return error("DisconnectBlock(): no undo data available");
2787 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2788 return error("DisconnectBlock(): failure reading undo data");
2790 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2791 return error("DisconnectBlock(): block and undo data inconsistent");
2792 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2793 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2794 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2796 // undo transactions in reverse order
2797 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2798 const CTransaction &tx = block.vtx[i];
2799 uint256 hash = tx.GetHash();
2800 if (fAddressIndex) {
2802 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2803 const CTxOut &out = tx.vout[k];
2805 if (out.scriptPubKey.IsPayToScriptHash()) {
2806 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2808 // undo receiving activity
2809 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2811 // undo unspent index
2812 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2815 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2816 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2818 // undo receiving activity
2819 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2821 // undo unspent index
2822 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2825 else if (out.scriptPubKey.IsPayToPublicKey()) {
2826 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2828 // undo receiving activity
2829 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2831 // undo unspent index
2832 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2835 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2836 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2838 // undo receiving activity
2839 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2841 // undo unspent index
2842 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2853 // Check that all outputs are available and match the outputs in the block itself
2856 CCoinsModifier outs = view.ModifyCoins(hash);
2857 outs->ClearUnspendable();
2859 CCoins outsBlock(tx, pindex->GetHeight());
2860 // The CCoins serialization does not serialize negative numbers.
2861 // No network rules currently depend on the version here, so an inconsistency is harmless
2862 // but it must be corrected before txout nversion ever influences a network rule.
2863 if (outsBlock.nVersion < 0)
2864 outs->nVersion = outsBlock.nVersion;
2865 if (*outs != outsBlock)
2866 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2872 // unspend nullifiers
2873 view.SetNullifiers(tx, false);
2877 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2878 if (txundo.vprevout.size() != tx.vin.size())
2879 return error("DisconnectBlock(): transaction and undo data inconsistent");
2880 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2881 const COutPoint &out = tx.vin[j].prevout;
2882 const CTxInUndo &undo = txundo.vprevout[j];
2883 if (!ApplyTxInUndo(undo, view, out))
2886 const CTxIn input = tx.vin[j];
2889 // undo and delete the spent index
2890 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2893 if (fAddressIndex) {
2894 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2895 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2896 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2898 // undo spending activity
2899 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2901 // restore unspent index
2902 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2906 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2907 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2909 // undo spending activity
2910 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2912 // restore unspent index
2913 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2916 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2917 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2919 // undo spending activity
2920 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2922 // restore unspent index
2923 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2926 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2927 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2929 // undo spending activity
2930 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2932 // restore unspent index
2933 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2942 else if (tx.IsCoinImport())
2944 RemoveImportTombstone(tx, view);
2948 // set the old best Sprout anchor back
2949 view.PopAnchor(blockUndo.old_sprout_tree_root, SPROUT);
2951 // set the old best Sapling anchor back
2952 // We can get this from the `hashFinalSaplingRoot` of the last block
2953 // However, this is only reliable if the last block was on or after
2954 // the Sapling activation height. Otherwise, the last anchor was the
2956 if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2957 view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING);
2959 view.PopAnchor(SaplingMerkleTree::empty_root(), SAPLING);
2962 // move best block pointer to prevout block
2963 view.SetBestBlock(pindex->pprev->GetBlockHash());
2970 if (fAddressIndex) {
2971 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2972 return AbortNode(state, "Failed to delete address index");
2974 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2975 return AbortNode(state, "Failed to write address unspent index");
2982 void static FlushBlockFile(bool fFinalize = false)
2984 LOCK(cs_LastBlockFile);
2986 CDiskBlockPos posOld(nLastBlockFile, 0);
2988 FILE *fileOld = OpenBlockFile(posOld);
2991 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2992 FileCommit(fileOld);
2996 fileOld = OpenUndoFile(posOld);
2999 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
3000 FileCommit(fileOld);
3005 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
3007 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
3009 void ThreadScriptCheck() {
3010 RenameThread("zcash-scriptch");
3011 scriptcheckqueue.Thread();
3015 // Called periodically asynchronously; alerts if it smells like
3016 // we're being fed a bad chain (blocks being generated much
3017 // too slowly or too quickly).
3019 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
3020 int64_t nPowTargetSpacing)
3022 if (bestHeader == NULL || initialDownloadCheck()) return;
3024 static int64_t lastAlertTime = 0;
3025 int64_t now = GetAdjustedTime();
3026 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
3028 const int SPAN_HOURS=4;
3029 const int SPAN_SECONDS=SPAN_HOURS*60*60;
3030 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
3032 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
3034 std::string strWarning;
3035 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
3038 const CBlockIndex* i = bestHeader;
3040 while (i->GetBlockTime() >= startTime) {
3043 if (i == NULL) return; // Ran out of chain, we must not be fully synced
3046 // How likely is it to find that many by chance?
3047 double p = boost::math::pdf(poisson, nBlocks);
3049 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
3050 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
3052 // Aim for one false-positive about every fifty years of normal running:
3053 const int FIFTY_YEARS = 50*365*24*60*60;
3054 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
3056 if (bestHeader->GetHeight() > BLOCKS_EXPECTED)
3058 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
3060 // Many fewer blocks than expected: alert!
3061 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
3062 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3064 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
3066 // Many more blocks than expected: alert!
3067 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
3068 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3071 if (!strWarning.empty())
3073 strMiscWarning = strWarning;
3074 CAlert::Notify(strWarning, true);
3075 lastAlertTime = now;
3080 static int64_t nTimeVerify = 0;
3081 static int64_t nTimeConnect = 0;
3082 static int64_t nTimeIndex = 0;
3083 static int64_t nTimeCallbacks = 0;
3084 static int64_t nTimeTotal = 0;
3086 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
3088 const CChainParams& chainparams = Params();
3089 if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT )
3091 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
3092 AssertLockHeld(cs_main);
3093 bool fExpensiveChecks = true;
3094 if (fCheckpointsEnabled) {
3095 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
3096 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->GetHeight()) == pindex) {
3097 // This block is an ancestor of a checkpoint: disable script checks
3098 fExpensiveChecks = false;
3101 auto verifier = libzcash::ProofVerifier::Strict();
3102 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
3103 int32_t futureblock;
3104 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
3105 if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
3107 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
3111 // verify that the view's current state corresponds to the previous block
3112 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
3113 if ( hashPrevBlock != view.GetBestBlock() )
3115 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
3116 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
3117 REJECT_INVALID, "hashPrevBlock-not-bestblock");
3119 assert(hashPrevBlock == view.GetBestBlock());
3121 // Special case for the genesis block, skipping connection of its transactions
3122 // (its coinbase is unspendable)
3123 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
3125 view.SetBestBlock(pindex->GetBlockHash());
3126 // Before the genesis block, there was an empty tree
3127 SproutMerkleTree tree;
3128 pindex->hashSproutAnchor = tree.root();
3129 // The genesis block contained no JoinSplits
3130 pindex->hashFinalSproutRoot = pindex->hashSproutAnchor;
3135 bool fScriptChecks = (!fCheckpointsEnabled || pindex->GetHeight() >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
3136 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->GetHeight() > KOMODO_TESTNET_EXPIRATION ) // "testnet"
3138 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
3139 // unless those are already completely spent.
3140 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
3141 const CCoins* coins = view.AccessCoins(tx.GetHash());
3142 if (coins && !coins->IsPruned())
3143 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
3144 REJECT_INVALID, "bad-txns-BIP30");
3147 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
3149 // DERSIG (BIP66) is also always enforced, but does not have a flag.
3151 CBlockUndo blockundo;
3153 if ( ASSETCHAINS_CC != 0 )
3155 if ( scriptcheckqueue.IsIdle() == 0 )
3157 fprintf(stderr,"scriptcheckqueue isnt idle\n");
3161 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
3163 int64_t nTimeStart = GetTimeMicros();
3166 int64_t interest,sum = 0;
3167 unsigned int nSigOps = 0;
3168 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
3169 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
3170 vPos.reserve(block.vtx.size());
3171 blockundo.vtxundo.reserve(block.vtx.size() - 1);
3172 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
3173 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
3174 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
3175 // Construct the incremental merkle tree at the current
3177 auto old_sprout_tree_root = view.GetBestAnchor(SPROUT);
3178 // saving the top anchor in the block index as we go.
3180 pindex->hashSproutAnchor = old_sprout_tree_root;
3183 SproutMerkleTree sprout_tree;
3185 // This should never fail: we should always be able to get the root
3186 // that is on the tip of our chain
3187 assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
3190 // Consistency check: the root of the tree we're given should
3191 // match what we asked for.
3192 assert(sprout_tree.root() == old_sprout_tree_root);
3195 SaplingMerkleTree sapling_tree;
3196 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
3198 // Grab the consensus branch ID for the block's height
3199 auto consensusBranchId = CurrentEpochBranchId(pindex->GetHeight(), Params().GetConsensus());
3201 std::vector<PrecomputedTransactionData> txdata;
3202 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
3203 for (unsigned int i = 0; i < block.vtx.size(); i++)
3205 const CTransaction &tx = block.vtx[i];
3206 const uint256 txhash = tx.GetHash();
3207 nInputs += tx.vin.size();
3208 nSigOps += GetLegacySigOpCount(tx);
3209 if (nSigOps > MAX_BLOCK_SIGOPS)
3210 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3211 REJECT_INVALID, "bad-blk-sigops");
3212 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->GetHeight(),tx.nLockTime);
3215 if (!view.HaveInputs(tx))
3217 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
3218 REJECT_INVALID, "bad-txns-inputs-missingorspent");
3220 // are the JoinSplit's requirements met?
3221 if (!view.HaveJoinSplitRequirements(tx))
3222 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
3223 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
3224 if (fAddressIndex || fSpentIndex)
3226 for (size_t j = 0; j < tx.vin.size(); j++) {
3228 const CTxIn input = tx.vin[j];
3229 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
3233 if (prevout.scriptPubKey.IsPayToScriptHash()) {
3234 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
3237 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
3238 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
3241 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
3242 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
3245 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
3246 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
3250 hashBytes.SetNull();
3254 if (fAddressIndex && addressType > 0) {
3255 // record spending activity
3256 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->GetHeight(), i, txhash, j, true), prevout.nValue * -1));
3258 // remove address from unspent index
3259 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
3263 // add the spent index to determine the txid and input that spent an output
3264 // and to find the amount and address from an input
3265 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->GetHeight(), prevout.nValue, addressType, hashBytes)));
3270 // Add in sigops done by pay-to-script-hash inputs;
3271 // this is to prevent a "rogue miner" from creating
3272 // an incredibly-expensive-to-validate block.
3273 nSigOps += GetP2SHSigOpCount(tx, view);
3274 if (nSigOps > MAX_BLOCK_SIGOPS)
3275 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3276 REJECT_INVALID, "bad-blk-sigops");
3279 txdata.emplace_back(tx);
3281 if (!tx.IsCoinBase())
3283 nFees += view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
3286 std::vector<CScriptCheck> vChecks;
3287 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
3289 control.Add(vChecks);
3292 if (fAddressIndex) {
3293 for (unsigned int k = 0; k < tx.vout.size(); k++) {
3294 const CTxOut &out = tx.vout[k];
3295 //fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
3296 if (out.scriptPubKey.IsPayToScriptHash()) {
3297 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
3299 // record receiving activity
3300 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3302 // record unspent output
3303 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3306 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
3307 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
3309 // record receiving activity
3310 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3312 // record unspent output
3313 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3316 else if (out.scriptPubKey.IsPayToPublicKey()) {
3317 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
3319 // record receiving activity
3320 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3322 // record unspent output
3323 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3326 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
3327 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
3329 // record receiving activity
3330 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3332 // record unspent output
3333 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3343 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3344 // komodo_earned_interest(pindex->GetHeight(),sum);
3347 blockundo.vtxundo.push_back(CTxUndo());
3349 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight());
3351 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
3352 BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
3353 // Insert the note commitments into our temporary tree.
3355 sprout_tree.append(note_commitment);
3359 BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) {
3360 sapling_tree.append(outputDescription.cm);
3363 vPos.push_back(std::make_pair(tx.GetHash(), pos));
3364 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
3367 view.PushAnchor(sprout_tree);
3368 view.PushAnchor(sapling_tree);
3370 pindex->hashFinalSproutRoot = sprout_tree.root();
3372 blockundo.old_sprout_tree_root = old_sprout_tree_root;
3374 // If Sapling is active, block.hashFinalSaplingRoot must be the
3375 // same as the root of the Sapling tree
3376 if (NetworkUpgradeActive(pindex->GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3377 if (block.hashFinalSaplingRoot != sapling_tree.root()) {
3378 return state.DoS(100,
3379 error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"),
3380 REJECT_INVALID, "bad-sapling-root-in-block");
3383 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3384 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);
3386 CAmount blockReward = nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum;
3387 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
3389 uint64_t checktoshis;
3390 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
3392 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
3393 blockReward += checktoshis;
3394 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
3397 if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward)
3399 return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
3400 REJECT_INVALID, "bad-cb-amount");
3402 if ( block.vtx[0].GetValueOut() > blockReward+1 )
3404 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->GetHeight() >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
3406 return state.DoS(100,
3407 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3408 block.vtx[0].GetValueOut(), blockReward),
3409 REJECT_INVALID, "bad-cb-amount");
3410 } else if ( IS_KOMODO_NOTARY != 0 )
3411 fprintf(stderr,"allow nHeight.%d coinbase %.8f vs %.8f interest %.8f\n",(int32_t)pindex->GetHeight(),dstr(block.vtx[0].GetValueOut()),dstr(blockReward),dstr(sum));
3413 if (!control.Wait())
3414 return state.DoS(100, false);
3415 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3416 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);
3421 // Write undo information to disk
3422 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
3424 if (pindex->GetUndoPos().IsNull()) {
3426 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
3427 return error("ConnectBlock(): FindUndoPos failed");
3428 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
3429 return AbortNode(state, "Failed to write undo data");
3431 // update nUndoPos in block index
3432 pindex->nUndoPos = pos.nPos;
3433 pindex->nStatus |= BLOCK_HAVE_UNDO;
3436 // Now that all consensus rules have been validated, set nCachedBranchId.
3437 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3438 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
3439 "nCachedBranchId must be set after all consensus rules have been validated.");
3440 if (IsActivationHeightForAnyUpgrade(pindex->GetHeight(), Params().GetConsensus())) {
3441 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
3442 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->GetHeight(), chainparams.GetConsensus());
3443 } else if (pindex->pprev) {
3444 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
3447 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
3448 setDirtyBlockIndex.insert(pindex);
3451 ConnectNotarisations(block, pindex->GetHeight());
3454 if (!pblocktree->WriteTxIndex(vPos))
3455 return AbortNode(state, "Failed to write transaction index");
3456 if (fAddressIndex) {
3457 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3458 return AbortNode(state, "Failed to write address index");
3461 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3462 return AbortNode(state, "Failed to write address unspent index");
3467 if (!pblocktree->UpdateSpentIndex(spentIndex))
3468 return AbortNode(state, "Failed to write transaction index");
3470 if (fTimestampIndex) {
3471 unsigned int logicalTS = pindex->nTime;
3472 unsigned int prevLogicalTS = 0;
3474 // retrieve logical timestamp of the previous block
3476 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3477 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3479 if (logicalTS <= prevLogicalTS) {
3480 logicalTS = prevLogicalTS + 1;
3481 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3484 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3485 return AbortNode(state, "Failed to write timestamp index");
3487 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3488 return AbortNode(state, "Failed to write blockhash index");
3491 // add this block to the view's block chain
3492 view.SetBestBlock(pindex->GetBlockHash());
3494 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3495 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
3497 // Watch for changes to the previous coinbase transaction.
3498 static uint256 hashPrevBestCoinBase;
3499 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
3500 hashPrevBestCoinBase = block.vtx[0].GetHash();
3502 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3503 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
3505 //FlushStateToDisk();
3506 komodo_connectblock(pindex,*(CBlock *)&block);
3510 enum FlushStateMode {
3512 FLUSH_STATE_IF_NEEDED,
3513 FLUSH_STATE_PERIODIC,
3518 * Update the on-disk chain state.
3519 * The caches and indexes are flushed depending on the mode we're called with
3520 * if they're too large, if it's been a while since the last write,
3521 * or always and in all cases if we're in prune mode and are deleting files.
3523 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
3524 LOCK2(cs_main, cs_LastBlockFile);
3525 static int64_t nLastWrite = 0;
3526 static int64_t nLastFlush = 0;
3527 static int64_t nLastSetChain = 0;
3528 std::set<int> setFilesToPrune;
3529 bool fFlushForPrune = false;
3531 if (fPruneMode && fCheckForPruning && !fReindex) {
3532 FindFilesToPrune(setFilesToPrune);
3533 fCheckForPruning = false;
3534 if (!setFilesToPrune.empty()) {
3535 fFlushForPrune = true;
3537 pblocktree->WriteFlag("prunedblockfiles", true);
3542 int64_t nNow = GetTimeMicros();
3543 // Avoid writing/flushing immediately after startup.
3544 if (nLastWrite == 0) {
3547 if (nLastFlush == 0) {
3550 if (nLastSetChain == 0) {
3551 nLastSetChain = nNow;
3553 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3554 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3555 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3556 // The cache is over the limit, we have to write now.
3557 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3558 // 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.
3559 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3560 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3561 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3562 // Combine all conditions that result in a full cache flush.
3563 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3564 // Write blocks and block index to disk.
3565 if (fDoFullFlush || fPeriodicWrite) {
3566 // Depend on nMinDiskSpace to ensure we can write block index
3567 if (!CheckDiskSpace(0))
3568 return state.Error("out of disk space");
3569 // First make sure all block and undo data is flushed to disk.
3571 // Then update all block file information (which may refer to block and undo files).
3573 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3574 vFiles.reserve(setDirtyFileInfo.size());
3575 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3576 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3577 setDirtyFileInfo.erase(it++);
3579 std::vector<const CBlockIndex*> vBlocks;
3580 vBlocks.reserve(setDirtyBlockIndex.size());
3581 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3582 vBlocks.push_back(*it);
3583 setDirtyBlockIndex.erase(it++);
3585 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3586 return AbortNode(state, "Files to write to block index database");
3589 // Finally remove any pruned files
3591 UnlinkPrunedFiles(setFilesToPrune);
3594 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3596 // Typical CCoins structures on disk are around 128 bytes in size.
3597 // Pushing a new one to the database can cause it to be written
3598 // twice (once in the log, and once in the tables). This is already
3599 // an overestimation, as most will delete an existing entry or
3600 // overwrite one. Still, use a conservative safety factor of 2.
3601 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3602 return state.Error("out of disk space");
3603 // Flush the chainstate (which may refer to block index entries).
3604 if (!pcoinsTip->Flush())
3605 return AbortNode(state, "Failed to write to coin database");
3608 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3609 // Update best block in wallet (so we can detect restored wallets).
3610 GetMainSignals().SetBestChain(chainActive.GetLocator());
3611 nLastSetChain = nNow;
3613 } catch (const std::runtime_error& e) {
3614 return AbortNode(state, std::string("System error while flushing: ") + e.what());
3619 void FlushStateToDisk() {
3620 CValidationState state;
3621 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3624 void PruneAndFlush() {
3625 CValidationState state;
3626 fCheckForPruning = true;
3627 FlushStateToDisk(state, FLUSH_STATE_NONE);
3630 /** Update chainActive and related internal data structures. */
3631 void static UpdateTip(CBlockIndex *pindexNew) {
3632 const CChainParams& chainParams = Params();
3633 chainActive.SetTip(pindexNew);
3636 nTimeBestReceived = GetTime();
3637 mempool.AddTransactionsUpdated(1);
3640 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
3641 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
3643 int32_t longestchain = komodo_longestchain();
3644 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
3647 LogPrintf("%s: new best=%s height=%d log2_work=%.8g log2_stake=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
3648 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3649 log(chainActive.Tip()->chainPower.chainWork.getdouble())/log(2.0),
3650 log(chainActive.Tip()->chainPower.chainStake.getdouble())/log(2.0),
3651 (unsigned long)chainActive.LastTip()->nChainTx,
3652 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
3653 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3655 cvBlockChange.notify_all();
3657 // Check the version of the last 100 blocks to see if we need to upgrade:
3658 static bool fWarned = false;
3659 if (!IsInitialBlockDownload() && !fWarned)
3662 const CBlockIndex* pindex = chainActive.Tip();
3663 for (int i = 0; i < 100 && pindex != NULL; i++)
3665 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3667 pindex = pindex->pprev;
3670 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3671 if (nUpgraded > 100/2)
3673 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3674 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3675 CAlert::Notify(strMiscWarning, true);
3682 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3683 * mempool.removeWithoutBranchId after this, with cs_main held.
3685 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3686 CBlockIndex *pindexDelete = chainActive.Tip();
3687 assert(pindexDelete);
3688 // Read block from disk.
3690 if (!ReadBlockFromDisk(block, pindexDelete,1))
3691 return AbortNode(state, "Failed to read block");
3692 // Apply the block atomically to the chain state.
3693 uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3694 uint256 saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3695 int64_t nStart = GetTimeMicros();
3697 CCoinsViewCache view(pcoinsTip);
3698 if (!DisconnectBlock(block, state, pindexDelete, view))
3699 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3700 assert(view.Flush());
3701 DisconnectNotarisations(block);
3703 pindexDelete->segid = -2;
3704 pindexDelete->newcoins = 0;
3705 pindexDelete->zfunds = 0;
3707 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3708 uint256 sproutAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3709 uint256 saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3710 // Write the chain state to disk, if necessary.
3711 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3715 // resurrect mempool transactions from the disconnected block.
3716 for (int i = 0; i < block.vtx.size(); i++)
3718 // ignore validation errors in resurrected transactions
3719 CTransaction &tx = block.vtx[i];
3720 list<CTransaction> removed;
3721 CValidationState stateDummy;
3723 // don't keep staking or invalid transactions
3724 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3726 mempool.remove(tx, removed, true);
3729 // if this is a staking tx, and we are on Verus Sapling with nothing at stake solution,
3730 // save staking tx as a possible cheat
3731 if (NetworkUpgradeActive(pindexDelete->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING) &&
3732 ASSETCHAINS_LWMAPOS && (i == (block.vtx.size() - 1)) &&
3733 (block.IsVerusPOSBlock()))
3735 CTxHolder txh = CTxHolder(block.vtx[i], pindexDelete->GetHeight());
3739 if (sproutAnchorBeforeDisconnect != sproutAnchorAfterDisconnect) {
3740 // The anchor may not change between block disconnects,
3741 // in which case we don't want to evict from the mempool yet!
3742 mempool.removeWithAnchor(sproutAnchorBeforeDisconnect, SPROUT);
3744 if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) {
3745 // The anchor may not change between block disconnects,
3746 // in which case we don't want to evict from the mempool yet!
3747 mempool.removeWithAnchor(saplingAnchorBeforeDisconnect, SAPLING);
3751 // Update chainActive and related variables.
3752 UpdateTip(pindexDelete->pprev);
3754 // Get the current commitment tree
3755 SproutMerkleTree newSproutTree;
3756 SaplingMerkleTree newSaplingTree;
3757 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
3758 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
3759 // Let wallets know transactions went from 1-confirmed to
3760 // 0-confirmed or conflicted:
3761 for (int i = 0; i < block.vtx.size(); i++)
3763 CTransaction &tx = block.vtx[i];
3764 if ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
3766 EraseFromWallets(tx.GetHash());
3770 SyncWithWallets(tx, NULL);
3773 // Update cached incremental witnesses
3774 GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
3778 static int64_t nTimeReadFromDisk = 0;
3779 static int64_t nTimeConnectTotal = 0;
3780 static int64_t nTimeFlush = 0;
3781 static int64_t nTimeChainState = 0;
3782 static int64_t nTimePostConnect = 0;
3785 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3786 * corresponding to pindexNew, to bypass loading it again from disk.
3787 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3789 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3791 assert(pindexNew->pprev == chainActive.Tip());
3792 // Read block from disk.
3793 int64_t nTime1 = GetTimeMicros();
3796 if (!ReadBlockFromDisk(block, pindexNew,1))
3797 return AbortNode(state, "Failed to read block");
3800 KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight();
3801 // Get the current commitment tree
3802 SproutMerkleTree oldSproutTree;
3803 SaplingMerkleTree oldSaplingTree;
3804 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
3805 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
3806 // Apply the block atomically to the chain state.
3807 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3809 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3811 CCoinsViewCache view(pcoinsTip);
3812 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3813 KOMODO_CONNECTING = -1;
3814 GetMainSignals().BlockChecked(*pblock, state);
3816 if (state.IsInvalid())
3817 InvalidBlockFound(pindexNew, state);
3818 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3820 mapBlockSource.erase(pindexNew->GetBlockHash());
3821 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3822 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3823 assert(view.Flush());
3825 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3826 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3827 // Write the chain state to disk, if necessary.
3828 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3830 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3831 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3832 // Remove conflicting transactions from the mempool.
3833 list<CTransaction> txConflicted;
3834 mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload());
3836 // Remove transactions that expire at new block height from mempool
3837 mempool.removeExpired(pindexNew->GetHeight());
3839 // Update chainActive & related variables.
3840 UpdateTip(pindexNew);
3841 // Tell wallet about transactions that went from mempool
3843 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3844 SyncWithWallets(tx, NULL);
3846 // ... and about transactions that got confirmed:
3847 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3848 SyncWithWallets(tx, pblock);
3850 // Update cached incremental witnesses
3851 GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
3853 EnforceNodeDeprecation(pindexNew->GetHeight());
3855 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3856 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3857 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3858 if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->GetHeight() >= KOMODO_LONGESTCHAIN )
3860 else KOMODO_INSYNC = 0;
3861 //fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->GetHeight(),KOMODO_INSYNC);
3862 if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
3863 komodo_broadcast(pblock,8);
3868 * Return the tip of the chain with the most work in it, that isn't
3869 * known to be invalid (it's however far from certain to be valid).
3871 static CBlockIndex* FindMostWorkChain() {
3873 CBlockIndex *pindexNew = NULL;
3875 // Find the best candidate header.
3877 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3878 if (it == setBlockIndexCandidates.rend())
3883 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3884 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3885 CBlockIndex *pindexTest = pindexNew;
3886 bool fInvalidAncestor = false;
3887 while (pindexTest && !chainActive.Contains(pindexTest)) {
3888 assert(pindexTest->nChainTx || pindexTest->GetHeight() == 0);
3890 // Pruned nodes may have entries in setBlockIndexCandidates for
3891 // which block files have been deleted. Remove those as candidates
3892 // for the most work chain if we come across them; we can't switch
3893 // to a chain unless we have all the non-active-chain parent blocks.
3894 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3895 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3896 if (fFailedChain || fMissingData) {
3897 // Candidate chain is not usable (either invalid or missing data)
3898 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->chainPower > pindexBestInvalid->chainPower))
3899 pindexBestInvalid = pindexNew;
3900 CBlockIndex *pindexFailed = pindexNew;
3901 // Remove the entire chain from the set.
3902 while (pindexTest != pindexFailed) {
3904 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3905 } else if (fMissingData) {
3906 // If we're missing data, then add back to mapBlocksUnlinked,
3907 // so that if the block arrives in the future we can try adding
3908 // to setBlockIndexCandidates again.
3909 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3911 setBlockIndexCandidates.erase(pindexFailed);
3912 pindexFailed = pindexFailed->pprev;
3914 setBlockIndexCandidates.erase(pindexTest);
3915 fInvalidAncestor = true;
3918 pindexTest = pindexTest->pprev;
3920 if (!fInvalidAncestor)
3925 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3926 static void PruneBlockIndexCandidates() {
3927 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3928 // reorganization to a better block fails.
3929 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3930 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
3931 setBlockIndexCandidates.erase(it++);
3933 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3934 assert(!setBlockIndexCandidates.empty());
3938 * Try to make some progress towards making pindexMostWork the active block.
3939 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3941 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3942 AssertLockHeld(cs_main);
3943 bool fInvalidFound = false;
3944 const CBlockIndex *pindexOldTip = chainActive.Tip();
3945 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3947 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3948 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3949 // then pindexFork will be null, and we would need to remove the entire chain including
3950 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3951 auto reorgLength = pindexOldTip ? pindexOldTip->GetHeight() - (pindexFork ? pindexFork->GetHeight() : -1) : 0;
3952 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3953 if (reorgLength > MAX_REORG_LENGTH) {
3954 auto msg = strprintf(_(
3955 "A block chain reorganization has been detected that would roll back %d blocks! "
3956 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3957 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3958 _("Reorganization details") + ":\n" +
3959 "- " + strprintf(_("Current tip: %s, height %d, work %s\nstake %s"),
3960 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex(),
3961 pindexOldTip->chainPower.chainStake.GetHex()) + "\n" +
3962 "- " + strprintf(_("New tip: %s, height %d, work %s\nstake %s"),
3963 pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex(),
3964 pindexMostWork->chainPower.chainStake.GetHex()) + "\n" +
3965 "- " + strprintf(_("Fork point: %s %s, height %d"),
3966 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n\n" +
3967 _("Please help, human!");
3968 LogPrintf("*** %s\n", msg);
3969 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3974 // Disconnect active blocks which are no longer in the best chain.
3975 bool fBlocksDisconnected = false;
3977 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3978 if (!DisconnectTip(state))
3980 fBlocksDisconnected = true;
3982 if ( KOMODO_REWIND != 0 )
3984 CBlockIndex *tipindex;
3985 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->GetHeight(),KOMODO_REWIND);
3986 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->GetHeight() > KOMODO_REWIND )
3988 fBlocksDisconnected = true;
3989 fprintf(stderr,"%d ",(int32_t)tipindex->GetHeight());
3990 InvalidateBlock(state,tipindex);
3991 if ( !DisconnectTip(state) )
3994 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3996 fprintf(stderr,"resuming normal operations\n");
4000 // Build list of new blocks to connect.
4001 std::vector<CBlockIndex*> vpindexToConnect;
4002 bool fContinue = true;
4003 int nHeight = pindexFork ? pindexFork->GetHeight() : -1;
4004 while (fContinue && nHeight != pindexMostWork->GetHeight()) {
4005 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
4006 // a few blocks along the way.
4007 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->GetHeight());
4008 vpindexToConnect.clear();
4009 vpindexToConnect.reserve(nTargetHeight - nHeight);
4010 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
4011 while (pindexIter && pindexIter->GetHeight() != nHeight) {
4012 vpindexToConnect.push_back(pindexIter);
4013 pindexIter = pindexIter->pprev;
4015 nHeight = nTargetHeight;
4017 // Connect new blocks.
4018 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
4019 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
4020 if (state.IsInvalid()) {
4021 // The block violates a consensus rule.
4022 if (!state.CorruptionPossible())
4023 InvalidChainFound(vpindexToConnect.back());
4024 state = CValidationState();
4025 fInvalidFound = true;
4029 // A system error occurred (disk space, database error, ...).
4033 PruneBlockIndexCandidates();
4034 if (!pindexOldTip || chainActive.Tip()->chainPower > pindexOldTip->chainPower) {
4035 // We're in a better position than we were. Return temporarily to release the lock.
4043 if (fBlocksDisconnected) {
4044 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4046 mempool.removeWithoutBranchId(
4047 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4048 mempool.check(pcoinsTip);
4050 // Callbacks/notifications for a new best chain.
4052 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
4054 CheckForkWarningConditions();
4060 * Make the best chain active, in multiple steps. The result is either failure
4061 * or an activated best chain. pblock is either NULL or a pointer to a block
4062 * that is already loaded (to avoid loading it again from disk).
4064 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
4065 CBlockIndex *pindexNewTip = NULL;
4066 CBlockIndex *pindexMostWork = NULL;
4067 const CChainParams& chainParams = Params();
4069 boost::this_thread::interruption_point();
4071 bool fInitialDownload;
4074 pindexMostWork = FindMostWorkChain();
4076 // Whether we have anything to do at all.
4077 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
4080 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
4082 pindexNewTip = chainActive.Tip();
4083 fInitialDownload = IsInitialBlockDownload();
4085 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
4087 // Notifications/callbacks that can run without cs_main
4088 if (!fInitialDownload) {
4089 uint256 hashNewTip = pindexNewTip->GetBlockHash();
4090 // Relay inventory, but don't relay old inventory during initial block download.
4091 int nBlockEstimate = 0;
4092 if (fCheckpointsEnabled)
4093 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
4094 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
4095 // in a stalled download if the block file is pruned before the request.
4096 if (nLocalServices & NODE_NETWORK) {
4098 BOOST_FOREACH(CNode* pnode, vNodes)
4099 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
4100 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
4102 // Notify external listeners about the new tip.
4103 GetMainSignals().UpdatedBlockTip(pindexNewTip);
4104 uiInterface.NotifyBlockTip(hashNewTip);
4105 } //else fprintf(stderr,"initial download skips propagation\n");
4106 } while(pindexMostWork != chainActive.Tip());
4109 // Write changes periodically to disk, after relay.
4110 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
4117 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
4118 AssertLockHeld(cs_main);
4120 // Mark the block itself as invalid.
4121 pindex->nStatus |= BLOCK_FAILED_VALID;
4122 setDirtyBlockIndex.insert(pindex);
4123 setBlockIndexCandidates.erase(pindex);
4125 while (chainActive.Contains(pindex)) {
4126 CBlockIndex *pindexWalk = chainActive.Tip();
4127 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
4128 setDirtyBlockIndex.insert(pindexWalk);
4129 setBlockIndexCandidates.erase(pindexWalk);
4130 // ActivateBestChain considers blocks already in chainActive
4131 // unconditionally valid already, so force disconnect away from it.
4132 if (!DisconnectTip(state)) {
4133 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4134 mempool.removeWithoutBranchId(
4135 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4139 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
4141 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
4143 BlockMap::iterator it = mapBlockIndex.begin();
4144 while (it != mapBlockIndex.end()) {
4145 if ((it->second != 0) && it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
4146 setBlockIndexCandidates.insert(it->second);
4151 InvalidChainFound(pindex);
4152 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4153 mempool.removeWithoutBranchId(
4154 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4158 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
4159 AssertLockHeld(cs_main);
4161 int nHeight = pindex->GetHeight();
4163 // Remove the invalidity flag from this block and all its descendants.
4164 BlockMap::iterator it = mapBlockIndex.begin();
4165 while (it != mapBlockIndex.end()) {
4166 if ((it->second != 0) && !it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
4167 it->second->nStatus &= ~BLOCK_FAILED_MASK;
4168 setDirtyBlockIndex.insert(it->second);
4169 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
4170 setBlockIndexCandidates.insert(it->second);
4172 if (it->second == pindexBestInvalid) {
4173 // Reset invalid block marker if it was pointing to one of those.
4174 pindexBestInvalid = NULL;
4180 // Remove the invalidity flag from all ancestors too.
4181 while (pindex != NULL) {
4182 if (pindex->nStatus & BLOCK_FAILED_MASK) {
4183 pindex->nStatus &= ~BLOCK_FAILED_MASK;
4184 setDirtyBlockIndex.insert(pindex);
4186 pindex = pindex->pprev;
4191 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
4193 // Check for duplicate
4194 uint256 hash = block.GetHash();
4195 BlockMap::iterator it = mapBlockIndex.find(hash);
4196 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
4198 // the following block is for debugging, comment when not needed
4200 std::vector<BlockMap::iterator> vrit;
4201 for (BlockMap::iterator bit = mapBlockIndex.begin(); bit != mapBlockIndex.end(); bit++)
4203 if (bit->second == NULL)
4204 vrit.push_back(bit);
4208 printf("found %d NULL blocks in mapBlockIndex\n", vrit.size());
4212 if (it != mapBlockIndex.end())
4214 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
4216 // 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
4217 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
4220 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
4222 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
4223 return(0); // return here to avoid the state of pindex->GetHeight() not set and pprev NULL
4226 // Construct new block index object
4227 CBlockIndex* pindexNew = new CBlockIndex(block);
4229 // We assign the sequence id to blocks only when the full data is available,
4230 // to avoid miners withholding blocks but broadcasting headers, to get a
4231 // competitive advantage.
4232 pindexNew->nSequenceId = 0;
4233 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4234 pindexNew->phashBlock = &((*mi).first);
4235 if (miPrev != mapBlockIndex.end())
4237 if ( (pindexNew->pprev = (*miPrev).second) != 0 )
4238 pindexNew->SetHeight(pindexNew->pprev->GetHeight() + 1);
4239 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
4240 pindexNew->BuildSkip();
4242 pindexNew->chainPower = (pindexNew->pprev ? CChainPower(pindexNew) + pindexNew->pprev->chainPower : CChainPower(pindexNew)) + GetBlockProof(*pindexNew);
4243 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
4244 if (pindexBestHeader == NULL || pindexBestHeader->chainPower < pindexNew->chainPower)
4245 pindexBestHeader = pindexNew;
4247 setDirtyBlockIndex.insert(pindexNew);
4248 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
4249 mi->second = pindexNew;
4253 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
4254 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
4256 pindexNew->nTx = block.vtx.size();
4257 pindexNew->nChainTx = 0;
4258 CAmount sproutValue = 0;
4259 CAmount saplingValue = 0;
4260 for (auto tx : block.vtx) {
4261 // Negative valueBalance "takes" money from the transparent value pool
4262 // and adds it to the Sapling value pool. Positive valueBalance "gives"
4263 // money to the transparent value pool, removing from the Sapling value
4264 // pool. So we invert the sign here.
4265 saplingValue += -tx.valueBalance;
4267 for (auto js : tx.vjoinsplit) {
4268 sproutValue += js.vpub_old;
4269 sproutValue -= js.vpub_new;
4272 pindexNew->nSproutValue = sproutValue;
4273 pindexNew->nChainSproutValue = boost::none;
4274 pindexNew->nSaplingValue = saplingValue;
4275 pindexNew->nChainSaplingValue = boost::none;
4276 pindexNew->nFile = pos.nFile;
4277 pindexNew->nDataPos = pos.nPos;
4278 pindexNew->nUndoPos = 0;
4279 pindexNew->nStatus |= BLOCK_HAVE_DATA;
4280 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
4281 setDirtyBlockIndex.insert(pindexNew);
4283 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
4284 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
4285 deque<CBlockIndex*> queue;
4286 queue.push_back(pindexNew);
4288 // Recursively process any descendant blocks that now may be eligible to be connected.
4289 while (!queue.empty()) {
4290 CBlockIndex *pindex = queue.front();
4292 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
4293 if (pindex->pprev) {
4294 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4295 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4297 pindex->nChainSproutValue = boost::none;
4299 if (pindex->pprev->nChainSaplingValue) {
4300 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
4302 pindex->nChainSaplingValue = boost::none;
4305 pindex->nChainSproutValue = pindex->nSproutValue;
4306 pindex->nChainSaplingValue = pindex->nSaplingValue;
4309 LOCK(cs_nBlockSequenceId);
4310 pindex->nSequenceId = nBlockSequenceId++;
4312 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
4313 setBlockIndexCandidates.insert(pindex);
4315 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
4316 while (range.first != range.second) {
4317 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
4318 queue.push_back(it->second);
4320 mapBlocksUnlinked.erase(it);
4324 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
4325 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
4332 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
4334 LOCK(cs_LastBlockFile);
4336 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
4337 if (vinfoBlockFile.size() <= nFile) {
4338 vinfoBlockFile.resize(nFile + 1);
4342 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
4344 if (vinfoBlockFile.size() <= nFile) {
4345 vinfoBlockFile.resize(nFile + 1);
4349 pos.nPos = vinfoBlockFile[nFile].nSize;
4352 if (nFile != nLastBlockFile) {
4354 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
4356 FlushBlockFile(!fKnown);
4357 nLastBlockFile = nFile;
4360 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
4362 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
4364 vinfoBlockFile[nFile].nSize += nAddSize;
4367 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4368 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4369 if (nNewChunks > nOldChunks) {
4371 fCheckForPruning = true;
4372 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
4373 FILE *file = OpenBlockFile(pos);
4375 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
4376 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
4381 return state.Error("out of disk space");
4385 setDirtyFileInfo.insert(nFile);
4389 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
4393 LOCK(cs_LastBlockFile);
4395 unsigned int nNewSize;
4396 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
4397 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
4398 setDirtyFileInfo.insert(nFile);
4400 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4401 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4402 if (nNewChunks > nOldChunks) {
4404 fCheckForPruning = true;
4405 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
4406 FILE *file = OpenUndoFile(pos);
4408 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
4409 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
4414 return state.Error("out of disk space");
4420 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
4425 uint256 hash; int32_t i;
4426 hash = blockhdr.GetHash();
4427 for (i=31; i>=0; i--)
4428 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4429 fprintf(stderr," <- CheckBlockHeader\n");
4430 if ( chainActive.LastTip() != 0 )
4432 hash = chainActive.LastTip()->GetBlockHash();
4433 for (i=31; i>=0; i--)
4434 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4435 fprintf(stderr," <- chainTip\n");
4439 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
4441 CBlockIndex *tipindex;
4442 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
4443 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
4445 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
4446 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4448 //fprintf(stderr,"now its valid\n");
4452 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4454 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
4455 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4458 // Check block version
4459 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
4460 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
4462 // Check Equihash solution is valid
4465 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4466 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4468 // Check proof of work matches claimed amount
4469 /*komodo_index2pubkey33(pubkey33,pindex,height);
4470 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
4471 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
4475 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
4476 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
4478 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
4479 libzcash::ProofVerifier& verifier,
4480 bool fCheckPOW, bool fCheckMerkleRoot)
4482 uint8_t pubkey33[33]; uint256 hash;
4483 // These are checks that are independent of context.
4484 hash = block.GetHash();
4485 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
4486 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
4488 if ( *futureblockp == 0 )
4490 LogPrintf("CheckBlock header error");
4496 //if ( !CheckEquihashSolution(&block, Params()) )
4497 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4498 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
4499 if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
4501 int32_t z; for (z=31; z>=0; z--)
4502 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
4503 fprintf(stderr," failed hash ht.%d\n",height);
4504 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
4506 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
4507 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4509 // Check the merkle root.
4510 if (fCheckMerkleRoot) {
4512 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4513 if (block.hashMerkleRoot != hashMerkleRoot2)
4514 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
4515 REJECT_INVALID, "bad-txnmrklroot", true);
4517 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4518 // of transactions in a block without affecting the merkle root of a block,
4519 // while still invalidating it.
4521 return state.DoS(100, error("CheckBlock: duplicate transaction"),
4522 REJECT_INVALID, "bad-txns-duplicate", true);
4525 // All potential-corruption validation must be done before we do any
4526 // transaction validation, as otherwise we may mark the header as invalid
4527 // because we receive the wrong transactions for it.
4530 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
4531 return state.DoS(100, error("CheckBlock: size limits failed"),
4532 REJECT_INVALID, "bad-blk-length");
4534 // First transaction must be coinbase, the rest must not be
4535 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
4536 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
4537 REJECT_INVALID, "bad-cb-missing");
4539 for (unsigned int i = 1; i < block.vtx.size(); i++)
4540 if (block.vtx[i].IsCoinBase())
4541 return state.DoS(100, error("CheckBlock: more than one coinbase"),
4542 REJECT_INVALID, "bad-cb-multiple");
4544 // Check transactions
4545 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
4547 int32_t i,j,rejects=0,lastrejects=0;
4548 //fprintf(stderr,"put block's tx into mempool\n");
4551 for (i=0; i<block.vtx.size(); i++)
4553 CValidationState state;
4555 const CTransaction &tx = (CTransaction)block.vtx[i];
4556 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0)))
4559 if ( myAddtomempool(Tx, &state) == false ) // happens with out of order tx in block on resync
4561 // take advantage of other checks, but if we were only rejected because it is a valid staking
4562 // transaction, sync with wallets and don't mark as a reject
4563 if (i == (block.vtx.size() - 1) && ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock() && state.GetRejectReason() == "staking")
4564 SyncWithWallets(Tx, &block);
4569 if ( rejects == 0 || rejects == lastrejects )
4571 if ( 0 && lastrejects != 0 )
4572 fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
4575 //fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
4576 lastrejects = rejects;
4579 //fprintf(stderr,"done putting block's tx into mempool\n");
4582 for (uint32_t i = 0; i < block.vtx.size(); i++)
4584 const CTransaction& tx = block.vtx[i];
4585 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
4586 return error("CheckBlock: komodo_validate_interest failed");
4587 if (!CheckTransaction(tx, state, verifier))
4588 return error("CheckBlock: CheckTransaction failed");
4590 unsigned int nSigOps = 0;
4591 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4593 nSigOps += GetLegacySigOpCount(tx);
4595 if (nSigOps > MAX_BLOCK_SIGOPS)
4596 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
4597 REJECT_INVALID, "bad-blk-sigops", true);
4598 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
4600 //static uint32_t counter;
4601 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
4602 // fprintf(stderr,"check deposit rejection\n");
4603 LogPrintf("CheckBlockHeader komodo_check_deposit error");
4609 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4611 const CChainParams& chainParams = Params();
4612 const Consensus::Params& consensusParams = chainParams.GetConsensus();
4613 uint256 hash = block.GetHash();
4614 if (hash == consensusParams.hashGenesisBlock)
4619 int nHeight = pindexPrev->GetHeight()+1;
4621 // Check proof of work
4622 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
4624 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) <<
4625 " for block #" << nHeight << endl;
4626 return state.DoS(100, error("%s: incorrect proof of work", __func__),
4627 REJECT_INVALID, "bad-diffbits");
4630 // Check timestamp against prev
4631 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
4633 return state.Invalid(error("%s: block's timestamp is too early", __func__),
4634 REJECT_INVALID, "time-too-old");
4637 // Check that timestamp is not too far in the future
4638 if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
4640 return state.Invalid(error("%s: block timestamp too far in the future", __func__),
4641 REJECT_INVALID, "time-too-new");
4644 if (fCheckpointsEnabled)
4646 // Check that the block chain matches the known block chain up to a checkpoint
4647 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
4649 /*CBlockIndex *heightblock = chainActive[nHeight];
4650 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4652 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4655 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
4657 // Don't accept any forks from the main chain prior to last checkpoint
4658 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
4659 int32_t notarized_height;
4660 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() > 1 )
4662 CBlockIndex *heightblock = chainActive[nHeight];
4663 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4665 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
4669 if ( pcheckpoint != 0 && nHeight < pcheckpoint->GetHeight() )
4670 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->GetHeight()));
4671 if ( komodo_checkpoint(¬arized_height,nHeight,hash) < 0 )
4673 CBlockIndex *heightblock = chainActive[nHeight];
4674 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4676 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4678 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4682 // Reject block.nVersion < 4 blocks
4683 if (block.nVersion < 4)
4684 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4685 REJECT_OBSOLETE, "bad-version");
4690 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4692 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->GetHeight() + 1;
4693 const Consensus::Params& consensusParams = Params().GetConsensus();
4694 bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
4696 // Check that all transactions are finalized
4697 for (uint32_t i = 0; i < block.vtx.size(); i++) {
4698 const CTransaction& tx = block.vtx[i];
4700 // Check transaction contextually against consensus rules at block height
4701 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4702 return false; // Failure reason has been set in validation state object
4705 // if this is a stake transaction with a stake opreturn, reject it if not staking a block. don't check coinbase or actual stake tx
4707 if (sapling && i > 0 && i < (block.vtx.size() - 1) && ValidateStakeTransaction(tx, p, false))
4709 return state.DoS(10, error("%s: attempt to submit block with staking transaction that is not staking", __func__), REJECT_INVALID, "bad-txns-staking");
4712 int nLockTimeFlags = 0;
4713 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4714 ? pindexPrev->GetMedianTimePast()
4715 : block.GetBlockTime();
4716 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4717 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4721 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4722 // In Zcash this has been enforced since launch, except that the genesis
4723 // block didn't include the height in the coinbase (see Zcash protocol spec
4724 // section '6.8 Bitcoin Improvement Proposals').
4727 CScript expect = CScript() << nHeight;
4728 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4729 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4730 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4736 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4738 static uint256 zero;
4739 const CChainParams& chainparams = Params();
4740 AssertLockHeld(cs_main);
4742 // Check for duplicate
4743 uint256 hash = block.GetHash();
4744 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4745 CBlockIndex *pindex = NULL;
4746 if (miSelf != mapBlockIndex.end())
4748 // Block header is already known.
4749 if ( (pindex = miSelf->second) == 0 )
4750 miSelf->second = pindex = AddToBlockIndex(block);
4753 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4754 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4755 /*if ( pindex != 0 && hash == komodo_requestedhash )
4757 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4758 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4759 komodo_requestedcount = 0;
4762 //if ( pindex == 0 )
4763 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4766 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state,0))
4768 if ( *futureblockp == 0 )
4770 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4774 // Get prev block index
4775 CBlockIndex* pindexPrev = NULL;
4776 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4778 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4779 if (mi == mapBlockIndex.end())
4781 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4783 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4785 pindexPrev = (*mi).second;
4786 if (pindexPrev == 0 )
4788 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4791 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4792 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4794 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4796 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4797 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4802 if ( (pindex= AddToBlockIndex(block)) != 0 )
4804 miSelf = mapBlockIndex.find(hash);
4805 if (miSelf != mapBlockIndex.end())
4806 miSelf->second = pindex;
4807 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4812 /*if ( pindex != 0 && hash == komodo_requestedhash )
4814 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4815 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4816 komodo_requestedcount = 0;
4821 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4823 const CChainParams& chainparams = Params();
4824 AssertLockHeld(cs_main);
4826 CBlockIndex *&pindex = *ppindex;
4827 if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
4829 if ( *futureblockp == 0 )
4831 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4837 LogPrintf("AcceptBlock null pindex\n");
4838 *futureblockp = true;
4841 //fprintf(stderr,"acceptblockheader passed\n");
4842 // Try to process all requested blocks that we don't have, but only
4843 // process an unrequested block if it's new and has enough work to
4844 // advance our tip, and isn't too many blocks ahead.
4845 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4846 bool fHasMoreWork = (chainActive.Tip() ? pindex->chainPower > chainActive.Tip()->chainPower : true);
4847 // Blocks that are too out-of-order needlessly limit the effectiveness of
4848 // pruning, because pruning will not delete block files that contain any
4849 // blocks which are too close in height to the tip. Apply this test
4850 // regardless of whether pruning is enabled; it should generally be safe to
4851 // not process unrequested blocks.
4852 bool fTooFarAhead = (pindex->GetHeight() > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4854 // TODO: deal better with return value and error conditions for duplicate
4855 // and unrequested blocks.
4856 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4857 if (fAlreadyHave) return true;
4858 if (!fRequested) { // If we didn't ask for it:
4859 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4860 if (!fHasMoreWork) return true; // Don't process less-work chains
4861 if (fTooFarAhead) return true; // Block height is too high
4864 // See method docstring for why this is always disabled
4865 auto verifier = libzcash::ProofVerifier::Disabled();
4866 if ((!CheckBlock(futureblockp,pindex->GetHeight(),pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4868 if ( *futureblockp == 0 )
4870 if (state.IsInvalid() && !state.CorruptionPossible()) {
4871 pindex->nStatus |= BLOCK_FAILED_VALID;
4872 setDirtyBlockIndex.insert(pindex);
4874 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4879 int nHeight = pindex->GetHeight();
4880 // Write block to history file
4882 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4883 CDiskBlockPos blockPos;
4886 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4887 return error("AcceptBlock(): FindBlockPos failed");
4889 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4890 AbortNode(state, "Failed to write block");
4891 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4892 return error("AcceptBlock(): ReceivedBlockTransactions failed");
4893 } catch (const std::runtime_error& e) {
4894 return AbortNode(state, std::string("System error: ") + e.what());
4897 if (fCheckForPruning)
4898 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4899 if ( *futureblockp == 0 )
4901 LogPrintf("AcceptBlock block from future error\n");
4905 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4907 unsigned int nFound = 0;
4908 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4910 if (pstart->nVersion >= minVersion)
4912 pstart = pstart->pprev;
4914 return (nFound >= nRequired);
4917 void komodo_currentheight_set(int32_t height);
4919 CBlockIndex *komodo_ensure(CBlock *pblock, uint256 hash)
4921 CBlockIndex *pindex = 0;
4922 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4923 if ( miSelf != mapBlockIndex.end() )
4925 if ( (pindex = miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4927 miSelf->second = AddToBlockIndex(*pblock);
4928 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4930 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4932 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4933 if ( miSelf != mapBlockIndex.end() )
4935 if ( miSelf->second == 0 )
4937 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4938 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4946 CBlockIndex *oldkomodo_ensure(CBlock *pblock, uint256 hash)
4948 CBlockIndex *pindex=0,*previndex=0;
4949 if ( (pindex = mapBlockIndex[hash]) == 0 )
4951 pindex = new CBlockIndex();
4953 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4954 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4955 pindex->phashBlock = &((*mi).first);
4957 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4958 if ( miSelf == mapBlockIndex.end() )
4960 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4963 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4967 pindex = AddToBlockIndex(*pblock);
4968 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4972 miSelf->second = pindex;
4973 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4974 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4976 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4978 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4979 if ( miSelf == mapBlockIndex.end() )
4980 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4981 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4983 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4985 if ( previndex == 0 )
4986 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4987 if ( previndex != 0 )
4989 miSelf->second = previndex;
4990 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4991 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4993 } else LogPrintf("komodo_ensure unexpected null miprev\n");
4999 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
5001 // Preliminary checks
5002 bool checked; uint256 hash; int32_t futureblock=0;
5003 auto verifier = libzcash::ProofVerifier::Disabled();
5004 hash = pblock->GetHash();
5005 //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
5008 if ( chainActive.LastTip() != 0 )
5009 komodo_currentheight_set(chainActive.LastTip()->GetHeight());
5010 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
5011 bool fRequested = MarkBlockAsReceived(hash);
5012 fRequested |= fForceProcessing;
5013 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
5016 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
5018 if (!checked && futureblock == 0)
5022 Misbehaving(pfrom->GetId(), 1);
5024 return error("%s: CheckBlock FAILED", __func__);
5027 CBlockIndex *pindex = NULL;
5029 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
5030 if (pindex && pfrom) {
5031 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
5034 if (!ret && futureblock == 0)
5035 return error("%s: AcceptBlock FAILED", __func__);
5036 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
5039 if (futureblock == 0 && !ActivateBestChain(state, pblock))
5040 return error("%s: ActivateBestChain failed", __func__);
5041 //fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
5043 // when we succeed here, we prune all cheat candidates in the cheat list to 250 blocks ago, as they should be used or not
5045 if ((height - 250) > 1)
5046 cheatList.Prune(height - 200);
5051 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
5053 AssertLockHeld(cs_main);
5054 assert(pindexPrev == chainActive.Tip());
5056 CCoinsViewCache viewNew(pcoinsTip);
5057 CBlockIndex indexDummy(block);
5058 indexDummy.pprev = pindexPrev;
5059 indexDummy.SetHeight(pindexPrev->GetHeight() + 1);
5060 // JoinSplit proofs are verified in ConnectBlock
5061 auto verifier = libzcash::ProofVerifier::Disabled();
5062 // NOTE: CheckBlockHeader is called by CheckBlock
5063 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
5065 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
5068 int32_t futureblock;
5069 if (!CheckBlock(&futureblock,indexDummy.GetHeight(),0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
5071 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
5074 if (!ContextualCheckBlock(block, state, pindexPrev))
5076 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
5079 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
5081 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
5084 assert(state.IsValid());
5085 if ( futureblock != 0 )
5091 * BLOCK PRUNING CODE
5094 /* Calculate the amount of disk space the block & undo files currently use */
5095 uint64_t CalculateCurrentUsage()
5097 uint64_t retval = 0;
5098 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
5099 retval += file.nSize + file.nUndoSize;
5104 /* Prune a block file (modify associated database entries)*/
5105 void PruneOneBlockFile(const int fileNumber)
5107 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
5108 CBlockIndex* pindex = it->second;
5109 if (pindex && pindex->nFile == fileNumber) {
5110 pindex->nStatus &= ~BLOCK_HAVE_DATA;
5111 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
5113 pindex->nDataPos = 0;
5114 pindex->nUndoPos = 0;
5115 setDirtyBlockIndex.insert(pindex);
5117 // Prune from mapBlocksUnlinked -- any block we prune would have
5118 // to be downloaded again in order to consider its chain, at which
5119 // point it would be considered as a candidate for
5120 // mapBlocksUnlinked or setBlockIndexCandidates.
5121 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
5122 while (range.first != range.second) {
5123 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
5125 if (it->second == pindex) {
5126 mapBlocksUnlinked.erase(it);
5132 vinfoBlockFile[fileNumber].SetNull();
5133 setDirtyFileInfo.insert(fileNumber);
5137 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
5139 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
5140 CDiskBlockPos pos(*it, 0);
5141 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
5142 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
5143 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
5147 /* Calculate the block/rev files that should be deleted to remain under target*/
5148 void FindFilesToPrune(std::set<int>& setFilesToPrune)
5150 LOCK2(cs_main, cs_LastBlockFile);
5151 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
5154 if (chainActive.Tip()->GetHeight() <= Params().PruneAfterHeight()) {
5157 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->GetHeight() - MIN_BLOCKS_TO_KEEP;
5158 uint64_t nCurrentUsage = CalculateCurrentUsage();
5159 // We don't check to prune until after we've allocated new space for files
5160 // So we should leave a buffer under our target to account for another allocation
5161 // before the next pruning.
5162 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
5163 uint64_t nBytesToPrune;
5166 if (nCurrentUsage + nBuffer >= nPruneTarget) {
5167 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
5168 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
5170 if (vinfoBlockFile[fileNumber].nSize == 0)
5173 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
5176 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
5177 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
5180 PruneOneBlockFile(fileNumber);
5181 // Queue up the files for removal
5182 setFilesToPrune.insert(fileNumber);
5183 nCurrentUsage -= nBytesToPrune;
5188 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
5189 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
5190 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
5191 nLastBlockWeCanPrune, count);
5194 bool CheckDiskSpace(uint64_t nAdditionalBytes)
5196 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
5198 // Check for nMinDiskSpace bytes (currently 50MB)
5199 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
5200 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
5205 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
5207 static int32_t didinit[64];
5210 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5211 boost::filesystem::create_directories(path.parent_path());
5212 FILE* file = fopen(path.string().c_str(), "rb+");
5213 if (!file && !fReadOnly)
5214 file = fopen(path.string().c_str(), "wb+");
5216 LogPrintf("Unable to open file %s\n", path.string());
5219 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
5221 komodo_prefetch(file);
5222 didinit[pos.nFile] = 1;
5225 if (fseek(file, pos.nPos, SEEK_SET)) {
5226 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5234 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
5235 return OpenDiskFile(pos, "blk", fReadOnly);
5238 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5239 return OpenDiskFile(pos, "rev", fReadOnly);
5242 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
5244 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
5247 CBlockIndex * InsertBlockIndex(uint256 hash)
5253 BlockMap::iterator mi = mapBlockIndex.find(hash);
5254 if (mi != mapBlockIndex.end() && mi->second != NULL)
5255 return (*mi).second;
5258 CBlockIndex* pindexNew = new CBlockIndex();
5260 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
5261 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
5262 pindexNew->phashBlock = &((*mi).first);
5263 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
5268 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
5270 bool static LoadBlockIndexDB()
5272 const CChainParams& chainparams = Params();
5273 LogPrintf("%s: start loading guts\n", __func__);
5274 if (!pblocktree->LoadBlockIndexGuts())
5276 LogPrintf("%s: loaded guts\n", __func__);
5277 boost::this_thread::interruption_point();
5279 // Calculate chainPower
5280 vector<pair<int, CBlockIndex*> > vSortedByHeight;
5281 vSortedByHeight.reserve(mapBlockIndex.size());
5282 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5284 CBlockIndex* pindex = item.second;
5285 vSortedByHeight.push_back(make_pair(pindex->GetHeight(), pindex));
5286 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5288 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
5289 sort(vSortedByHeight.begin(), vSortedByHeight.end());
5290 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
5291 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
5293 CBlockIndex* pindex = item.second;
5294 pindex->chainPower = (pindex->pprev ? CChainPower(pindex) + pindex->pprev->chainPower : CChainPower(pindex)) + GetBlockProof(*pindex);
5295 // We can link the chain of blocks for which we've received transactions at some point.
5296 // Pruned nodes may have deleted the block.
5297 if (pindex->nTx > 0) {
5298 if (pindex->pprev) {
5299 if (pindex->pprev->nChainTx) {
5300 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
5301 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
5302 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
5304 pindex->nChainSproutValue = boost::none;
5306 if (pindex->pprev->nChainSaplingValue) {
5307 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
5309 pindex->nChainSaplingValue = boost::none;
5312 pindex->nChainTx = 0;
5313 pindex->nChainSproutValue = boost::none;
5314 pindex->nChainSaplingValue = boost::none;
5315 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
5318 pindex->nChainTx = pindex->nTx;
5319 pindex->nChainSproutValue = pindex->nSproutValue;
5320 pindex->nChainSaplingValue = pindex->nSaplingValue;
5323 // Construct in-memory chain of branch IDs.
5324 // Relies on invariant: a block that does not activate a network upgrade
5325 // will always be valid under the same consensus rules as its parent.
5326 // Genesis block has a branch ID of zero by definition, but has no
5327 // validity status because it is side-loaded into a fresh chain.
5328 // Activation blocks will have branch IDs set (read from disk).
5329 if (pindex->pprev) {
5330 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
5331 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
5334 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
5336 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
5337 setBlockIndexCandidates.insert(pindex);
5338 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->chainPower > pindexBestInvalid->chainPower))
5339 pindexBestInvalid = pindex;
5341 pindex->BuildSkip();
5342 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
5343 pindexBestHeader = pindex;
5344 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5346 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
5348 // Load block file info
5349 pblocktree->ReadLastBlockFile(nLastBlockFile);
5350 vinfoBlockFile.resize(nLastBlockFile + 1);
5351 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
5352 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
5353 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
5355 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
5356 for (int nFile = nLastBlockFile + 1; true; nFile++) {
5357 CBlockFileInfo info;
5358 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
5359 vinfoBlockFile.push_back(info);
5365 // Check presence of blk files
5366 LogPrintf("Checking all blk files are present...\n");
5367 set<int> setBlkDataFiles;
5368 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5370 CBlockIndex* pindex = item.second;
5371 if (pindex->nStatus & BLOCK_HAVE_DATA) {
5372 setBlkDataFiles.insert(pindex->nFile);
5374 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5376 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
5377 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
5379 CDiskBlockPos pos(*it, 0);
5380 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
5385 // Check whether we have ever pruned block & undo files
5386 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
5388 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
5390 // Check whether we need to continue reindexing
5391 bool fReindexing = false;
5392 pblocktree->ReadReindexing(fReindexing);
5393 fReindex |= fReindexing;
5395 // Check whether we have a transaction index
5396 pblocktree->ReadFlag("txindex", fTxIndex);
5397 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
5398 // Check whether we have an address index
5399 pblocktree->ReadFlag("addressindex", fAddressIndex);
5400 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
5402 // Check whether we have a timestamp index
5403 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
5404 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
5406 // Check whether we have a spent index
5407 pblocktree->ReadFlag("spentindex", fSpentIndex);
5408 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
5410 // Fill in-memory data
5411 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5413 CBlockIndex* pindex = item.second;
5414 // - This relationship will always be true even if pprev has multiple
5415 // children, because hashSproutAnchor is technically a property of pprev,
5416 // not its children.
5417 // - This will miss chain tips; we handle the best tip below, and other
5418 // tips will be handled by ConnectTip during a re-org.
5419 if (pindex->pprev) {
5420 pindex->pprev->hashFinalSproutRoot = pindex->hashSproutAnchor;
5422 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5425 // Load pointer to end of best chain
5426 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
5427 if (it == mapBlockIndex.end())
5430 chainActive.SetTip(it->second);
5432 // Set hashFinalSproutRoot for the end of best chain
5433 it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT);
5435 PruneBlockIndexCandidates();
5438 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
5439 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
5441 int32_t longestchain = komodo_longestchain();
5442 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
5443 // runs, which makes it return 0, so we guess 50% for now
5444 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
5447 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
5448 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
5449 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
5452 EnforceNodeDeprecation(chainActive.Height(), true);
5457 CVerifyDB::CVerifyDB()
5459 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
5462 CVerifyDB::~CVerifyDB()
5464 uiInterface.ShowProgress("", 100);
5467 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
5470 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
5473 // Verify blocks in the best chain
5474 if (nCheckDepth <= 0)
5475 nCheckDepth = 1000000000; // suffices until the year 19000
5476 if (nCheckDepth > chainActive.Height())
5477 nCheckDepth = chainActive.Height();
5478 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
5479 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
5480 CCoinsViewCache coins(coinsview);
5481 CBlockIndex* pindexState = chainActive.Tip();
5482 CBlockIndex* pindexFailure = NULL;
5483 int nGoodTransactions = 0;
5484 CValidationState state;
5485 // No need to verify JoinSplits twice
5486 auto verifier = libzcash::ProofVerifier::Disabled();
5487 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
5488 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
5490 boost::this_thread::interruption_point();
5491 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
5492 if (pindex->GetHeight() < chainActive.Height()-nCheckDepth)
5495 // check level 0: read from disk
5496 if (!ReadBlockFromDisk(block, pindex,0))
5497 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5498 // check level 1: verify block validity
5499 int32_t futureblock;
5500 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, verifier,0) )
5501 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5502 // check level 2: verify undo validity
5503 if (nCheckLevel >= 2 && pindex) {
5505 CDiskBlockPos pos = pindex->GetUndoPos();
5506 if (!pos.IsNull()) {
5507 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5508 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5511 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
5512 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
5514 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5515 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5516 pindexState = pindex->pprev;
5518 nGoodTransactions = 0;
5519 pindexFailure = pindex;
5521 nGoodTransactions += block.vtx.size();
5523 if (ShutdownRequested())
5526 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
5528 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->GetHeight() + 1, nGoodTransactions);
5530 // check level 4: try reconnecting blocks
5531 if (nCheckLevel >= 4) {
5532 CBlockIndex *pindex = pindexState;
5533 while (pindex != chainActive.Tip()) {
5534 boost::this_thread::interruption_point();
5535 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * 50))));
5536 pindex = chainActive.Next(pindex);
5538 if (!ReadBlockFromDisk(block, pindex,0))
5539 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5540 if (!ConnectBlock(block, state, pindex, coins,false, true))
5541 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5545 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions);
5550 bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches)
5554 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
5555 // index will have nCachedBranchId set based on the values previously persisted
5556 // to disk. By definition, a set nCachedBranchId means that the block was
5557 // fully-validated under the corresponding consensus rules. Thus we can quickly
5558 // identify whether the current active chain matches our expected sequence of
5559 // consensus rule changes, with two checks:
5561 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
5562 // - nCachedBranchId for each block matches what we expect.
5563 auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) {
5564 auto consensus = params.GetConsensus();
5565 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5566 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->GetHeight(), consensus);
5567 return fFlagSet == fFlagExpected &&
5568 pindex->nCachedBranchId &&
5569 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->GetHeight(), consensus);
5573 while (nHeight <= chainActive.Height()) {
5574 if (!sufficientlyValidated(chainActive[nHeight])) {
5580 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
5581 auto rewindLength = chainActive.Height() - nHeight;
5582 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH)
5584 auto pindexOldTip = chainActive.Tip();
5585 auto pindexRewind = chainActive[nHeight - 1];
5586 auto msg = strprintf(_(
5587 "A block chain rewind has been detected that would roll back %d blocks! "
5588 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5589 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5590 _("Rewind details") + ":\n" +
5591 "- " + strprintf(_("Current tip: %s, height %d"),
5592 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight()) + "\n" +
5593 "- " + strprintf(_("Rewinding to: %s, height %d"),
5594 pindexRewind->phashBlock->GetHex(), pindexRewind->GetHeight()) + "\n\n" +
5595 _("Please help, human!");
5596 LogPrintf("*** %s\n", msg);
5597 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5602 CValidationState state;
5603 CBlockIndex* pindex = chainActive.Tip();
5604 while (chainActive.Height() >= nHeight) {
5605 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5606 // If pruning, don't try rewinding past the HAVE_DATA point;
5607 // since older blocks can't be served anyway, there's
5608 // no need to walk further, and trying to DisconnectTip()
5609 // will fail (and require a needless reindex/redownload
5610 // of the blockchain).
5613 if (!DisconnectTip(state, true)) {
5614 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->GetHeight());
5616 // Occasionally flush state to disk.
5617 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5621 // Reduce validity flag and have-data flags.
5623 // Collect blocks to be removed (blocks in mapBlockIndex must be at least BLOCK_VALID_TREE).
5624 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5625 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5626 std::vector<const CBlockIndex*> vBlocks;
5627 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5628 CBlockIndex* pindexIter = it->second;
5630 // Note: If we encounter an insufficiently validated block that
5631 // is on chainActive, it must be because we are a pruning node, and
5632 // this block or some successor doesn't HAVE_DATA, so we were unable to
5633 // rewind all the way. Blocks remaining on chainActive at this point
5634 // must not have their validity reduced.
5635 if (pindexIter && !sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
5637 pindexIter->nStatus =
5638 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5639 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
5640 // Remove have-data flags
5641 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
5643 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
5644 pindexIter->nCachedBranchId = boost::none;
5645 // Remove storage location
5646 pindexIter->nFile = 0;
5647 pindexIter->nDataPos = 0;
5648 pindexIter->nUndoPos = 0;
5649 // Remove various other things
5650 pindexIter->nTx = 0;
5651 pindexIter->nChainTx = 0;
5652 pindexIter->nSproutValue = boost::none;
5653 pindexIter->nChainSproutValue = boost::none;
5654 pindexIter->nSaplingValue = 0;
5655 pindexIter->nChainSaplingValue = boost::none;
5656 pindexIter->nSequenceId = 0;
5658 // Make sure it gets written
5659 /* corresponds to commented out block below as an alternative to setDirtyBlockIndex
5660 vBlocks.push_back(pindexIter);
5662 setDirtyBlockIndex.insert(pindexIter);
5663 if (pindexIter == pindexBestInvalid)
5665 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
5666 pindexBestInvalid = NULL;
5670 setBlockIndexCandidates.erase(pindexIter);
5671 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
5672 while (ret.first != ret.second) {
5673 if (ret.first->second == pindexIter) {
5674 mapBlocksUnlinked.erase(ret.first++);
5679 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5680 setBlockIndexCandidates.insert(pindexIter);
5685 // Set pindexBestHeader to the current chain tip
5686 // (since we are about to delete the block it is pointing to)
5687 pindexBestHeader = chainActive.Tip();
5689 // Erase block indices on-disk
5690 if (!pblocktree->EraseBatchSync(vBlocks)) {
5691 return AbortNode(state, "Failed to erase from block index database");
5694 // Erase block indices in-memory
5695 for (auto pindex : vBlocks) {
5696 auto ret = mapBlockIndex.find(*pindex->phashBlock);
5697 if (ret != mapBlockIndex.end()) {
5698 mapBlockIndex.erase(ret);
5704 PruneBlockIndexCandidates();
5708 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5715 void UnloadBlockIndex()
5718 setBlockIndexCandidates.clear();
5719 chainActive.SetTip(NULL);
5720 pindexBestInvalid = NULL;
5721 pindexBestHeader = NULL;
5723 mapOrphanTransactions.clear();
5724 mapOrphanTransactionsByPrev.clear();
5726 mapBlocksUnlinked.clear();
5727 vinfoBlockFile.clear();
5729 nBlockSequenceId = 1;
5730 mapBlockSource.clear();
5731 mapBlocksInFlight.clear();
5732 nQueuedValidatedHeaders = 0;
5733 nPreferredDownload = 0;
5734 setDirtyBlockIndex.clear();
5735 setDirtyFileInfo.clear();
5736 mapNodeState.clear();
5737 recentRejects.reset(NULL);
5739 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5740 delete entry.second;
5742 mapBlockIndex.clear();
5743 fHavePruned = false;
5746 bool LoadBlockIndex()
5748 // Load block index from databases
5749 KOMODO_LOADINGBLOCKS = 1;
5750 if (!fReindex && !LoadBlockIndexDB())
5752 KOMODO_LOADINGBLOCKS = 0;
5755 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5760 bool InitBlockIndex() {
5761 const CChainParams& chainparams = Params();
5764 // Initialize global variables that cannot be constructed at startup.
5765 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5766 // Check whether we're already initialized
5767 if (chainActive.Genesis() != NULL)
5771 // Use the provided setting for -txindex in the new database
5772 fTxIndex = GetBoolArg("-txindex", true);
5773 pblocktree->WriteFlag("txindex", fTxIndex);
5774 // Use the provided setting for -addressindex in the new database
5775 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5776 pblocktree->WriteFlag("addressindex", fAddressIndex);
5778 // Use the provided setting for -timestampindex in the new database
5779 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5780 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5782 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5783 pblocktree->WriteFlag("spentindex", fSpentIndex);
5784 fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
5785 LogPrintf("Initializing databases...\n");
5787 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5790 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5791 // Start new block file
5792 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5793 CDiskBlockPos blockPos;
5794 CValidationState state;
5795 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5796 return error("LoadBlockIndex(): FindBlockPos failed");
5797 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5798 return error("LoadBlockIndex(): writing genesis block to disk failed");
5799 CBlockIndex *pindex = AddToBlockIndex(block);
5801 return error("LoadBlockIndex(): couldnt add to block index");
5802 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5803 return error("LoadBlockIndex(): genesis block not accepted");
5804 if (!ActivateBestChain(state, &block))
5805 return error("LoadBlockIndex(): genesis block cannot be activated");
5806 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5807 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5808 } catch (const std::runtime_error& e) {
5809 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5818 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5820 const CChainParams& chainparams = Params();
5821 // Map of disk positions for blocks with unknown parent (only used for reindex)
5822 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5823 int64_t nStart = GetTimeMillis();
5827 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5828 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5829 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5830 uint64_t nRewind = blkdat.GetPos();
5831 while (!blkdat.eof()) {
5832 boost::this_thread::interruption_point();
5834 blkdat.SetPos(nRewind);
5835 nRewind++; // start one byte further next time, in case of failure
5836 blkdat.SetLimit(); // remove former limit
5837 unsigned int nSize = 0;
5840 unsigned char buf[MESSAGE_START_SIZE];
5841 blkdat.FindByte(Params().MessageStart()[0]);
5842 nRewind = blkdat.GetPos()+1;
5843 blkdat >> FLATDATA(buf);
5844 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5848 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5850 } catch (const std::exception&) {
5851 // no valid block header found; don't complain
5856 uint64_t nBlockPos = blkdat.GetPos();
5858 dbp->nPos = nBlockPos;
5859 blkdat.SetLimit(nBlockPos + nSize);
5860 blkdat.SetPos(nBlockPos);
5863 nRewind = blkdat.GetPos();
5865 // detect out of order blocks, and store them for later
5866 uint256 hash = block.GetHash();
5867 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5868 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5869 block.hashPrevBlock.ToString());
5871 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5875 // process in case the block isn't known yet
5876 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5877 CValidationState state;
5878 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5880 if (state.IsError())
5882 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->GetHeight() % 1000 == 0) {
5883 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->GetHeight());
5886 // Recursively process earlier encountered successors of this block
5887 deque<uint256> queue;
5888 queue.push_back(hash);
5889 while (!queue.empty()) {
5890 uint256 head = queue.front();
5892 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5893 while (range.first != range.second) {
5894 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5895 if (ReadBlockFromDisk(mapBlockIndex.count(hash)!=0?mapBlockIndex[hash]->GetHeight():0,block, it->second,1))
5897 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5899 CValidationState dummy;
5900 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5903 queue.push_back(block.GetHash());
5907 mapBlocksUnknownParent.erase(it);
5910 } catch (const std::exception& e) {
5911 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5914 } catch (const std::runtime_error& e) {
5915 AbortNode(std::string("System error: ") + e.what());
5918 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5922 void static CheckBlockIndex()
5924 const Consensus::Params& consensusParams = Params().GetConsensus();
5925 if (!fCheckBlockIndex) {
5931 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5932 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5933 // iterating the block tree require that chainActive has been initialized.)
5934 if (chainActive.Height() < 0) {
5935 assert(mapBlockIndex.size() <= 1);
5939 // Build forward-pointing map of the entire block tree.
5940 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5941 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5942 if ( it->second != 0 )
5943 forward.insert(std::make_pair(it->second->pprev, it->second));
5945 if ( Params().NetworkIDString() != "regtest" )
5946 assert(forward.size() == mapBlockIndex.size());
5948 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5949 CBlockIndex *pindex = rangeGenesis.first->second;
5950 rangeGenesis.first++;
5951 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5953 // Iterate over the entire block tree, using depth-first search.
5954 // Along the way, remember whether there are blocks on the path from genesis
5955 // block being explored which are the first to have certain properties.
5958 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5959 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5960 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5961 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5962 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5963 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5964 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5965 while (pindex != NULL) {
5967 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5968 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5969 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5970 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5971 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5972 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5973 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5975 // Begin: actual consistency checks.
5976 if (pindex->pprev == NULL) {
5977 // Genesis block checks.
5978 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5979 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5981 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
5982 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5983 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5985 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5986 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5987 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5989 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5990 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5992 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5993 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5994 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5995 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5996 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5997 assert(pindex->GetHeight() == nHeight); // nHeight must be consistent.
5998 assert(pindex->pprev == NULL || pindex->chainPower >= pindex->pprev->chainPower); // For every block except the genesis block, the chainwork must be larger than the parent's.
5999 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->GetHeight() < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
6000 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
6001 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
6002 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
6003 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
6004 if (pindexFirstInvalid == NULL) {
6005 // Checks for not-invalid blocks.
6006 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
6008 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
6009 if (pindexFirstInvalid == NULL) {
6010 // If this block sorts at least as good as the current tip and
6011 // is valid and we have all data for its parents, it must be in
6012 // setBlockIndexCandidates. chainActive.Tip() must also be there
6013 // even if some data has been pruned.
6014 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
6015 assert(setBlockIndexCandidates.count(pindex));
6017 // If some parent is missing, then it could be that this block was in
6018 // setBlockIndexCandidates but had to be removed because of the missing data.
6019 // In this case it must be in mapBlocksUnlinked -- see test below.
6021 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
6022 assert(setBlockIndexCandidates.count(pindex) == 0);
6024 // Check whether this block is in mapBlocksUnlinked.
6025 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
6026 bool foundInUnlinked = false;
6027 while (rangeUnlinked.first != rangeUnlinked.second) {
6028 assert(rangeUnlinked.first->first == pindex->pprev);
6029 if (rangeUnlinked.first->second == pindex) {
6030 foundInUnlinked = true;
6033 rangeUnlinked.first++;
6035 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
6036 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
6037 assert(foundInUnlinked);
6039 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
6040 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
6041 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
6042 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
6043 assert(fHavePruned); // We must have pruned.
6044 // This block may have entered mapBlocksUnlinked if:
6045 // - it has a descendant that at some point had more work than the
6047 // - we tried switching to that descendant but were missing
6048 // data for some intermediate block between chainActive and the
6050 // So if this block is itself better than chainActive.Tip() and it wasn't in
6051 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
6052 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
6053 if (pindexFirstInvalid == NULL) {
6054 assert(foundInUnlinked);
6058 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
6059 // End: actual consistency checks.
6061 // Try descending into the first subnode.
6062 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
6063 if (range.first != range.second) {
6064 // A subnode was found.
6065 pindex = range.first->second;
6069 // This is a leaf node.
6070 // Move upwards until we reach a node of which we have not yet visited the last child.
6072 // We are going to either move to a parent or a sibling of pindex.
6073 // If pindex was the first with a certain property, unset the corresponding variable.
6074 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
6075 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
6076 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
6077 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
6078 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
6079 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
6080 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
6082 CBlockIndex* pindexPar = pindex->pprev;
6083 // Find which child we just visited.
6084 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
6085 while (rangePar.first->second != pindex) {
6086 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
6089 // Proceed to the next one.
6091 if (rangePar.first != rangePar.second) {
6092 // Move to the sibling.
6093 pindex = rangePar.first->second;
6104 // Check that we actually traversed the entire map.
6105 assert(nNodes == forward.size());
6108 //////////////////////////////////////////////////////////////////////////////
6113 std::string GetWarnings(const std::string& strFor)
6116 string strStatusBar;
6119 if (!CLIENT_VERSION_IS_RELEASE)
6120 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
6122 if (GetBoolArg("-testsafemode", false))
6123 strStatusBar = strRPC = "testsafemode enabled";
6125 // Misc warnings like out of disk space and clock is wrong
6126 if (strMiscWarning != "")
6129 strStatusBar = strMiscWarning;
6132 if (fLargeWorkForkFound)
6135 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
6137 else if (fLargeWorkInvalidChainFound)
6140 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.");
6146 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6148 const CAlert& alert = item.second;
6149 if (alert.AppliesToMe() && alert.nPriority > nPriority)
6151 nPriority = alert.nPriority;
6152 strStatusBar = alert.strStatusBar;
6153 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
6154 strRPC = alert.strRPCError;
6160 if (strFor == "statusbar")
6161 return strStatusBar;
6162 else if (strFor == "rpc")
6164 assert(!"GetWarnings(): invalid parameter");
6175 //////////////////////////////////////////////////////////////////////////////
6181 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
6187 assert(recentRejects);
6188 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
6190 // If the chain tip has changed previously rejected transactions
6191 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
6192 // or a double-spend. Reset the rejects filter and give those
6193 // txs a second chance.
6194 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
6195 recentRejects->reset();
6198 return recentRejects->contains(inv.hash) ||
6199 mempool.exists(inv.hash) ||
6200 mapOrphanTransactions.count(inv.hash) ||
6201 pcoinsTip->HaveCoins(inv.hash);
6204 return mapBlockIndex.count(inv.hash);
6206 // Don't know what it is, just say we already got one
6210 void static ProcessGetData(CNode* pfrom)
6212 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
6214 vector<CInv> vNotFound;
6218 while (it != pfrom->vRecvGetData.end()) {
6219 // Don't bother if send buffer is too full to respond anyway
6220 if (pfrom->nSendSize >= SendBufferSize())
6223 const CInv &inv = *it;
6225 boost::this_thread::interruption_point();
6228 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6231 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
6232 if (mi != mapBlockIndex.end())
6234 if (chainActive.Contains(mi->second)) {
6237 static const int nOneMonth = 30 * 24 * 60 * 60;
6238 // To prevent fingerprinting attacks, only send blocks outside of the active
6239 // chain if they are valid, and no more than a month older (both in time, and in
6240 // best equivalent proof of work) than the best header chain we know about.
6241 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
6242 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
6243 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
6245 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
6249 // Pruned nodes may have deleted the block, so check whether
6250 // it's available before trying to send.
6251 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
6253 // Send block from disk
6255 if (!ReadBlockFromDisk(block, (*mi).second,1))
6257 assert(!"cannot load block from disk");
6261 if (inv.type == MSG_BLOCK)
6263 //uint256 hash; int32_t z;
6264 //hash = block.GetHash();
6265 //for (z=31; z>=0; z--)
6266 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
6267 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
6268 pfrom->PushMessage("block", block);
6270 else // MSG_FILTERED_BLOCK)
6272 LOCK(pfrom->cs_filter);
6275 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
6276 pfrom->PushMessage("merkleblock", merkleBlock);
6277 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
6278 // This avoids hurting performance by pointlessly requiring a round-trip
6279 // Note that there is currently no way for a node to request any single transactions we didn't send here -
6280 // they must either disconnect and retry or request the full block.
6281 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
6282 // however we MUST always provide at least what the remote peer needs
6283 typedef std::pair<unsigned int, uint256> PairType;
6284 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
6285 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
6286 pfrom->PushMessage("tx", block.vtx[pair.first]);
6292 // Trigger the peer node to send a getblocks request for the next batch of inventory
6293 if (inv.hash == pfrom->hashContinue)
6295 // Bypass PushInventory, this must send even if redundant,
6296 // and we want it right after the last block so they don't
6297 // wait for other stuff first.
6299 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
6300 pfrom->PushMessage("inv", vInv);
6301 pfrom->hashContinue.SetNull();
6305 else if (inv.IsKnownType())
6307 // Send stream from relay memory
6308 bool pushed = false;
6311 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
6312 if (mi != mapRelay.end()) {
6313 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
6317 if (!pushed && inv.type == MSG_TX) {
6319 if (mempool.lookup(inv.hash, tx)) {
6320 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
6323 pfrom->PushMessage("tx", ss);
6328 vNotFound.push_back(inv);
6332 // Track requests for our stuff.
6333 GetMainSignals().Inventory(inv.hash);
6335 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6340 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
6342 if (!vNotFound.empty()) {
6343 // Let the peer know that we didn't find what it asked for, so it doesn't
6344 // have to wait around forever. Currently only SPV clients actually care
6345 // about this message: it's needed when they are recursively walking the
6346 // dependencies of relevant unconfirmed transactions. SPV clients want to
6347 // do that because they want to know about (and store and rebroadcast and
6348 // risk analyze) the dependencies of transactions relevant to them, without
6349 // having to download the entire memory pool.
6350 pfrom->PushMessage("notfound", vNotFound);
6354 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
6356 const CChainParams& chainparams = Params();
6357 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
6358 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
6359 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
6361 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
6365 //printf("netmsg: %s\n", strCommand.c_str());
6367 if (strCommand == "version")
6369 // Each connection can only send one version message
6370 if (pfrom->nVersion != 0)
6372 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
6373 Misbehaving(pfrom->GetId(), 1);
6380 uint64_t nNonce = 1;
6381 int nVersion; // use temporary for version, don't set version number until validated as connected
6382 vRecv >> nVersion >> pfrom->nServices >> nTime >> addrMe;
6383 if (nVersion == 10300)
6386 if (nVersion < MIN_PEER_PROTO_VERSION)
6388 // disconnect from peers older than this proto version
6389 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6390 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6391 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
6392 pfrom->fDisconnect = true;
6396 // Reject incoming connections from nodes that don't know about the current epoch
6397 const Consensus::Params& params = Params().GetConsensus();
6398 auto currentEpoch = CurrentEpoch(GetHeight(), params);
6399 if (nVersion < params.vUpgrades[currentEpoch].nProtocolVersion)
6401 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion);
6402 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6403 strprintf("Version must be %d or greater",
6404 params.vUpgrades[currentEpoch].nProtocolVersion));
6405 pfrom->fDisconnect = true;
6410 vRecv >> addrFrom >> nNonce;
6411 if (!vRecv.empty()) {
6412 vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
6413 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
6416 vRecv >> pfrom->nStartingHeight;
6418 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
6420 pfrom->fRelayTxes = true;
6422 // Disconnect if we connected to ourself
6423 if (nNonce == nLocalHostNonce && nNonce > 1)
6425 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
6426 pfrom->fDisconnect = true;
6430 pfrom->nVersion = nVersion;
6432 pfrom->addrLocal = addrMe;
6433 if (pfrom->fInbound && addrMe.IsRoutable())
6438 // Be shy and don't send version until we hear
6439 if (pfrom->fInbound)
6440 pfrom->PushVersion();
6442 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
6444 // Potentially mark this peer as a preferred download peer.
6445 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
6448 pfrom->PushMessage("verack");
6449 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6451 if (!pfrom->fInbound)
6453 // Advertise our address
6454 if (fListen && !IsInitialBlockDownload())
6456 CAddress addr = GetLocalAddress(&pfrom->addr);
6457 if (addr.IsRoutable())
6459 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6460 pfrom->PushAddress(addr);
6461 } else if (IsPeerAddrLocalGood(pfrom)) {
6462 addr.SetIP(pfrom->addrLocal);
6463 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6464 pfrom->PushAddress(addr);
6468 // Get recent addresses
6469 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
6471 pfrom->PushMessage("getaddr");
6472 pfrom->fGetAddr = true;
6474 addrman.Good(pfrom->addr);
6476 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
6478 addrman.Add(addrFrom, addrFrom);
6479 addrman.Good(addrFrom);
6486 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6487 item.second.RelayTo(pfrom);
6490 pfrom->fSuccessfullyConnected = true;
6494 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
6496 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
6497 pfrom->cleanSubVer, pfrom->nVersion,
6498 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
6501 int64_t nTimeOffset = nTime - GetTime();
6502 pfrom->nTimeOffset = nTimeOffset;
6503 AddTimeData(pfrom->addr, nTimeOffset);
6507 else if (pfrom->nVersion == 0)
6509 // Must have a version message before anything else
6510 Misbehaving(pfrom->GetId(), 1);
6515 else if (strCommand == "verack")
6517 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6519 // Mark this node as currently connected, so we update its timestamp later.
6520 if (pfrom->fNetworkNode) {
6522 State(pfrom->GetId())->fCurrentlyConnected = true;
6527 // Disconnect existing peer connection when:
6528 // 1. The version message has been received
6529 // 2. Peer version is below the minimum version for the current epoch
6530 else if (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[
6531 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion)
6533 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6534 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6535 strprintf("Version must be %d or greater",
6536 chainparams.GetConsensus().vUpgrades[
6537 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion));
6538 pfrom->fDisconnect = true;
6543 else if (strCommand == "addr")
6545 vector<CAddress> vAddr;
6548 // Don't want addr from older versions unless seeding
6549 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
6551 if (vAddr.size() > 1000)
6553 Misbehaving(pfrom->GetId(), 20);
6554 return error("message addr size() = %u", vAddr.size());
6557 // Store the new addresses
6558 vector<CAddress> vAddrOk;
6559 int64_t nNow = GetAdjustedTime();
6560 int64_t nSince = nNow - 10 * 60;
6561 BOOST_FOREACH(CAddress& addr, vAddr)
6563 boost::this_thread::interruption_point();
6565 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6566 addr.nTime = nNow - 5 * 24 * 60 * 60;
6567 pfrom->AddAddressKnown(addr);
6568 bool fReachable = IsReachable(addr);
6569 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
6571 // Relay to a limited number of other nodes
6574 // Use deterministic randomness to send to the same nodes for 24 hours
6575 // at a time so the addrKnowns of the chosen nodes prevent repeats
6576 static uint256 hashSalt;
6577 if (hashSalt.IsNull())
6578 hashSalt = GetRandHash();
6579 uint64_t hashAddr = addr.GetHash();
6580 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
6581 hashRand = Hash(BEGIN(hashRand), END(hashRand));
6582 multimap<uint256, CNode*> mapMix;
6583 BOOST_FOREACH(CNode* pnode, vNodes)
6585 if (pnode->nVersion < CADDR_TIME_VERSION)
6587 unsigned int nPointer;
6588 memcpy(&nPointer, &pnode, sizeof(nPointer));
6589 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
6590 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6591 mapMix.insert(make_pair(hashKey, pnode));
6593 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
6594 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6595 ((*mi).second)->PushAddress(addr);
6598 // Do not store addresses outside our network
6600 vAddrOk.push_back(addr);
6602 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
6603 if (vAddr.size() < 1000)
6604 pfrom->fGetAddr = false;
6605 if (pfrom->fOneShot)
6606 pfrom->fDisconnect = true;
6610 else if (strCommand == "inv")
6614 if (vInv.size() > MAX_INV_SZ)
6616 Misbehaving(pfrom->GetId(), 20);
6617 return error("message inv size() = %u", vInv.size());
6622 std::vector<CInv> vToFetch;
6624 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
6626 const CInv &inv = vInv[nInv];
6628 boost::this_thread::interruption_point();
6629 pfrom->AddInventoryKnown(inv);
6631 bool fAlreadyHave = AlreadyHave(inv);
6632 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
6634 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6637 if (inv.type == MSG_BLOCK) {
6638 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
6639 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
6640 // First request the headers preceding the announced block. In the normal fully-synced
6641 // case where a new block is announced that succeeds the current tip (no reorganization),
6642 // there are no such headers.
6643 // Secondly, and only when we are close to being synced, we request the announced block directly,
6644 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6645 // time the block arrives, the header chain leading up to it is already validated. Not
6646 // doing this will result in the received block being rejected as an orphan in case it is
6647 // not a direct successor.
6648 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
6649 CNodeState *nodestate = State(pfrom->GetId());
6650 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
6651 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6652 vToFetch.push_back(inv);
6653 // Mark block as in flight already, even though the actual "getdata" message only goes out
6654 // later (within the same cs_main lock, though).
6655 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
6657 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->GetHeight(), inv.hash.ToString(), pfrom->id);
6661 // Track requests for our stuff
6662 GetMainSignals().Inventory(inv.hash);
6664 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6665 Misbehaving(pfrom->GetId(), 50);
6666 return error("send buffer size() = %u", pfrom->nSendSize);
6670 if (!vToFetch.empty())
6671 pfrom->PushMessage("getdata", vToFetch);
6675 else if (strCommand == "getdata")
6679 if (vInv.size() > MAX_INV_SZ)
6681 Misbehaving(pfrom->GetId(), 20);
6682 return error("message getdata size() = %u", vInv.size());
6685 if (fDebug || (vInv.size() != 1))
6686 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
6688 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
6689 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
6691 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6692 ProcessGetData(pfrom);
6696 else if (strCommand == "getblocks")
6698 CBlockLocator locator;
6700 vRecv >> locator >> hashStop;
6704 // Find the last block the caller has in the main chain
6705 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
6707 // Send the rest of the chain
6709 pindex = chainActive.Next(pindex);
6711 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
6712 for (; pindex; pindex = chainActive.Next(pindex))
6714 if (pindex->GetBlockHash() == hashStop)
6716 LogPrint("net", " getblocks stopping at %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6719 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6722 // When this block is requested, we'll send an inv that'll
6723 // trigger the peer to getblocks the next batch of inventory.
6724 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6725 pfrom->hashContinue = pindex->GetBlockHash();
6732 else if (strCommand == "getheaders")
6734 CBlockLocator locator;
6736 vRecv >> locator >> hashStop;
6740 if (IsInitialBlockDownload())
6743 CBlockIndex* pindex = NULL;
6744 if (locator.IsNull())
6746 // If locator is null, return the hashStop block
6747 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6748 if (mi == mapBlockIndex.end())
6750 pindex = (*mi).second;
6754 // Find the last block the caller has in the main chain
6755 pindex = FindForkInGlobalIndex(chainActive, locator);
6757 pindex = chainActive.Next(pindex);
6760 // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6761 vector<CNetworkBlockHeader> vHeaders;
6762 int nLimit = MAX_HEADERS_RESULTS;
6763 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.ToString(), pfrom->id);
6764 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->GetHeight() : -1) )// no need to ever suppress this
6766 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->GetHeight() : -1);
6767 for (; pindex; pindex = chainActive.Next(pindex))
6769 CBlockHeader h = pindex->GetBlockHeader();
6770 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6771 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
6772 vHeaders.push_back(pindex->GetBlockHeader());
6773 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6776 pfrom->PushMessage("headers", vHeaders);
6778 /*else if ( IS_KOMODO_NOTARY != 0 )
6780 static uint32_t counter;
6781 if ( counter++ < 3 )
6782 fprintf(stderr,"you can ignore redundant getheaders from peer.%d %d prev.%d\n",(int32_t)pfrom->id,(int32_t)(pindex ? pindex->GetHeight() : -1),pfrom->lasthdrsreq);
6787 else if (strCommand == "tx")
6789 vector<uint256> vWorkQueue;
6790 vector<uint256> vEraseQueue;
6794 CInv inv(MSG_TX, tx.GetHash());
6795 pfrom->AddInventoryKnown(inv);
6799 bool fMissingInputs = false;
6800 CValidationState state;
6802 pfrom->setAskFor.erase(inv.hash);
6803 mapAlreadyAskedFor.erase(inv);
6805 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6807 mempool.check(pcoinsTip);
6808 RelayTransaction(tx);
6809 vWorkQueue.push_back(inv.hash);
6811 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6812 pfrom->id, pfrom->cleanSubVer,
6813 tx.GetHash().ToString(),
6814 mempool.mapTx.size());
6816 // Recursively process any orphan transactions that depended on this one
6817 set<NodeId> setMisbehaving;
6818 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6820 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6821 if (itByPrev == mapOrphanTransactionsByPrev.end())
6823 for (set<uint256>::iterator mi = itByPrev->second.begin();
6824 mi != itByPrev->second.end();
6827 const uint256& orphanHash = *mi;
6828 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6829 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6830 bool fMissingInputs2 = false;
6831 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6832 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6833 // anyone relaying LegitTxX banned)
6834 CValidationState stateDummy;
6837 if (setMisbehaving.count(fromPeer))
6839 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6841 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
6842 RelayTransaction(orphanTx);
6843 vWorkQueue.push_back(orphanHash);
6844 vEraseQueue.push_back(orphanHash);
6846 else if (!fMissingInputs2)
6849 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6851 // Punish peer that gave us an invalid orphan tx
6852 Misbehaving(fromPeer, nDos);
6853 setMisbehaving.insert(fromPeer);
6854 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6856 // Has inputs but not accepted to mempool
6857 // Probably non-standard or insufficient fee/priority
6858 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
6859 vEraseQueue.push_back(orphanHash);
6860 assert(recentRejects);
6861 recentRejects->insert(orphanHash);
6863 mempool.check(pcoinsTip);
6867 BOOST_FOREACH(uint256 hash, vEraseQueue)
6868 EraseOrphanTx(hash);
6870 // TODO: currently, prohibit joinsplits and shielded spends/outputs from entering mapOrphans
6871 else if (fMissingInputs &&
6872 tx.vjoinsplit.empty() &&
6873 tx.vShieldedSpend.empty() &&
6874 tx.vShieldedOutput.empty())
6876 // valid stake transactions end up in the orphan tx bin
6877 AddOrphanTx(tx, pfrom->GetId());
6879 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6880 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6881 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6883 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6885 assert(recentRejects);
6886 recentRejects->insert(tx.GetHash());
6888 if (pfrom->fWhitelisted) {
6889 // Always relay transactions received from whitelisted peers, even
6890 // if they were already in the mempool or rejected from it due
6891 // to policy, allowing the node to function as a gateway for
6892 // nodes hidden behind it.
6894 // Never relay transactions that we would assign a non-zero DoS
6895 // score for, as we expect peers to do the same with us in that
6898 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6899 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6900 RelayTransaction(tx);
6902 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6903 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6908 if (state.IsInvalid(nDoS))
6910 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6911 pfrom->id, pfrom->cleanSubVer,
6912 state.GetRejectReason());
6913 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6914 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6916 Misbehaving(pfrom->GetId(), nDoS);
6920 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6922 std::vector<CBlockHeader> headers;
6924 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6925 unsigned int nCount = ReadCompactSize(vRecv);
6926 if (nCount > MAX_HEADERS_RESULTS) {
6927 Misbehaving(pfrom->GetId(), 20);
6928 return error("headers message size = %u", nCount);
6930 headers.resize(nCount);
6931 for (unsigned int n = 0; n < nCount; n++) {
6932 vRecv >> headers[n];
6933 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6939 // Nothing interesting. Stop asking this peers for more headers.
6943 CBlockIndex *pindexLast = NULL;
6944 BOOST_FOREACH(const CBlockHeader& header, headers) {
6945 //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6946 //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
6948 CValidationState state;
6949 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6950 Misbehaving(pfrom->GetId(), 20);
6951 return error("non-continuous headers sequence");
6953 int32_t futureblock;
6954 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6956 if (state.IsInvalid(nDoS) && futureblock == 0)
6958 if (nDoS > 0 && futureblock == 0)
6959 Misbehaving(pfrom->GetId(), nDoS/nDoS);
6960 return error("invalid header received");
6966 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6968 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6969 // Headers message had its maximum size; the peer may have more headers.
6970 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6971 // from there instead.
6972 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->GetHeight() != pfrom->sendhdrsreq )
6974 pfrom->sendhdrsreq = (int32_t)pindexLast->GetHeight();
6975 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->GetHeight(), pfrom->id, pfrom->nStartingHeight);
6976 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6983 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6988 CInv inv(MSG_BLOCK, block.GetHash());
6989 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6991 pfrom->AddInventoryKnown(inv);
6993 CValidationState state;
6994 // Process all blocks from whitelisted peers, even if not requested,
6995 // unless we're still syncing with the network.
6996 // Such an unrequested block may still be processed, subject to the
6997 // conditions in AcceptBlock().
6998 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6999 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
7001 if (state.IsInvalid(nDoS)) {
7002 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
7003 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
7006 Misbehaving(pfrom->GetId(), nDoS);
7013 // This asymmetric behavior for inbound and outbound connections was introduced
7014 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
7015 // to users' AddrMan and later request them by sending getaddr messages.
7016 // Making nodes which are behind NAT and can only make outgoing connections ignore
7017 // the getaddr message mitigates the attack.
7018 else if ((strCommand == "getaddr") && (pfrom->fInbound))
7020 // Only send one GetAddr response per connection to reduce resource waste
7021 // and discourage addr stamping of INV announcements.
7022 if (pfrom->fSentAddr) {
7023 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
7026 pfrom->fSentAddr = true;
7028 pfrom->vAddrToSend.clear();
7029 vector<CAddress> vAddr = addrman.GetAddr();
7030 BOOST_FOREACH(const CAddress &addr, vAddr)
7031 pfrom->PushAddress(addr);
7035 else if (strCommand == "mempool")
7037 LOCK2(cs_main, pfrom->cs_filter);
7039 std::vector<uint256> vtxid;
7040 mempool.queryHashes(vtxid);
7042 BOOST_FOREACH(uint256& hash, vtxid) {
7043 CInv inv(MSG_TX, hash);
7044 if (pfrom->pfilter) {
7046 bool fInMemPool = mempool.lookup(hash, tx);
7047 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
7048 if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
7050 vInv.push_back(inv);
7051 if (vInv.size() == MAX_INV_SZ) {
7052 pfrom->PushMessage("inv", vInv);
7056 if (vInv.size() > 0)
7057 pfrom->PushMessage("inv", vInv);
7061 else if (strCommand == "ping")
7063 if (pfrom->nVersion > BIP0031_VERSION)
7067 // Echo the message back with the nonce. This allows for two useful features:
7069 // 1) A remote node can quickly check if the connection is operational
7070 // 2) Remote nodes can measure the latency of the network thread. If this node
7071 // is overloaded it won't respond to pings quickly and the remote node can
7072 // avoid sending us more work, like chain download requests.
7074 // The nonce stops the remote getting confused between different pings: without
7075 // it, if the remote node sends a ping once per second and this node takes 5
7076 // seconds to respond to each, the 5th ping the remote sends would appear to
7077 // return very quickly.
7078 pfrom->PushMessage("pong", nonce);
7083 else if (strCommand == "pong")
7085 int64_t pingUsecEnd = nTimeReceived;
7087 size_t nAvail = vRecv.in_avail();
7088 bool bPingFinished = false;
7089 std::string sProblem;
7091 if (nAvail >= sizeof(nonce)) {
7094 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
7095 if (pfrom->nPingNonceSent != 0) {
7096 if (nonce == pfrom->nPingNonceSent) {
7097 // Matching pong received, this ping is no longer outstanding
7098 bPingFinished = true;
7099 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
7100 if (pingUsecTime > 0) {
7101 // Successful ping time measurement, replace previous
7102 pfrom->nPingUsecTime = pingUsecTime;
7103 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
7105 // This should never happen
7106 sProblem = "Timing mishap";
7109 // Nonce mismatches are normal when pings are overlapping
7110 sProblem = "Nonce mismatch";
7112 // This is most likely a bug in another implementation somewhere; cancel this ping
7113 bPingFinished = true;
7114 sProblem = "Nonce zero";
7118 sProblem = "Unsolicited pong without ping";
7121 // This is most likely a bug in another implementation somewhere; cancel this ping
7122 bPingFinished = true;
7123 sProblem = "Short payload";
7126 if (!(sProblem.empty())) {
7127 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
7131 pfrom->nPingNonceSent,
7135 if (bPingFinished) {
7136 pfrom->nPingNonceSent = 0;
7141 else if (fAlerts && strCommand == "alert")
7146 uint256 alertHash = alert.GetHash();
7147 if (pfrom->setKnown.count(alertHash) == 0)
7149 if (alert.ProcessAlert(Params().AlertKey()))
7152 pfrom->setKnown.insert(alertHash);
7155 BOOST_FOREACH(CNode* pnode, vNodes)
7156 alert.RelayTo(pnode);
7160 // Small DoS penalty so peers that send us lots of
7161 // duplicate/expired/invalid-signature/whatever alerts
7162 // eventually get banned.
7163 // This isn't a Misbehaving(100) (immediate ban) because the
7164 // peer might be an older or different implementation with
7165 // a different signature key, etc.
7166 Misbehaving(pfrom->GetId(), 10);
7171 else if (!(nLocalServices & NODE_BLOOM) &&
7172 (strCommand == "filterload" ||
7173 strCommand == "filteradd"))
7175 if (pfrom->nVersion >= NO_BLOOM_VERSION) {
7176 Misbehaving(pfrom->GetId(), 100);
7178 } else if (GetBoolArg("-enforcenodebloom", false)) {
7179 pfrom->fDisconnect = true;
7185 else if (strCommand == "filterload")
7187 CBloomFilter filter;
7190 if (!filter.IsWithinSizeConstraints())
7191 // There is no excuse for sending a too-large filter
7192 Misbehaving(pfrom->GetId(), 100);
7195 LOCK(pfrom->cs_filter);
7196 delete pfrom->pfilter;
7197 pfrom->pfilter = new CBloomFilter(filter);
7198 pfrom->pfilter->UpdateEmptyFull();
7200 pfrom->fRelayTxes = true;
7204 else if (strCommand == "filteradd")
7206 vector<unsigned char> vData;
7209 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
7210 // and thus, the maximum size any matched object can have) in a filteradd message
7211 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
7213 Misbehaving(pfrom->GetId(), 100);
7215 LOCK(pfrom->cs_filter);
7217 pfrom->pfilter->insert(vData);
7219 Misbehaving(pfrom->GetId(), 100);
7224 else if (strCommand == "filterclear")
7226 LOCK(pfrom->cs_filter);
7227 if (nLocalServices & NODE_BLOOM) {
7228 delete pfrom->pfilter;
7229 pfrom->pfilter = new CBloomFilter();
7231 pfrom->fRelayTxes = true;
7235 else if (strCommand == "reject")
7239 string strMsg; unsigned char ccode; string strReason;
7240 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
7243 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
7245 if (strMsg == "block" || strMsg == "tx")
7249 ss << ": hash " << hash.ToString();
7251 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
7252 } catch (const std::ios_base::failure&) {
7253 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
7254 LogPrint("net", "Unparseable reject message received\n");
7258 else if (strCommand == "notfound") {
7259 // We do not care about the NOTFOUND message, but logging an Unknown Command
7260 // message would be undesirable as we transmit it ourselves.
7264 // Ignore unknown commands for extensibility
7265 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
7273 // requires LOCK(cs_vRecvMsg)
7274 bool ProcessMessages(CNode* pfrom)
7277 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
7281 // (4) message start
7289 if (!pfrom->vRecvGetData.empty())
7290 ProcessGetData(pfrom);
7292 // this maintains the order of responses
7293 if (!pfrom->vRecvGetData.empty()) return fOk;
7295 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
7296 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
7297 // Don't bother if send buffer is too full to respond anyway
7298 if (pfrom->nSendSize >= SendBufferSize())
7302 CNetMessage& msg = *it;
7305 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
7306 // msg.hdr.nMessageSize, msg.vRecv.size(),
7307 // msg.complete() ? "Y" : "N");
7309 // end, if an incomplete message is found
7310 if (!msg.complete())
7313 // at this point, any failure means we can delete the current message
7316 // Scan for message start
7317 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
7318 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
7324 CMessageHeader& hdr = msg.hdr;
7325 if (!hdr.IsValid(Params().MessageStart()))
7327 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
7330 string strCommand = hdr.GetCommand();
7333 unsigned int nMessageSize = hdr.nMessageSize;
7336 CDataStream& vRecv = msg.vRecv;
7337 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
7338 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
7339 if (nChecksum != hdr.nChecksum)
7341 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
7342 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
7350 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
7351 boost::this_thread::interruption_point();
7353 catch (const std::ios_base::failure& e)
7355 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
7356 if (strstr(e.what(), "end of data"))
7358 // Allow exceptions from under-length message on vRecv
7359 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());
7361 else if (strstr(e.what(), "size too large"))
7363 // Allow exceptions from over-long size
7364 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
7368 //PrintExceptionContinue(&e, "ProcessMessages()");
7371 catch (const boost::thread_interrupted&) {
7374 catch (const std::exception& e) {
7375 PrintExceptionContinue(&e, "ProcessMessages()");
7377 PrintExceptionContinue(NULL, "ProcessMessages()");
7381 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
7386 // In case the connection got shut down, its receive buffer was wiped
7387 if (!pfrom->fDisconnect)
7388 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
7394 bool SendMessages(CNode* pto, bool fSendTrickle)
7396 const Consensus::Params& consensusParams = Params().GetConsensus();
7398 // Don't send anything until we get its version message
7399 if (pto->nVersion == 0)
7405 bool pingSend = false;
7406 if (pto->fPingQueued) {
7407 // RPC ping request by user
7410 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
7411 // Ping automatically sent as a latency probe & keepalive.
7416 while (nonce == 0) {
7417 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
7419 pto->fPingQueued = false;
7420 pto->nPingUsecStart = GetTimeMicros();
7421 if (pto->nVersion > BIP0031_VERSION) {
7422 pto->nPingNonceSent = nonce;
7423 pto->PushMessage("ping", nonce);
7425 // Peer is too old to support ping command with nonce, pong will never arrive.
7426 pto->nPingNonceSent = 0;
7427 pto->PushMessage("ping");
7431 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
7435 // Address refresh broadcast
7436 static int64_t nLastRebroadcast;
7437 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
7440 BOOST_FOREACH(CNode* pnode, vNodes)
7442 // Periodically clear addrKnown to allow refresh broadcasts
7443 if (nLastRebroadcast)
7444 pnode->addrKnown.reset();
7446 // Rebroadcast our address
7447 AdvertizeLocal(pnode);
7449 if (!vNodes.empty())
7450 nLastRebroadcast = GetTime();
7458 vector<CAddress> vAddr;
7459 vAddr.reserve(pto->vAddrToSend.size());
7460 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
7462 if (!pto->addrKnown.contains(addr.GetKey()))
7464 pto->addrKnown.insert(addr.GetKey());
7465 vAddr.push_back(addr);
7466 // receiver rejects addr messages larger than 1000
7467 if (vAddr.size() >= 1000)
7469 pto->PushMessage("addr", vAddr);
7474 pto->vAddrToSend.clear();
7476 pto->PushMessage("addr", vAddr);
7479 CNodeState &state = *State(pto->GetId());
7480 if (state.fShouldBan) {
7481 if (pto->fWhitelisted)
7482 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
7484 pto->fDisconnect = true;
7485 if (pto->addr.IsLocal())
7486 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
7489 CNode::Ban(pto->addr);
7492 state.fShouldBan = false;
7495 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
7496 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
7497 state.rejects.clear();
7500 if (pindexBestHeader == NULL)
7501 pindexBestHeader = chainActive.Tip();
7502 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.
7503 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
7504 // Only actively request headers from a single peer, unless we're close to today.
7505 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
7506 state.fSyncStarted = true;
7508 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
7509 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->GetHeight(), pto->id, pto->nStartingHeight);
7510 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
7514 // Resend wallet transactions that haven't gotten in a block yet
7515 // Except during reindex, importing and IBD, when old wallet
7516 // transactions become unconfirmed and spams other nodes.
7517 if (!fReindex && !fImporting && !IsInitialBlockDownload())
7519 GetMainSignals().Broadcast(nTimeBestReceived);
7523 // Message: inventory
7526 vector<CInv> vInvWait;
7528 LOCK(pto->cs_inventory);
7529 vInv.reserve(pto->vInventoryToSend.size());
7530 vInvWait.reserve(pto->vInventoryToSend.size());
7531 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
7533 if (pto->setInventoryKnown.count(inv))
7536 // trickle out tx inv to protect privacy
7537 if (inv.type == MSG_TX && !fSendTrickle)
7539 // 1/4 of tx invs blast to all immediately
7540 static uint256 hashSalt;
7541 if (hashSalt.IsNull())
7542 hashSalt = GetRandHash();
7543 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
7544 hashRand = Hash(BEGIN(hashRand), END(hashRand));
7545 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
7549 vInvWait.push_back(inv);
7554 // returns true if wasn't already contained in the set
7555 if (pto->setInventoryKnown.insert(inv).second)
7557 vInv.push_back(inv);
7558 if (vInv.size() >= 1000)
7560 pto->PushMessage("inv", vInv);
7565 pto->vInventoryToSend = vInvWait;
7568 pto->PushMessage("inv", vInv);
7570 // Detect whether we're stalling
7571 int64_t nNow = GetTimeMicros();
7572 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7573 // Stalling only triggers when the block download window cannot move. During normal steady state,
7574 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7575 // should only happen during initial block download.
7576 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
7577 pto->fDisconnect = true;
7579 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
7580 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7581 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7582 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
7583 // to unreasonably increase our timeout.
7584 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7585 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7586 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7587 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7588 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7589 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7590 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
7591 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
7592 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7593 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7594 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7596 if (queuedBlock.nTimeDisconnect < nNow) {
7597 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7598 pto->fDisconnect = true;
7603 // Message: getdata (blocks)
7605 static uint256 zero;
7606 vector<CInv> vGetData;
7607 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
7608 vector<CBlockIndex*> vToDownload;
7609 NodeId staller = -1;
7610 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7611 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7612 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
7613 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
7614 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
7615 pindex->GetHeight(), pto->id);
7617 if (state.nBlocksInFlight == 0 && staller != -1) {
7618 if (State(staller)->nStallingSince == 0) {
7619 State(staller)->nStallingSince = nNow;
7620 LogPrint("net", "Stall started peer=%d\n", staller);
7624 /*CBlockIndex *pindex;
7625 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
7627 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7628 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7629 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7630 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
7631 komodo_requestedcount++;
7632 if ( komodo_requestedcount > 16 )
7634 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7635 komodo_requestedcount = 0;
7640 // Message: getdata (non-blocks)
7642 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
7644 const CInv& inv = (*pto->mapAskFor.begin()).second;
7645 if (!AlreadyHave(inv))
7648 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
7649 vGetData.push_back(inv);
7650 if (vGetData.size() >= 1000)
7652 pto->PushMessage("getdata", vGetData);
7656 //If we're not going to ask, don't expect a response.
7657 pto->setAskFor.erase(inv.hash);
7659 pto->mapAskFor.erase(pto->mapAskFor.begin());
7661 if (!vGetData.empty())
7662 pto->PushMessage("getdata", vGetData);
7668 std::string CBlockFileInfo::ToString() const {
7669 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));
7674 static class CMainCleanup
7680 BlockMap::iterator it1 = mapBlockIndex.begin();
7681 for (; it1 != mapBlockIndex.end(); it1++)
7682 delete (*it1).second;
7683 mapBlockIndex.clear();
7685 // orphan transactions
7686 mapOrphanTransactions.clear();
7687 mapOrphanTransactionsByPrev.clear();
7689 } instance_of_cmaincleanup;
7691 extern "C" const char* getDataDir()
7693 return GetDataDir().string().c_str();
7697 // Set default values of new CMutableTransaction based on consensus rules at given height.
7698 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7700 CMutableTransaction mtx;
7702 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7703 if (isOverwintered) {
7704 mtx.fOverwintered = true;
7705 mtx.nExpiryHeight = nHeight + expiryDelta;
7707 if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) {
7708 mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
7709 mtx.nVersion = SAPLING_TX_VERSION;
7711 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7712 mtx.nVersion = OVERWINTER_TX_VERSION;
7713 mtx.nExpiryHeight = std::min(
7715 static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));