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"
41 #include <unordered_map>
43 #include <boost/algorithm/string/replace.hpp>
44 #include <boost/filesystem.hpp>
45 #include <boost/filesystem/fstream.hpp>
46 #include <boost/math/distributions/poisson.hpp>
47 #include <boost/thread.hpp>
48 #include <boost/static_assert.hpp>
53 # error "Zcash cannot be compiled without assertions."
56 #include "librustzcash.h"
62 CCriticalSection cs_main;
63 extern uint8_t NOTARY_PUBKEY33[33];
64 extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING;
65 int32_t KOMODO_NEWBLOCKS;
66 int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
67 void komodo_broadcast(CBlock *pblock,int32_t limit);
69 BlockMap mapBlockIndex;
71 CBlockIndex *pindexBestHeader = NULL;
72 static int64_t nTimeBestReceived = 0;
73 CWaitableCriticalSection csBestBlock;
74 CConditionVariable cvBlockChange;
75 int nScriptCheckThreads = 0;
76 bool fExperimentalMode = false;
77 bool fImporting = false;
78 bool fReindex = false;
79 bool fTxIndex = false;
80 bool fAddressIndex = false;
81 bool fTimestampIndex = false;
82 bool fSpentIndex = false;
83 bool fHavePruned = false;
84 bool fPruneMode = false;
85 bool fIsBareMultisigStd = true;
86 bool fCheckBlockIndex = false;
87 bool fCheckpointsEnabled = true;
88 bool fCoinbaseEnforcedProtectionEnabled = true;
89 size_t nCoinCacheUsage = 5000 * 300;
90 uint64_t nPruneTarget = 0;
91 bool fAlerts = DEFAULT_ALERTS;
92 /* If the tip is older than this (in seconds), the node is considered to be in initial block download.
94 int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
96 unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
98 /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
99 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
101 CTxMemPool mempool(::minRelayTxFee);
107 map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
108 map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
109 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
112 * Returns true if there are nRequired or more blocks of minVersion or above
113 * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
115 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
116 static void CheckBlockIndex();
118 /** Constant stuff for coinbase transactions we create: */
119 CScript COINBASE_FLAGS;
121 const string strMessageMagic = "Komodo Signed Message:\n";
126 struct CBlockIndexWorkComparator
128 bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
129 // First sort by most total work, ...
130 if (pa->chainPower > pb->chainPower) return false;
131 if (pa->chainPower < pb->chainPower) return true;
133 // ... then by earliest time received, ...
134 if (pa->nSequenceId < pb->nSequenceId) return false;
135 if (pa->nSequenceId > pb->nSequenceId) return true;
137 // Use pointer address as tie breaker (should only happen with blocks
138 // loaded from disk, as those all have id 0).
139 if (pa < pb) return false;
140 if (pa > pb) return true;
147 CBlockIndex *pindexBestInvalid;
150 * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
151 * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
152 * missing the data for the block.
154 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
155 /** Number of nodes with fSyncStarted. */
156 int nSyncStarted = 0;
157 /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
158 * Pruned nodes may have entries where B is missing data.
160 multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
162 CCriticalSection cs_LastBlockFile;
163 std::vector<CBlockFileInfo> vinfoBlockFile;
164 int nLastBlockFile = 0;
165 /** Global flag to indicate we should check to see if there are
166 * block/undo files that should be deleted. Set on startup
167 * or if we allocate more file space when we're in prune mode
169 bool fCheckForPruning = false;
172 * Every received block is assigned a unique and increasing identifier, so we
173 * know which one to give priority in case of a fork.
175 CCriticalSection cs_nBlockSequenceId;
176 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
177 uint32_t nBlockSequenceId = 1;
180 * Sources of received blocks, saved to be able to send them reject
181 * messages or ban them when processing happens afterwards. Protected by
184 map<uint256, NodeId> mapBlockSource;
187 * Filter for transactions that were recently rejected by
188 * AcceptToMemoryPool. These are not rerequested until the chain tip
189 * changes, at which point the entire filter is reset. Protected by
192 * Without this filter we'd be re-requesting txs from each of our peers,
193 * increasing bandwidth consumption considerably. For instance, with 100
194 * peers, half of which relay a tx we don't accept, that might be a 50x
195 * bandwidth increase. A flooding attacker attempting to roll-over the
196 * filter using minimum-sized, 60byte, transactions might manage to send
197 * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
198 * two minute window to send invs to us.
200 * Decreasing the false positive rate is fairly cheap, so we pick one in a
201 * million to make it highly unlikely for users to have issues with this
206 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
207 uint256 hashRecentRejectsChainTip;
209 /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
212 CBlockIndex *pindex; //! Optional.
213 int64_t nTime; //! Time of "getdata" request in microseconds.
214 bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
215 int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
217 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
219 /** Number of blocks in flight with validated headers. */
220 int nQueuedValidatedHeaders = 0;
222 /** Number of preferable block download peers. */
223 int nPreferredDownload = 0;
225 /** Dirty block index entries. */
226 set<CBlockIndex*> setDirtyBlockIndex;
228 /** Dirty block file entries. */
229 set<int> setDirtyFileInfo;
232 //////////////////////////////////////////////////////////////////////////////
234 // Registration of network node signals.
239 struct CBlockReject {
240 unsigned char chRejectCode;
241 string strRejectReason;
246 * Maintain validation-specific state about nodes, protected by cs_main, instead
247 * by CNode's own locks. This simplifies asynchronous operation, where
248 * processing of incoming data is done after the ProcessMessage call returns,
249 * and we're no longer holding the node's locks.
252 //! The peer's address
254 //! Whether we have a fully established connection.
255 bool fCurrentlyConnected;
256 //! Accumulated misbehaviour score for this peer.
258 //! Whether this peer should be disconnected and banned (unless whitelisted).
260 //! String name of this peer (debugging/logging purposes).
262 //! List of asynchronously-determined block rejections to notify this peer about.
263 std::vector<CBlockReject> rejects;
264 //! The best known block we know this peer has announced.
265 CBlockIndex *pindexBestKnownBlock;
266 //! The hash of the last unknown block this peer has announced.
267 uint256 hashLastUnknownBlock;
268 //! The last full block we both have.
269 CBlockIndex *pindexLastCommonBlock;
270 //! Whether we've started headers synchronization with this peer.
272 //! Since when we're stalling block download progress (in microseconds), or 0.
273 int64_t nStallingSince;
274 list<QueuedBlock> vBlocksInFlight;
276 int nBlocksInFlightValidHeaders;
277 //! Whether we consider this a preferred download peer.
278 bool fPreferredDownload;
281 fCurrentlyConnected = false;
284 pindexBestKnownBlock = NULL;
285 hashLastUnknownBlock.SetNull();
286 pindexLastCommonBlock = NULL;
287 fSyncStarted = false;
290 nBlocksInFlightValidHeaders = 0;
291 fPreferredDownload = false;
295 /** Map maintaining per-node state. Requires cs_main. */
296 map<NodeId, CNodeState> mapNodeState;
299 CNodeState *State(NodeId pnode) {
300 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
301 if (it == mapNodeState.end())
308 return chainActive.LastTip()->GetHeight();
311 void UpdatePreferredDownload(CNode* node, CNodeState* state)
313 nPreferredDownload -= state->fPreferredDownload;
315 // Whether this node should be marked as a preferred download node.
316 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
318 nPreferredDownload += state->fPreferredDownload;
321 // Returns time at which to timeout block request (nTime in microseconds)
322 int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
324 return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
327 void InitializeNode(NodeId nodeid, const CNode *pnode) {
329 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
330 state.name = pnode->addrName;
331 state.address = pnode->addr;
334 void FinalizeNode(NodeId nodeid) {
336 CNodeState *state = State(nodeid);
338 if (state->fSyncStarted)
341 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
342 AddressCurrentlyConnected(state->address);
345 BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
346 mapBlocksInFlight.erase(entry.hash);
347 EraseOrphansFor(nodeid);
348 nPreferredDownload -= state->fPreferredDownload;
350 mapNodeState.erase(nodeid);
353 void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
355 /* int expired = pool.Expire(GetTime() - age);
357 LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
359 std::vector<uint256> vNoSpendsRemaining;
360 pool.TrimToSize(limit, &vNoSpendsRemaining);
361 BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
362 pcoinsTip->Uncache(removed);*/
366 // Returns a bool indicating whether we requested this block.
367 bool MarkBlockAsReceived(const uint256& hash) {
368 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
369 if (itInFlight != mapBlocksInFlight.end()) {
370 CNodeState *state = State(itInFlight->second.first);
371 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
372 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
373 state->vBlocksInFlight.erase(itInFlight->second.second);
374 state->nBlocksInFlight--;
375 state->nStallingSince = 0;
376 mapBlocksInFlight.erase(itInFlight);
383 void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
384 CNodeState *state = State(nodeid);
385 assert(state != NULL);
387 // Make sure it's not listed somewhere already.
388 MarkBlockAsReceived(hash);
390 int64_t nNow = GetTimeMicros();
391 QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
392 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
393 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
394 state->nBlocksInFlight++;
395 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
396 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
399 /** Check whether the last unknown block a peer advertized is not yet known. */
400 void ProcessBlockAvailability(NodeId nodeid) {
401 CNodeState *state = State(nodeid);
402 assert(state != NULL);
404 if (!state->hashLastUnknownBlock.IsNull()) {
405 BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
406 if (itOld != mapBlockIndex.end() && itOld->second->chainPower > CChainPower())
408 if (state->pindexBestKnownBlock == NULL || itOld->second->chainPower >= state->pindexBestKnownBlock->chainPower)
409 state->pindexBestKnownBlock = itOld->second;
410 state->hashLastUnknownBlock.SetNull();
415 /** Update tracking information about which blocks a peer is assumed to have. */
416 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
417 CNodeState *state = State(nodeid);
418 assert(state != NULL);
420 /*ProcessBlockAvailability(nodeid);
422 BlockMap::iterator it = mapBlockIndex.find(hash);
423 if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
424 // An actually better block was announced.
425 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
426 state->pindexBestKnownBlock = it->second;
429 // An unknown block was announced; just assume that the latest one is the best one.
430 state->hashLastUnknownBlock = hash;
434 /** Find the last common ancestor two blocks have.
435 * Both pa and pb must be non-NULL. */
436 CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
437 if (pa->GetHeight() > pb->GetHeight()) {
438 pa = pa->GetAncestor(pb->GetHeight());
439 } else if (pb->GetHeight() > pa->GetHeight()) {
440 pb = pb->GetAncestor(pa->GetHeight());
443 while (pa != pb && pa && pb) {
448 // Eventually all chain branches meet at the genesis block.
453 /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
454 * at most count entries. */
455 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
459 vBlocks.reserve(vBlocks.size() + count);
460 CNodeState *state = State(nodeid);
461 assert(state != NULL);
463 // Make sure pindexBestKnownBlock is up to date, we'll need it.
464 ProcessBlockAvailability(nodeid);
466 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->chainPower < chainActive.Tip()->chainPower) {
467 // This peer has nothing interesting.
471 if (state->pindexLastCommonBlock == NULL) {
472 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
473 // Guessing wrong in either direction is not a problem.
474 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->GetHeight(), chainActive.Height())];
477 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
478 // of its current tip anymore. Go back enough to fix that.
479 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
480 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
483 std::vector<CBlockIndex*> vToFetch;
484 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
485 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
486 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
487 // download that next block if the window were 1 larger.
488 int nWindowEnd = state->pindexLastCommonBlock->GetHeight() + BLOCK_DOWNLOAD_WINDOW;
489 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->GetHeight(), nWindowEnd + 1);
490 NodeId waitingfor = -1;
491 while (pindexWalk->GetHeight() < nMaxHeight) {
492 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
493 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
494 // as iterating over ~100 CBlockIndex* entries anyway.
495 int nToFetch = std::min(nMaxHeight - pindexWalk->GetHeight(), std::max<int>(count - vBlocks.size(), 128));
496 vToFetch.resize(nToFetch);
497 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->GetHeight() + nToFetch);
498 vToFetch[nToFetch - 1] = pindexWalk;
499 for (unsigned int i = nToFetch - 1; i > 0; i--) {
500 vToFetch[i - 1] = vToFetch[i]->pprev;
503 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
504 // are not yet downloaded and not in flight to vBlocks. In the meantime, update
505 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
506 // already part of our chain (and therefore don't need it even if pruned).
507 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
508 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
509 // We consider the chain that this peer is on invalid.
512 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
513 if (pindex->nChainTx)
514 state->pindexLastCommonBlock = pindex;
515 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
516 // The block is not already downloaded, and not yet in flight.
517 if (pindex->GetHeight() > nWindowEnd) {
518 // We reached the end of the window.
519 if (vBlocks.size() == 0 && waitingfor != nodeid) {
520 // We aren't able to fetch anything, but we would be if the download window was one larger.
521 nodeStaller = waitingfor;
525 vBlocks.push_back(pindex);
526 if (vBlocks.size() == count) {
529 } else if (waitingfor == -1) {
530 // This is the first already-in-flight block.
531 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
539 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
541 CNodeState *state = State(nodeid);
544 stats.nMisbehavior = state->nMisbehavior;
545 stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->GetHeight() : -1;
546 stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->GetHeight() : -1;
547 BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
549 stats.vHeightInFlight.push_back(queue.pindex->GetHeight());
554 void RegisterNodeSignals(CNodeSignals& nodeSignals)
556 nodeSignals.GetHeight.connect(&GetHeight);
557 nodeSignals.ProcessMessages.connect(&ProcessMessages);
558 nodeSignals.SendMessages.connect(&SendMessages);
559 nodeSignals.InitializeNode.connect(&InitializeNode);
560 nodeSignals.FinalizeNode.connect(&FinalizeNode);
563 void UnregisterNodeSignals(CNodeSignals& nodeSignals)
565 nodeSignals.GetHeight.disconnect(&GetHeight);
566 nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
567 nodeSignals.SendMessages.disconnect(&SendMessages);
568 nodeSignals.InitializeNode.disconnect(&InitializeNode);
569 nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
572 CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
574 // Find the first block the caller has in the main chain
575 BOOST_FOREACH(const uint256& hash, locator.vHave) {
576 BlockMap::iterator mi = mapBlockIndex.find(hash);
577 if (mi != mapBlockIndex.end())
579 CBlockIndex* pindex = (*mi).second;
580 if (pindex != 0 && chain.Contains(pindex))
582 if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
587 return chain.Genesis();
590 CCoinsViewCache *pcoinsTip = NULL;
591 CBlockTreeDB *pblocktree = NULL;
598 UniValue komodo_snapshot(int top)
602 UniValue result(UniValue::VOBJ);
605 if ( pblocktree != 0 ) {
606 result = pblocktree->Snapshot(top);
608 fprintf(stderr,"null pblocktree start with -addressindex=1\n");
611 fprintf(stderr,"getsnapshot requires -addressindex=1\n");
616 //////////////////////////////////////////////////////////////////////////////
618 // mapOrphanTransactions
621 bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
623 uint256 hash = tx.GetHash();
624 if (mapOrphanTransactions.count(hash))
627 // Ignore big transactions, to avoid a
628 // send-big-orphans memory exhaustion attack. If a peer has a legitimate
629 // large transaction with a missing parent then we assume
630 // it will rebroadcast it later, after the parent transaction(s)
631 // have been mined or received.
632 // 10,000 orphans, each of which is at most 5,000 bytes big is
633 // at most 500 megabytes of orphans:
634 unsigned int sz = GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
637 LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
641 mapOrphanTransactions[hash].tx = tx;
642 mapOrphanTransactions[hash].fromPeer = peer;
643 BOOST_FOREACH(const CTxIn& txin, tx.vin)
644 mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
646 LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
647 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
651 void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
653 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
654 if (it == mapOrphanTransactions.end())
656 BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
658 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
659 if (itPrev == mapOrphanTransactionsByPrev.end())
661 itPrev->second.erase(hash);
662 if (itPrev->second.empty())
663 mapOrphanTransactionsByPrev.erase(itPrev);
665 mapOrphanTransactions.erase(it);
668 void EraseOrphansFor(NodeId peer)
671 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
672 while (iter != mapOrphanTransactions.end())
674 map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
675 if (maybeErase->second.fromPeer == peer)
677 EraseOrphanTx(maybeErase->second.tx.GetHash());
681 if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
685 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
687 unsigned int nEvicted = 0;
688 while (mapOrphanTransactions.size() > nMaxOrphans)
690 // Evict a random orphan:
691 uint256 randomhash = GetRandHash();
692 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
693 if (it == mapOrphanTransactions.end())
694 it = mapOrphanTransactions.begin();
695 EraseOrphanTx(it->first);
702 bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
704 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
705 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
708 // Sapling standard rules apply
709 if (tx.nVersion > CTransaction::SAPLING_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SAPLING_MIN_CURRENT_VERSION) {
710 reason = "sapling-version";
713 } else if (overwinterActive) {
714 // Overwinter standard rules apply
715 if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
716 reason = "overwinter-version";
720 // Sprout standard rules apply
721 if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
727 BOOST_FOREACH(const CTxIn& txin, tx.vin)
729 // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
730 // keys. (remember the 520 byte limit on redeemScript size) That works
731 // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
732 // bytes of scriptSig, which we round off to 1650 bytes for some minor
733 // future-proofing. That's also enough to spend a 20-of-20
734 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
735 // considered standard)
736 if (txin.scriptSig.size() > 1650) {
737 reason = "scriptsig-size";
740 if (!txin.scriptSig.IsPushOnly()) {
741 reason = "scriptsig-not-pushonly";
746 unsigned int v=0,nDataOut = 0;
747 txnouttype whichType;
748 BOOST_FOREACH(const CTxOut& txout, tx.vout)
750 if (!::IsStandard(txout.scriptPubKey, whichType))
752 reason = "scriptpubkey";
753 //fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
757 if (whichType == TX_NULL_DATA)
759 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
761 reason = "opreturn too big";
765 //fprintf(stderr,"is OP_RETURN\n");
767 else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
768 reason = "bare-multisig";
770 } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) {
777 // only one OP_RETURN txout is permitted
779 reason = "multi-op-return";
786 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
789 if (tx.nLockTime == 0)
791 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
793 BOOST_FOREACH(const CTxIn& txin, tx.vin)
795 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)) )
799 else if (!txin.IsFinal())
801 //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
808 bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
810 if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
813 return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
816 bool CheckFinalTx(const CTransaction &tx, int flags)
818 AssertLockHeld(cs_main);
820 // By convention a negative value for flags indicates that the
821 // current network-enforced consensus rules should be used. In
822 // a future soft-fork scenario that would mean checking which
823 // rules would be enforced for the next block and setting the
824 // appropriate flags. At the present time no soft-forks are
825 // scheduled, so no flags are set.
826 flags = std::max(flags, 0);
828 // CheckFinalTx() uses chainActive.Height()+1 to evaluate
829 // nLockTime because when IsFinalTx() is called within
830 // CBlock::AcceptBlock(), the height of the block *being*
831 // evaluated is what is used. Thus if we want to know if a
832 // transaction can be part of the *next* block, we need to call
833 // IsFinalTx() with one more than chainActive.Height().
834 const int nBlockHeight = chainActive.Height() + 1;
836 // Timestamps on the other hand don't get any special treatment,
837 // because we can't know what timestamp the next block will have,
838 // and there aren't timestamp applications where it matters.
839 // However this changes once median past time-locks are enforced:
840 const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
841 ? chainActive.Tip()->GetMedianTimePast()
844 return IsFinalTx(tx, nBlockHeight, nBlockTime);
848 * Check transaction inputs to mitigate two
849 * potential denial-of-service attacks:
851 * 1. scriptSigs with extra data stuffed into them,
852 * not consumed by scriptPubKey (or P2SH script)
853 * 2. P2SH scripts with a crazy number of expensive
854 * CHECKSIG/CHECKMULTISIG operations
856 bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
859 return true; // Coinbases don't use vin normally
861 if (tx.IsCoinImport())
862 return tx.vin[0].scriptSig.IsCoinImport();
864 for (unsigned int i = 0; i < tx.vin.size(); i++)
866 const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
868 vector<vector<unsigned char> > vSolutions;
869 txnouttype whichType;
870 // get the scriptPubKey corresponding to this input:
871 const CScript& prevScript = prev.scriptPubKey;
872 //printf("Previous script: %s\n", prevScript.ToString().c_str());
874 if (!Solver(prevScript, whichType, vSolutions))
876 int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
877 if (nArgsExpected < 0)
880 // Transactions with extra stuff in their scriptSigs are
881 // non-standard. Note that this EvalScript() call will
882 // be quick, because if there are any operations
883 // beside "push data" in the scriptSig
884 // IsStandardTx() will have already returned false
885 // and this method isn't called.
886 vector<vector<unsigned char> > stack;
887 //printf("Checking script: %s\n", tx.vin[i].scriptSig.ToString().c_str());
888 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
891 if (whichType == TX_SCRIPTHASH)
895 CScript subscript(stack.back().begin(), stack.back().end());
896 vector<vector<unsigned char> > vSolutions2;
897 txnouttype whichType2;
898 if (Solver(subscript, whichType2, vSolutions2))
900 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
903 nArgsExpected += tmpExpected;
907 // Any other Script with less than 15 sigops OK:
908 unsigned int sigops = subscript.GetSigOpCount(true);
909 // ... extra data left on the stack after execution is OK, too:
910 return (sigops <= MAX_P2SH_SIGOPS);
914 if (stack.size() != (unsigned int)nArgsExpected)
921 unsigned int GetLegacySigOpCount(const CTransaction& tx)
923 unsigned int nSigOps = 0;
924 BOOST_FOREACH(const CTxIn& txin, tx.vin)
926 nSigOps += txin.scriptSig.GetSigOpCount(false);
928 BOOST_FOREACH(const CTxOut& txout, tx.vout)
930 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
935 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
937 if (tx.IsCoinBase() || tx.IsCoinImport())
940 unsigned int nSigOps = 0;
941 for (unsigned int i = 0; i < tx.vin.size(); i++)
943 const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
944 if (prevout.scriptPubKey.IsPayToScriptHash())
945 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
951 * Ensure that a coinbase transaction is structured according to the consensus rules of the
954 bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight)
956 // if time locks are on, ensure that this coin base is time locked exactly as it should be
957 if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) ||
958 (((nHeight >= 31680) || strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE))
960 CScriptID scriptHash;
962 // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that
963 // holds the full output script, which may include multisig, etc., but starts with
964 // the time lock verify of the correct time lock for this block height
965 if (tx.vout.size() == 2 &&
966 CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) &&
967 tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
968 tx.vout[1].scriptPubKey[0] == OP_RETURN)
971 std::vector<uint8_t> opretData = std::vector<uint8_t>();
972 CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
973 if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
975 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
978 CScriptExt opretScript = CScriptExt(&opretData[1], &opretData[opretData.size()]);
980 if (CScriptID(opretScript) == scriptHash &&
981 opretScript.IsCheckLockTimeVerify(&unlocktime) &&
982 komodo_block_unlocktime(nHeight) == unlocktime)
995 * Check a transaction contextually against a set of consensus rules valid at a given block height.
998 * 1. AcceptToMemoryPool calls CheckTransaction and this function.
999 * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
1000 * and ContextualCheckBlock (which calls this function).
1001 * 3. The isInitBlockDownload argument is only to assist with testing.
1003 bool ContextualCheckTransaction(
1004 const CTransaction& tx,
1005 CValidationState &state,
1008 bool (*isInitBlockDownload)())
1010 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
1011 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
1012 bool isSprout = !overwinterActive;
1014 // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
1015 if (isSprout && tx.fOverwintered) {
1016 return state.DoS(isInitBlockDownload() ? 0 : dosLevel,
1017 error("ContextualCheckTransaction(): ht.%d activates.%d dosLevel.%d overwinter is not active yet",
1018 nHeight, Params().GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight, dosLevel),
1019 REJECT_INVALID, "tx-overwinter-not-active");
1022 if (saplingActive) {
1023 // Reject transactions with valid version but missing overwintered flag
1024 if (tx.nVersion >= SAPLING_MIN_TX_VERSION && !tx.fOverwintered) {
1025 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwintered flag must be set"),
1026 REJECT_INVALID, "tx-overwintered-flag-not-set");
1029 // Reject transactions with non-Sapling version group ID
1030 if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1031 return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),
1032 REJECT_INVALID, "bad-sapling-tx-version-group-id");
1035 // Reject transactions with invalid version
1036 if (tx.fOverwintered && tx.nVersion < SAPLING_MIN_TX_VERSION ) {
1037 return state.DoS(100, error("CheckTransaction(): Sapling version too low"),
1038 REJECT_INVALID, "bad-tx-sapling-version-too-low");
1041 // Reject transactions with invalid version
1042 if (tx.fOverwintered && tx.nVersion > SAPLING_MAX_TX_VERSION ) {
1043 return state.DoS(100, error("CheckTransaction(): Sapling version too high"),
1044 REJECT_INVALID, "bad-tx-sapling-version-too-high");
1046 } else if (overwinterActive) {
1047 // Reject transactions with valid version but missing overwinter flag
1048 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
1049 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
1050 REJECT_INVALID, "tx-overwinter-flag-not-set");
1053 // Reject transactions with non-Overwinter version group ID
1054 if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1055 return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),
1056 REJECT_INVALID, "bad-overwinter-tx-version-group-id");
1059 // Reject transactions with invalid version
1060 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
1061 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
1062 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
1066 // Rules that apply to Overwinter or later:
1067 if (overwinterActive) {
1068 // Reject transactions intended for Sprout
1069 if (!tx.fOverwintered) {
1070 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
1071 REJECT_INVALID, "tx-overwinter-active");
1074 // Check that all transactions are unexpired
1075 if (IsExpiredTx(tx, nHeight)) {
1076 // Don't increase banscore if the transaction only just expired
1077 int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? dosLevel : 0;
1078 return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
1082 // Rules that apply before Sapling:
1083 if (!saplingActive) {
1085 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1086 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_BEFORE_SAPLING)
1087 return state.DoS(100, error("ContextualCheckTransaction(): size limits failed"),
1088 REJECT_INVALID, "bad-txns-oversize");
1091 uint256 dataToBeSigned;
1094 (!tx.vjoinsplit.empty() ||
1095 !tx.vShieldedSpend.empty() ||
1096 !tx.vShieldedOutput.empty()))
1098 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
1099 // Empty output script.
1102 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1103 } catch (std::logic_error ex) {
1104 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
1105 REJECT_INVALID, "error-computing-signature-hash");
1110 if (!(tx.IsMint() || tx.vjoinsplit.empty()))
1112 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
1114 // We rely on libsodium to check that the signature is canonical.
1115 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1116 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1117 dataToBeSigned.begin(), 32,
1118 tx.joinSplitPubKey.begin()
1120 return state.DoS(isInitBlockDownload() ? 0 : 100,
1121 error("CheckTransaction(): invalid joinsplit signature"),
1122 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1126 if (tx.IsCoinBase())
1128 if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1129 return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1130 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
1133 if (!tx.vShieldedSpend.empty() ||
1134 !tx.vShieldedOutput.empty())
1136 auto ctx = librustzcash_sapling_verification_ctx_init();
1138 for (const SpendDescription &spend : tx.vShieldedSpend) {
1139 if (!librustzcash_sapling_check_spend(
1142 spend.anchor.begin(),
1143 spend.nullifier.begin(),
1145 spend.zkproof.begin(),
1146 spend.spendAuthSig.begin(),
1147 dataToBeSigned.begin()
1150 librustzcash_sapling_verification_ctx_free(ctx);
1151 return state.DoS(100, error("ContextualCheckTransaction(): Sapling spend description invalid"),
1152 REJECT_INVALID, "bad-txns-sapling-spend-description-invalid");
1156 for (const OutputDescription &output : tx.vShieldedOutput) {
1157 if (!librustzcash_sapling_check_output(
1161 output.ephemeralKey.begin(),
1162 output.zkproof.begin()
1165 librustzcash_sapling_verification_ctx_free(ctx);
1166 return state.DoS(100, error("ContextualCheckTransaction(): Sapling output description invalid"),
1167 REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
1171 if (!librustzcash_sapling_final_check(
1174 tx.bindingSig.begin(),
1175 dataToBeSigned.begin()
1178 librustzcash_sapling_verification_ctx_free(ctx);
1179 return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
1180 REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
1183 librustzcash_sapling_verification_ctx_free(ctx);
1188 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1189 libzcash::ProofVerifier& verifier)
1191 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1192 if ( *(int32_t *)&array[0] == 0 )
1193 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1197 for (k=0; k<numbanned; k++)
1199 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1201 static uint32_t counter;
1202 if ( counter++ < 100 )
1203 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->GetHeight(),j);
1208 // Don't count coinbase transactions because mining skews the count
1209 if (!tx.IsCoinBase()) {
1210 transactionsValidated.increment();
1213 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1216 // Ensure that zk-SNARKs v|| y
1217 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1218 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1219 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1220 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1227 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1229 // Basic checks that don't depend on any context
1233 * 1. The consensus rule below was:
1234 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1235 * which checked if tx.nVersion fell within the range:
1236 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1237 * 2. The parser allowed tx.nVersion to be negative
1240 * 1. The consensus rule checks to see if tx.Version falls within the range:
1241 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1242 * 2. The previous consensus rule checked for negative values within the range:
1243 * INT32_MIN <= tx.nVersion < 0
1244 * This is unnecessary for Overwinter transactions since the parser now
1245 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1246 * and when Overwinter is not active ContextualCheckTransaction rejects
1247 * transactions with fOverwintered set. When fOverwintered is set,
1248 * this function and ContextualCheckTransaction will together check to
1249 * ensure tx.nVersion avoids the following ranges:
1250 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1251 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1253 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1254 return state.DoS(100, error("CheckTransaction(): version too low"),
1255 REJECT_INVALID, "bad-txns-version-too-low");
1257 else if (tx.fOverwintered) {
1258 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1259 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1260 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1262 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID &&
1263 tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1264 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1265 REJECT_INVALID, "bad-tx-version-group-id");
1267 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1268 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1269 REJECT_INVALID, "bad-tx-expiry-height-too-high");
1273 // Transactions containing empty `vin` must have either non-empty
1274 // `vjoinsplit` or non-empty `vShieldedSpend`.
1275 if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
1276 return state.DoS(10, error("CheckTransaction(): vin empty"),
1277 REJECT_INVALID, "bad-txns-vin-empty");
1278 // Transactions containing empty `vout` must have either non-empty
1279 // `vjoinsplit` or non-empty `vShieldedOutput`.
1280 if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
1281 return state.DoS(10, error("CheckTransaction(): vout empty"),
1282 REJECT_INVALID, "bad-txns-vout-empty");
1285 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE >= MAX_TX_SIZE_AFTER_SAPLING); // sanity
1286 BOOST_STATIC_ASSERT(MAX_TX_SIZE_AFTER_SAPLING > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1287 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_AFTER_SAPLING)
1288 return state.DoS(100, error("CheckTransaction(): size limits failed"),
1289 REJECT_INVALID, "bad-txns-oversize");
1291 // Check for negative or overflow output values
1292 CAmount nValueOut = 0;
1293 int32_t iscoinbase = tx.IsCoinBase();
1294 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1296 if (txout.nValue < 0)
1297 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1298 REJECT_INVALID, "bad-txns-vout-negative");
1299 if (txout.nValue > MAX_MONEY)
1301 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1302 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1304 if ( ASSETCHAINS_PRIVATE != 0 )
1306 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
1307 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetValueOut() > 0 )
1308 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
1310 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
1311 return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative");
1312 nValueOut += txout.nValue;
1313 if (!MoneyRange(nValueOut))
1314 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1315 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1318 // Check for non-zero valueBalance when there are no Sapling inputs or outputs
1319 if (tx.vShieldedSpend.empty() && tx.vShieldedOutput.empty() && tx.valueBalance != 0) {
1320 return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"),
1321 REJECT_INVALID, "bad-txns-valuebalance-nonzero");
1324 // Check for overflow valueBalance
1325 if (tx.valueBalance > MAX_MONEY || tx.valueBalance < -MAX_MONEY) {
1326 return state.DoS(100, error("CheckTransaction(): abs(tx.valueBalance) too large"),
1327 REJECT_INVALID, "bad-txns-valuebalance-toolarge");
1330 if (tx.valueBalance <= 0) {
1331 // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
1332 nValueOut += -tx.valueBalance;
1334 if (!MoneyRange(nValueOut)) {
1335 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1336 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1340 // Ensure that joinsplit values are well-formed
1341 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1343 if ( ASSETCHAINS_PUBLIC != 0 )
1345 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1346 REJECT_INVALID, "bad-txns-acprivacy-chain");
1348 if (joinsplit.vpub_old < 0) {
1349 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1350 REJECT_INVALID, "bad-txns-vpub_old-negative");
1353 if (joinsplit.vpub_new < 0) {
1354 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1355 REJECT_INVALID, "bad-txns-vpub_new-negative");
1358 if (joinsplit.vpub_old > MAX_MONEY) {
1359 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1360 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1363 if (joinsplit.vpub_new > MAX_MONEY) {
1364 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1365 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1368 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1369 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1370 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1373 nValueOut += joinsplit.vpub_old;
1374 if (!MoneyRange(nValueOut)) {
1375 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1376 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1380 // Ensure input values do not exceed MAX_MONEY
1381 // We have not resolved the txin values at this stage,
1382 // but we do know what the joinsplits claim to add
1383 // to the value pool.
1385 CAmount nValueIn = 0;
1386 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1388 nValueIn += it->vpub_new;
1390 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1391 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1392 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1396 // Also check for Sapling
1397 if (tx.valueBalance >= 0) {
1398 // NB: positive valueBalance "adds" money to the transparent value pool, just as inputs do
1399 nValueIn += tx.valueBalance;
1401 if (!MoneyRange(nValueIn)) {
1402 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1403 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1408 // Check for duplicate inputs
1409 set<COutPoint> vInOutPoints;
1410 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1412 if (vInOutPoints.count(txin.prevout))
1413 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1414 REJECT_INVALID, "bad-txns-inputs-duplicate");
1415 vInOutPoints.insert(txin.prevout);
1418 // Check for duplicate joinsplit nullifiers in this transaction
1420 set<uint256> vJoinSplitNullifiers;
1421 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1423 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1425 if (vJoinSplitNullifiers.count(nf))
1426 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1427 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1429 vJoinSplitNullifiers.insert(nf);
1434 // Check for duplicate sapling nullifiers in this transaction
1436 set<uint256> vSaplingNullifiers;
1437 BOOST_FOREACH(const SpendDescription& spend_desc, tx.vShieldedSpend)
1439 if (vSaplingNullifiers.count(spend_desc.nullifier))
1440 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1441 REJECT_INVALID, "bad-spend-description-nullifiers-duplicate");
1443 vSaplingNullifiers.insert(spend_desc.nullifier);
1449 // There should be no joinsplits in a coinbase transaction
1450 if (tx.vjoinsplit.size() > 0)
1451 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1452 REJECT_INVALID, "bad-cb-has-joinsplits");
1454 // A coinbase transaction cannot have spend descriptions or output descriptions
1455 if (tx.vShieldedSpend.size() > 0)
1456 return state.DoS(100, error("CheckTransaction(): coinbase has spend descriptions"),
1457 REJECT_INVALID, "bad-cb-has-spend-description");
1458 if (tx.vShieldedOutput.size() > 0)
1459 return state.DoS(100, error("CheckTransaction(): coinbase has output descriptions"),
1460 REJECT_INVALID, "bad-cb-has-output-description");
1462 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1463 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1464 REJECT_INVALID, "bad-cb-length");
1468 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1469 if (txin.prevout.IsNull())
1470 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1471 REJECT_INVALID, "bad-txns-prevout-null");
1477 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1479 extern int32_t KOMODO_ON_DEMAND;
1482 uint256 hash = tx.GetHash();
1483 double dPriorityDelta = 0;
1484 CAmount nFeeDelta = 0;
1485 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1486 if (dPriorityDelta > 0 || nFeeDelta > 0)
1490 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1494 // There is a free transaction area in blocks created by most miners,
1495 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1496 // to be considered to fall into this category. We don't want to encourage sending
1497 // multiple transactions instead of one big transaction to avoid fees.
1498 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1502 if (!MoneyRange(nMinFee))
1503 nMinFee = MAX_MONEY;
1508 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
1510 AssertLockHeld(cs_main);
1511 if (pfMissingInputs)
1512 *pfMissingInputs = false;
1514 int flag=0,nextBlockHeight = chainActive.Height() + 1;
1515 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1517 // Node operator can choose to reject tx by number of transparent inputs
1518 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1519 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1520 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
1524 size_t n = tx.vin.size();
1526 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1531 auto verifier = libzcash::ProofVerifier::Strict();
1532 if ( komodo_validate_interest(tx,chainActive.LastTip()->GetHeight()+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
1534 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1535 return error("AcceptToMemoryPool: komodo_validate_interest failed");
1537 if (!CheckTransaction(tx, state, verifier))
1539 return error("AcceptToMemoryPool: CheckTransaction failed");
1541 // DoS level set to 10 to be more forgiving.
1542 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1543 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10))
1545 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1548 // Coinbase is only valid in a block, not as a loose transaction
1549 if (tx.IsCoinBase())
1551 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1552 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1554 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1556 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1558 //fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
1559 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1561 // Only accept nLockTime-using transactions that can be mined in the next
1562 // block; we don't want our mempool filled up with transactions that can't
1564 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1566 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1567 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1569 // is it already in the memory pool?
1570 uint256 hash = tx.GetHash();
1571 if (pool.exists(hash))
1573 //fprintf(stderr,"already in mempool\n");
1574 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
1577 // Check for conflicts with in-memory transactions
1579 LOCK(pool.cs); // protect pool.mapNextTx
1580 for (unsigned int i = 0; i < tx.vin.size(); i++)
1582 COutPoint outpoint = tx.vin[i].prevout;
1583 if (pool.mapNextTx.count(outpoint))
1585 // Disable replacement feature for now
1589 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1590 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
1591 if (pool.nullifierExists(nf, SPROUT)) {
1592 fprintf(stderr,"pool.mapNullifiers.count\n");
1597 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
1598 if (pool.nullifierExists(spendDescription.nullifier, SAPLING)) {
1606 CCoinsViewCache view(&dummy);
1608 CAmount nValueIn = 0;
1611 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1612 view.SetBackend(viewMemPool);
1614 // do we already have it?
1615 if (view.HaveCoins(hash))
1617 //fprintf(stderr,"view.HaveCoins(hash) error\n");
1618 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
1621 if (tx.IsCoinImport())
1623 // Inverse of normal case; if input exists, it's been spent
1624 if (ExistsImportTombstone(tx, view))
1625 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
1629 // do all inputs exist?
1630 // Note that this does not check for the presence of actual outputs (see the next check for that),
1631 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1632 BOOST_FOREACH(const CTxIn txin, tx.vin)
1634 if (!view.HaveCoins(txin.prevout.hash))
1636 if (pfMissingInputs)
1637 *pfMissingInputs = true;
1638 //fprintf(stderr,"missing inputs\n");
1643 // are the actual inputs available?
1644 if (!view.HaveInputs(tx))
1646 //fprintf(stderr,"accept failure.1\n");
1647 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1650 // are the joinsplit's requirements met?
1651 if (!view.HaveJoinSplitRequirements(tx))
1653 //fprintf(stderr,"accept failure.2\n");
1654 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1657 // Bring the best block into scope
1658 view.GetBestBlock();
1660 nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
1661 if ( 0 && interest != 0 )
1662 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1663 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1664 view.SetBackend(dummy);
1667 // Check for non-standard pay-to-script-hash in inputs
1668 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1669 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1671 // Check that the transaction doesn't have an excessive number of
1672 // sigops, making it impossible to mine. Since the coinbase transaction
1673 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1674 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1675 // merely non-standard transaction.
1676 unsigned int nSigOps = GetLegacySigOpCount(tx);
1677 nSigOps += GetP2SHSigOpCount(tx, view);
1678 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1680 fprintf(stderr,"accept failure.4\n");
1681 return state.DoS(0, error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
1684 CAmount nValueOut = tx.GetValueOut();
1685 CAmount nFees = nValueIn-nValueOut;
1686 double dPriority = view.GetPriority(tx, chainActive.Height());
1688 // Keep track of transactions that spend a coinbase, which we re-scan
1689 // during reorgs to ensure COINBASE_MATURITY is still met.
1690 bool fSpendsCoinbase = false;
1691 if (!tx.IsCoinImport()) {
1692 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1693 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1694 if (coins->IsCoinBase()) {
1695 fSpendsCoinbase = true;
1701 // Grab the branch ID we expect this transaction to commit to. We don't
1702 // yet know if it does, but if the entry gets added to the mempool, then
1703 // it has passed ContextualCheckInputs and therefore this is correct.
1704 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1706 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1707 unsigned int nSize = entry.GetTxSize();
1709 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1710 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1711 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1713 // Don't accept it if it can't get into a block
1714 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1715 if (fLimitFree && nFees < txMinFee)
1717 //fprintf(stderr,"accept failure.5\n");
1718 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1722 // Require that free transactions have sufficient priority to be mined in the next block.
1723 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1724 fprintf(stderr,"accept failure.6\n");
1725 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1728 // Continuously rate-limit free (really, very-low-fee) transactions
1729 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1730 // be annoying or make others' transactions take longer to confirm.
1731 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1733 static CCriticalSection csFreeLimiter;
1734 static double dFreeCount;
1735 static int64_t nLastTime;
1736 int64_t nNow = GetTime();
1738 LOCK(csFreeLimiter);
1740 // Use an exponentially decaying ~10-minute window:
1741 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1743 // -limitfreerelay unit is thousand-bytes-per-minute
1744 // At default rate it would take over a month to fill 1GB
1745 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1747 fprintf(stderr,"accept failure.7\n");
1748 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1750 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1751 dFreeCount += nSize;
1754 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
1756 string errmsg = strprintf("absurdly high fees %s, %d > %d",
1758 nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1759 LogPrint("mempool", errmsg.c_str());
1760 return state.Error("AcceptToMemoryPool: " + errmsg);
1763 // Check against previous transactions
1764 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1765 PrecomputedTransactionData txdata(tx);
1766 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1768 //fprintf(stderr,"accept failure.9\n");
1769 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1772 // Check again against just the consensus-critical mandatory script
1773 // verification flags, in case of bugs in the standard flags that cause
1774 // transactions to pass as valid when they're actually invalid. For
1775 // instance the STRICTENC flag was incorrectly allowing certain
1776 // CHECKSIG NOT scripts to pass, even though they were invalid.
1778 // There is a similar check in CreateNewBlock() to prevent creating
1779 // invalid blocks, however allowing such transactions into the mempool
1780 // can be exploited as a DoS attack.
1781 // XXX: is this neccesary for CryptoConditions?
1782 if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 )
1785 KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
1787 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1790 KOMODO_CONNECTING = -1;
1791 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1794 KOMODO_CONNECTING = -1;
1796 // Store transaction in memory
1797 if ( komodo_is_notarytx(tx) == 0 )
1799 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1801 if (!tx.IsCoinImport())
1803 // Add memory address index
1804 if (fAddressIndex) {
1805 pool.addAddressIndex(entry, view);
1808 // Add memory spent index
1810 pool.addSpentIndex(entry, view);
1815 SyncWithWallets(tx, NULL);
1820 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1822 if (!fTimestampIndex)
1823 return error("Timestamp index not enabled");
1825 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1826 return error("Unable to get hashes for timestamps");
1831 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1836 if (mempool.getSpentIndex(key, value))
1839 if (!pblocktree->ReadSpentIndex(key, value))
1845 bool GetAddressIndex(uint160 addressHash, int type,
1846 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1849 return error("address index not enabled");
1851 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1852 return error("unable to get txids for address");
1857 bool GetAddressUnspent(uint160 addressHash, int type,
1858 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1861 return error("address index not enabled");
1863 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1864 return error("unable to get txids for address");
1869 /*uint64_t myGettxout(uint256 hash,int32_t n)
1872 LOCK2(cs_main,mempool.cs);
1873 CCoinsViewMemPool view(pcoinsTip, mempool);
1874 if (!view.GetCoins(hash, coins))
1876 if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
1878 else return(coins.vout[n].nValue);
1881 bool myAddtomempool(CTransaction &tx)
1883 CValidationState state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
1884 if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
1885 return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
1889 bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1891 // need a GetTransaction without lock so the validation code for assets can run without deadlock
1893 //fprintf(stderr,"check mempool\n");
1894 if (mempool.lookup(hash, txOut))
1896 //fprintf(stderr,"found in mempool\n");
1900 //fprintf(stderr,"check disk\n");
1904 //fprintf(stderr,"ReadTxIndex\n");
1905 if (pblocktree->ReadTxIndex(hash, postx)) {
1906 //fprintf(stderr,"OpenBlockFile\n");
1907 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1909 return error("%s: OpenBlockFile failed", __func__);
1910 CBlockHeader header;
1911 //fprintf(stderr,"seek and read\n");
1914 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1916 } catch (const std::exception& e) {
1917 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1919 hashBlock = header.GetHash();
1920 if (txOut.GetHash() != hash)
1921 return error("%s: txid mismatch", __func__);
1922 //fprintf(stderr,"found on disk\n");
1926 //fprintf(stderr,"not found\n");
1930 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1931 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1933 CBlockIndex *pindexSlow = NULL;
1937 if (mempool.lookup(hash, txOut))
1944 if (pblocktree->ReadTxIndex(hash, postx)) {
1945 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1947 return error("%s: OpenBlockFile failed", __func__);
1948 CBlockHeader header;
1951 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1953 } catch (const std::exception& e) {
1954 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1956 hashBlock = header.GetHash();
1957 if (txOut.GetHash() != hash)
1958 return error("%s: txid mismatch", __func__);
1963 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1966 CCoinsViewCache &view = *pcoinsTip;
1967 const CCoins* coins = view.AccessCoins(hash);
1969 nHeight = coins->nHeight;
1972 pindexSlow = chainActive[nHeight];
1977 if (ReadBlockFromDisk(block, pindexSlow,1)) {
1978 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1979 if (tx.GetHash() == hash) {
1981 hashBlock = pindexSlow->GetBlockHash();
1991 /*char *komodo_getspendscript(uint256 hash,int32_t n)
1993 CTransaction tx; uint256 hashBlock;
1994 if ( !GetTransaction(hash,tx,hashBlock,true) )
1996 printf("null GetTransaction\n");
1999 if ( n >= 0 && n < tx.vout.size() )
2000 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
2001 else printf("getspendscript illegal n.%d\n",n);
2006 //////////////////////////////////////////////////////////////////////////////
2008 // CBlock and CBlockIndex
2011 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
2013 // Open history file to append
2014 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
2015 if (fileout.IsNull())
2016 return error("WriteBlockToDisk: OpenBlockFile failed");
2018 // Write index header
2019 unsigned int nSize = GetSerializeSize(fileout, block);
2020 fileout << FLATDATA(messageStart) << nSize;
2023 long fileOutPos = ftell(fileout.Get());
2025 return error("WriteBlockToDisk: ftell failed");
2026 pos.nPos = (unsigned int)fileOutPos;
2032 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
2034 uint8_t pubkey33[33];
2037 // Open history file to read
2038 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
2039 if (filein.IsNull())
2041 //fprintf(stderr,"readblockfromdisk err A\n");
2042 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
2049 catch (const std::exception& e) {
2050 fprintf(stderr,"readblockfromdisk err B\n");
2051 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
2054 if ( 0 && checkPOW != 0 )
2056 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
2057 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
2059 int32_t i; for (i=0; i<33; i++)
2060 fprintf(stderr,"%02x",pubkey33[i]);
2061 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
2063 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
2069 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
2073 if (!ReadBlockFromDisk(pindex->GetHeight(),block, pindex->GetBlockPos(),checkPOW))
2075 if (block.GetHash() != pindex->GetBlockHash())
2076 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
2077 pindex->ToString(), pindex->GetBlockPos().ToString());
2081 //uint64_t komodo_moneysupply(int32_t height);
2082 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
2083 extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
2084 extern uint32_t ASSETCHAINS_MAGIC;
2085 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
2086 extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
2088 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
2090 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
2091 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2094 return(100000000 * COIN); // ICO allocation
2095 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
2101 return(komodo_ac_block_subsidy(nHeight));
2104 // Mining slow start
2105 // The subsidy is ramped up linearly, skipping the middle payout of
2106 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
2107 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
2108 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2109 nSubsidy *= nHeight;
2111 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
2112 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2113 nSubsidy *= (nHeight+1);
2117 assert(nHeight > consensusParams.SubsidySlowStartShift());
2118 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
2119 // Force block reward to zero when right shift is undefined.
2120 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
2121 //if (halvings >= 64)
2124 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
2125 //nSubsidy >>= halvings;
2129 bool IsInitialBlockDownload()
2131 const CChainParams& chainParams = Params();
2133 // Once this function has returned false, it must remain false.
2134 static std::atomic<bool> latchToFalse{false};
2135 // Optimization: pre-test latch before taking the lock.
2136 if (latchToFalse.load(std::memory_order_relaxed))
2140 if (latchToFalse.load(std::memory_order_relaxed))
2143 if (fImporting || fReindex)
2145 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2149 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2151 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload - %d blocks\n", Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2156 arith_uint256 bigZero = arith_uint256();
2157 arith_uint256 minWork = UintToArith256(chainParams.GetConsensus().nMinimumChainWork);
2158 CBlockIndex *ptr = chainActive.Tip();
2162 if (ptr->chainPower < CChainPower(ptr, bigZero, minWork))
2165 state = ((chainActive.Height() < ptr->GetHeight() - 24*60) ||
2166 ptr->GetBlockTime() < (GetTime() - nMaxTipAge));
2168 //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()));
2171 LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
2172 latchToFalse.store(true, std::memory_order_relaxed);
2177 // determine if we are in sync with the best chain
2180 const CChainParams& chainParams = Params();
2183 if (fImporting || fReindex)
2185 //fprintf(stderr,"IsInSync: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2188 if (fCheckpointsEnabled)
2190 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2192 //fprintf(stderr,"IsInSync: checkpoint -> initialdownload chainActive.Height().%d GetTotalBlocksEstimate(chainParams.Checkpoints().%d\n", chainActive.Height(), Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2197 CBlockIndex *pbi = chainActive.Tip();
2198 int longestchain = komodo_longestchain();
2200 (pindexBestHeader == 0) ||
2201 ((pindexBestHeader->GetHeight() - 1) > pbi->GetHeight()) ||
2202 (longestchain != 0 && longestchain > pbi->GetHeight()) )
2208 static bool fLargeWorkForkFound = false;
2209 static bool fLargeWorkInvalidChainFound = false;
2210 static CBlockIndex *pindexBestForkTip = NULL;
2211 static CBlockIndex *pindexBestForkBase = NULL;
2213 void CheckForkWarningConditions()
2215 AssertLockHeld(cs_main);
2216 // Before we get past initial download, we cannot reliably alert about forks
2217 // (we assume we don't get stuck on a fork before finishing our initial sync)
2218 if (IsInitialBlockDownload())
2221 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
2222 // of our head, drop it
2223 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->GetHeight() >= 288)
2224 pindexBestForkTip = NULL;
2226 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->chainPower > (chainActive.LastTip()->chainPower + (GetBlockProof(*chainActive.LastTip()) * 6))))
2228 if (!fLargeWorkForkFound && pindexBestForkBase)
2230 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
2231 pindexBestForkBase->phashBlock->ToString() + std::string("'");
2232 CAlert::Notify(warning, true);
2234 if (pindexBestForkTip && pindexBestForkBase)
2236 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__,
2237 pindexBestForkBase->GetHeight(), pindexBestForkBase->phashBlock->ToString(),
2238 pindexBestForkTip->GetHeight(), pindexBestForkTip->phashBlock->ToString());
2239 fLargeWorkForkFound = true;
2243 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
2244 LogPrintf("%s: %s\n", warning.c_str(), __func__);
2245 CAlert::Notify(warning, true);
2246 fLargeWorkInvalidChainFound = true;
2251 fLargeWorkForkFound = false;
2252 fLargeWorkInvalidChainFound = false;
2256 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
2258 AssertLockHeld(cs_main);
2259 // If we are on a fork that is sufficiently large, set a warning flag
2260 CBlockIndex* pfork = pindexNewForkTip;
2261 CBlockIndex* plonger = chainActive.LastTip();
2262 while (pfork && pfork != plonger)
2264 while (plonger && plonger->GetHeight() > pfork->GetHeight())
2265 plonger = plonger->pprev;
2266 if (pfork == plonger)
2268 pfork = pfork->pprev;
2271 // We define a condition where we should warn the user about as a fork of at least 7 blocks
2272 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
2273 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
2274 // hash rate operating on the fork.
2275 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
2276 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
2277 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
2278 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->GetHeight() > pindexBestForkTip->GetHeight())) &&
2279 pindexNewForkTip->chainPower - pfork->chainPower > (GetBlockProof(*pfork) * 7) &&
2280 chainActive.Height() - pindexNewForkTip->GetHeight() < 72)
2282 pindexBestForkTip = pindexNewForkTip;
2283 pindexBestForkBase = pfork;
2286 CheckForkWarningConditions();
2289 // Requires cs_main.
2290 void Misbehaving(NodeId pnode, int howmuch)
2295 CNodeState *state = State(pnode);
2299 state->nMisbehavior += howmuch;
2300 int banscore = GetArg("-banscore", 101);
2301 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
2303 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2304 state->fShouldBan = true;
2306 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2309 void static InvalidChainFound(CBlockIndex* pindexNew)
2311 if (!pindexBestInvalid || pindexNew->chainPower > pindexBestInvalid->chainPower)
2312 pindexBestInvalid = pindexNew;
2314 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2315 pindexNew->GetBlockHash().ToString(), pindexNew->GetHeight(),
2316 log(pindexNew->chainPower.chainWork.getdouble())/log(2.0),
2317 log(pindexNew->chainPower.chainStake.getdouble())/log(2.0),
2318 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()));
2319 CBlockIndex *tip = chainActive.LastTip();
2321 LogPrintf("%s: current best=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2322 tip->GetBlockHash().ToString(), chainActive.Height(),
2323 log(tip->chainPower.chainWork.getdouble())/log(2.0),
2324 log(tip->chainPower.chainStake.getdouble())/log(2.0),
2325 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
2326 CheckForkWarningConditions();
2329 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2331 if (state.IsInvalid(nDoS)) {
2332 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2333 if (it != mapBlockSource.end() && State(it->second)) {
2334 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
2335 State(it->second)->rejects.push_back(reject);
2337 Misbehaving(it->second, nDoS);
2340 if (!state.CorruptionPossible()) {
2341 pindex->nStatus |= BLOCK_FAILED_VALID;
2342 setDirtyBlockIndex.insert(pindex);
2343 setBlockIndexCandidates.erase(pindex);
2344 InvalidChainFound(pindex);
2348 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
2350 if (!tx.IsMint()) // mark inputs spent
2352 txundo.vprevout.reserve(tx.vin.size());
2353 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
2354 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2355 unsigned nPos = txin.prevout.n;
2357 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2359 // mark an outpoint spent, and construct undo information
2360 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2362 if (coins->vout.size() == 0) {
2363 CTxInUndo& undo = txundo.vprevout.back();
2364 undo.nHeight = coins->nHeight;
2365 undo.fCoinBase = coins->fCoinBase;
2366 undo.nVersion = coins->nVersion;
2372 inputs.SetNullifiers(tx, true);
2374 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2377 if (tx.IsCoinImport()) {
2378 // add a tombstone for the burnTx
2379 AddImportTombstone(tx, inputs, nHeight);
2383 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2386 UpdateCoins(tx, inputs, txundo, nHeight);
2389 bool CScriptCheck::operator()() {
2390 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2391 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2392 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
2393 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2398 int GetSpendHeight(const CCoinsViewCache& inputs)
2401 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2402 return pindexPrev->GetHeight() + 1;
2405 namespace Consensus {
2406 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2408 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2409 // for an attacker to attempt to split the network.
2410 if (!inputs.HaveInputs(tx))
2411 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2413 // are the JoinSplit's requirements met?
2414 if (!inputs.HaveJoinSplitRequirements(tx))
2415 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2417 CAmount nValueIn = 0;
2419 for (unsigned int i = 0; i < tx.vin.size(); i++)
2421 const COutPoint &prevout = tx.vin[i].prevout;
2422 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2425 if (coins->IsCoinBase()) {
2426 // Ensure that coinbases are matured
2427 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2428 return state.Invalid(
2429 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2430 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2433 // ensure that output of coinbases are not still time locked
2434 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2435 if (nSpendHeight < unlockTime && coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE) {
2436 return state.Invalid(
2437 error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2438 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2441 // Ensure that coinbases cannot be spent to transparent outputs
2442 // Disabled on regtest
2443 if (fCoinbaseEnforcedProtectionEnabled &&
2444 consensusParams.fCoinbaseMustBeProtected &&
2446 (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
2447 return state.Invalid(
2448 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2449 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2453 // Check for negative or overflow input values
2454 nValueIn += coins->vout[prevout.n].nValue;
2455 #ifdef KOMODO_ENABLE_INTEREST
2456 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() >= 60000 )
2458 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2460 int64_t interest; int32_t txheight; uint32_t locktime;
2461 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2463 //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);
2464 nValueIn += interest;
2469 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2470 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2471 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2475 nValueIn += tx.GetShieldedValueIn();
2476 if (!MoneyRange(nValueIn))
2477 return state.DoS(100, error("CheckInputs(): shielded input to transparent value pool out of range"),
2478 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2480 if (nValueIn < tx.GetValueOut())
2482 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2483 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2484 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2486 // Tally transaction fees
2487 CAmount nTxFee = nValueIn - tx.GetValueOut();
2489 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2490 REJECT_INVALID, "bad-txns-fee-negative");
2492 if (!MoneyRange(nFees))
2493 return state.DoS(100, error("CheckInputs(): nFees out of range"),
2494 REJECT_INVALID, "bad-txns-fee-outofrange");
2497 }// namespace Consensus
2499 bool ContextualCheckInputs(
2500 const CTransaction& tx,
2501 CValidationState &state,
2502 const CCoinsViewCache &inputs,
2506 PrecomputedTransactionData& txdata,
2507 const Consensus::Params& consensusParams,
2508 uint32_t consensusBranchId,
2509 std::vector<CScriptCheck> *pvChecks)
2513 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2518 pvChecks->reserve(tx.vin.size());
2520 // The first loop above does all the inexpensive checks.
2521 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2522 // Helps prevent CPU exhaustion attacks.
2524 // Skip ECDSA signature verification when connecting blocks
2525 // before the last block chain checkpoint. This is safe because block merkle hashes are
2526 // still computed and checked, and any change will be caught at the next checkpoint.
2527 if (fScriptChecks) {
2528 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2529 const COutPoint &prevout = tx.vin[i].prevout;
2530 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2534 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2536 pvChecks->push_back(CScriptCheck());
2537 check.swap(pvChecks->back());
2538 } else if (!check()) {
2539 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2540 // Check whether the failure was caused by a
2541 // non-mandatory script verification check, such as
2542 // non-standard DER encodings or non-null dummy
2543 // arguments; if so, don't trigger DoS protection to
2544 // avoid splitting the network between upgraded and
2545 // non-upgraded nodes.
2546 CScriptCheck check2(*coins, tx, i,
2547 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2549 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2551 // Failures of other flags indicate a transaction that is
2552 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2553 // such nodes as they are not following the protocol. That
2554 // said during an upgrade careful thought should be taken
2555 // as to the correct behavior - we may want to continue
2556 // peering with non-upgraded nodes even after a soft-fork
2557 // super-majority vote has passed.
2558 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2564 if (tx.IsCoinImport())
2566 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2567 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2574 /*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)
2576 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2577 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2581 if (!tx.IsCoinBase())
2583 // While checking, GetBestBlock() refers to the parent block.
2584 // This is also true for mempool checks.
2585 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2586 int nSpendHeight = pindexPrev->GetHeight() + 1;
2587 for (unsigned int i = 0; i < tx.vin.size(); i++)
2589 const COutPoint &prevout = tx.vin[i].prevout;
2590 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2591 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2595 // If prev is coinbase, check that it's matured
2596 if (coins->IsCoinBase()) {
2597 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2598 COINBASE_MATURITY = _COINBASE_MATURITY;
2599 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2600 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2602 return state.Invalid(
2603 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2614 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2616 // Open history file to append
2617 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2618 if (fileout.IsNull())
2619 return error("%s: OpenUndoFile failed", __func__);
2621 // Write index header
2622 unsigned int nSize = GetSerializeSize(fileout, blockundo);
2623 fileout << FLATDATA(messageStart) << nSize;
2626 long fileOutPos = ftell(fileout.Get());
2628 return error("%s: ftell failed", __func__);
2629 pos.nPos = (unsigned int)fileOutPos;
2630 fileout << blockundo;
2632 // calculate & write checksum
2633 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2634 hasher << hashBlock;
2635 hasher << blockundo;
2636 fileout << hasher.GetHash();
2641 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2643 // Open history file to read
2644 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2645 if (filein.IsNull())
2646 return error("%s: OpenBlockFile failed", __func__);
2649 uint256 hashChecksum;
2651 filein >> blockundo;
2652 filein >> hashChecksum;
2654 catch (const std::exception& e) {
2655 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2658 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2659 hasher << hashBlock;
2660 hasher << blockundo;
2661 if (hashChecksum != hasher.GetHash())
2662 return error("%s: Checksum mismatch", __func__);
2667 /** Abort with a message */
2668 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2670 strMiscWarning = strMessage;
2671 LogPrintf("*** %s\n", strMessage);
2672 uiInterface.ThreadSafeMessageBox(
2673 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2674 "", CClientUIInterface::MSG_ERROR);
2679 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2681 AbortNode(strMessage, userMessage);
2682 return state.Error(strMessage);
2688 * Apply the undo operation of a CTxInUndo to the given chain state.
2689 * @param undo The undo object.
2690 * @param view The coins view to which to apply the changes.
2691 * @param out The out point that corresponds to the tx input.
2692 * @return True on success.
2694 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2698 CCoinsModifier coins = view.ModifyCoins(out.hash);
2699 if (undo.nHeight != 0) {
2700 // undo data contains height: this is the last output of the prevout tx being spent
2701 if (!coins->IsPruned())
2702 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2704 coins->fCoinBase = undo.fCoinBase;
2705 coins->nHeight = undo.nHeight;
2706 coins->nVersion = undo.nVersion;
2708 if (coins->IsPruned())
2709 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2711 if (coins->IsAvailable(out.n))
2712 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2713 if (coins->vout.size() < out.n+1)
2714 coins->vout.resize(out.n+1);
2715 coins->vout[out.n] = undo.txout;
2721 void ConnectNotarisations(const CBlock &block, int height)
2723 // Record Notarisations
2724 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2725 if (notarisations.size() > 0) {
2726 CDBBatch batch = CDBBatch(*pnotarisations);
2727 batch.Write(block.GetHash(), notarisations);
2728 WriteBackNotarisations(notarisations, batch);
2729 pnotarisations->WriteBatch(batch, true);
2730 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2731 notarisations.size(), block.GetHash().GetHex().data());
2736 void DisconnectNotarisations(const CBlock &block)
2738 // Delete from notarisations cache
2739 NotarisationsInBlock nibs;
2740 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2741 CDBBatch batch = CDBBatch(*pnotarisations);
2742 batch.Erase(block.GetHash());
2743 EraseBackNotarisations(nibs, batch);
2744 pnotarisations->WriteBatch(batch, true);
2745 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2746 nibs.size(), block.GetHash().GetHex().data());
2751 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2753 assert(pindex->GetBlockHash() == view.GetBestBlock());
2759 komodo_disconnect(pindex,block);
2760 CBlockUndo blockUndo;
2761 CDiskBlockPos pos = pindex->GetUndoPos();
2763 return error("DisconnectBlock(): no undo data available");
2764 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2765 return error("DisconnectBlock(): failure reading undo data");
2767 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2768 return error("DisconnectBlock(): block and undo data inconsistent");
2769 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2770 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2771 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2773 // undo transactions in reverse order
2774 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2775 const CTransaction &tx = block.vtx[i];
2776 uint256 hash = tx.GetHash();
2777 if (fAddressIndex) {
2779 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2780 const CTxOut &out = tx.vout[k];
2782 if (out.scriptPubKey.IsPayToScriptHash()) {
2783 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2785 // undo receiving activity
2786 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2788 // undo unspent index
2789 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2792 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2793 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2795 // undo receiving activity
2796 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2798 // undo unspent index
2799 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2802 else if (out.scriptPubKey.IsPayToPublicKey()) {
2803 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2805 // undo receiving activity
2806 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2808 // undo unspent index
2809 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2812 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2813 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2815 // undo receiving activity
2816 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2818 // undo unspent index
2819 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2830 // Check that all outputs are available and match the outputs in the block itself
2833 CCoinsModifier outs = view.ModifyCoins(hash);
2834 outs->ClearUnspendable();
2836 CCoins outsBlock(tx, pindex->GetHeight());
2837 // The CCoins serialization does not serialize negative numbers.
2838 // No network rules currently depend on the version here, so an inconsistency is harmless
2839 // but it must be corrected before txout nversion ever influences a network rule.
2840 if (outsBlock.nVersion < 0)
2841 outs->nVersion = outsBlock.nVersion;
2842 if (*outs != outsBlock)
2843 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2849 // unspend nullifiers
2850 view.SetNullifiers(tx, false);
2854 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2855 if (txundo.vprevout.size() != tx.vin.size())
2856 return error("DisconnectBlock(): transaction and undo data inconsistent");
2857 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2858 const COutPoint &out = tx.vin[j].prevout;
2859 const CTxInUndo &undo = txundo.vprevout[j];
2860 if (!ApplyTxInUndo(undo, view, out))
2863 const CTxIn input = tx.vin[j];
2866 // undo and delete the spent index
2867 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2870 if (fAddressIndex) {
2871 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2872 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2873 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2875 // undo spending activity
2876 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2878 // restore unspent index
2879 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2883 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2884 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2886 // undo spending activity
2887 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2889 // restore unspent index
2890 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2893 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2894 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2896 // undo spending activity
2897 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2899 // restore unspent index
2900 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2903 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2904 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2906 // undo spending activity
2907 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2909 // restore unspent index
2910 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2919 else if (tx.IsCoinImport())
2921 RemoveImportTombstone(tx, view);
2925 // set the old best Sprout anchor back
2926 view.PopAnchor(blockUndo.old_sprout_tree_root, SPROUT);
2928 // set the old best Sapling anchor back
2929 // We can get this from the `hashFinalSaplingRoot` of the last block
2930 // However, this is only reliable if the last block was on or after
2931 // the Sapling activation height. Otherwise, the last anchor was the
2933 if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2934 view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING);
2936 view.PopAnchor(SaplingMerkleTree::empty_root(), SAPLING);
2939 // move best block pointer to prevout block
2940 view.SetBestBlock(pindex->pprev->GetBlockHash());
2947 if (fAddressIndex) {
2948 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2949 return AbortNode(state, "Failed to delete address index");
2951 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2952 return AbortNode(state, "Failed to write address unspent index");
2959 void static FlushBlockFile(bool fFinalize = false)
2961 LOCK(cs_LastBlockFile);
2963 CDiskBlockPos posOld(nLastBlockFile, 0);
2965 FILE *fileOld = OpenBlockFile(posOld);
2968 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2969 FileCommit(fileOld);
2973 fileOld = OpenUndoFile(posOld);
2976 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2977 FileCommit(fileOld);
2982 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
2984 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
2986 void ThreadScriptCheck() {
2987 RenameThread("zcash-scriptch");
2988 scriptcheckqueue.Thread();
2992 // Called periodically asynchronously; alerts if it smells like
2993 // we're being fed a bad chain (blocks being generated much
2994 // too slowly or too quickly).
2996 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2997 int64_t nPowTargetSpacing)
2999 if (bestHeader == NULL || initialDownloadCheck()) return;
3001 static int64_t lastAlertTime = 0;
3002 int64_t now = GetAdjustedTime();
3003 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
3005 const int SPAN_HOURS=4;
3006 const int SPAN_SECONDS=SPAN_HOURS*60*60;
3007 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
3009 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
3011 std::string strWarning;
3012 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
3015 const CBlockIndex* i = bestHeader;
3017 while (i->GetBlockTime() >= startTime) {
3020 if (i == NULL) return; // Ran out of chain, we must not be fully synced
3023 // How likely is it to find that many by chance?
3024 double p = boost::math::pdf(poisson, nBlocks);
3026 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
3027 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
3029 // Aim for one false-positive about every fifty years of normal running:
3030 const int FIFTY_YEARS = 50*365*24*60*60;
3031 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
3033 if (bestHeader->GetHeight() > BLOCKS_EXPECTED)
3035 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
3037 // Many fewer blocks than expected: alert!
3038 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
3039 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3041 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
3043 // Many more blocks than expected: alert!
3044 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
3045 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3048 if (!strWarning.empty())
3050 strMiscWarning = strWarning;
3051 CAlert::Notify(strWarning, true);
3052 lastAlertTime = now;
3057 static int64_t nTimeVerify = 0;
3058 static int64_t nTimeConnect = 0;
3059 static int64_t nTimeIndex = 0;
3060 static int64_t nTimeCallbacks = 0;
3061 static int64_t nTimeTotal = 0;
3063 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
3065 const CChainParams& chainparams = Params();
3066 if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT )
3068 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
3069 AssertLockHeld(cs_main);
3070 bool fExpensiveChecks = true;
3071 if (fCheckpointsEnabled) {
3072 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
3073 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->GetHeight()) == pindex) {
3074 // This block is an ancestor of a checkpoint: disable script checks
3075 fExpensiveChecks = false;
3078 auto verifier = libzcash::ProofVerifier::Strict();
3079 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
3080 int32_t futureblock;
3081 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
3082 if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
3084 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
3088 // verify that the view's current state corresponds to the previous block
3089 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
3090 if ( hashPrevBlock != view.GetBestBlock() )
3092 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
3093 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
3094 REJECT_INVALID, "hashPrevBlock-not-bestblock");
3096 assert(hashPrevBlock == view.GetBestBlock());
3098 // Special case for the genesis block, skipping connection of its transactions
3099 // (its coinbase is unspendable)
3100 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
3102 view.SetBestBlock(pindex->GetBlockHash());
3103 // Before the genesis block, there was an empty tree
3104 SproutMerkleTree tree;
3105 pindex->hashSproutAnchor = tree.root();
3106 // The genesis block contained no JoinSplits
3107 pindex->hashFinalSproutRoot = pindex->hashSproutAnchor;
3112 bool fScriptChecks = (!fCheckpointsEnabled || pindex->GetHeight() >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
3113 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->GetHeight() > KOMODO_TESTNET_EXPIRATION ) // "testnet"
3115 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
3116 // unless those are already completely spent.
3117 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
3118 const CCoins* coins = view.AccessCoins(tx.GetHash());
3119 if (coins && !coins->IsPruned())
3120 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
3121 REJECT_INVALID, "bad-txns-BIP30");
3124 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
3126 // DERSIG (BIP66) is also always enforced, but does not have a flag.
3128 CBlockUndo blockundo;
3130 if ( ASSETCHAINS_CC != 0 )
3132 if ( scriptcheckqueue.IsIdle() == 0 )
3134 fprintf(stderr,"scriptcheckqueue isnt idle\n");
3138 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
3140 int64_t nTimeStart = GetTimeMicros();
3143 int64_t interest,sum = 0;
3144 unsigned int nSigOps = 0;
3145 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
3146 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
3147 vPos.reserve(block.vtx.size());
3148 blockundo.vtxundo.reserve(block.vtx.size() - 1);
3149 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
3150 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
3151 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
3152 // Construct the incremental merkle tree at the current
3154 auto old_sprout_tree_root = view.GetBestAnchor(SPROUT);
3155 // saving the top anchor in the block index as we go.
3157 pindex->hashSproutAnchor = old_sprout_tree_root;
3160 SproutMerkleTree sprout_tree;
3162 // This should never fail: we should always be able to get the root
3163 // that is on the tip of our chain
3164 assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
3167 // Consistency check: the root of the tree we're given should
3168 // match what we asked for.
3169 assert(sprout_tree.root() == old_sprout_tree_root);
3172 SaplingMerkleTree sapling_tree;
3173 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
3175 // Grab the consensus branch ID for the block's height
3176 auto consensusBranchId = CurrentEpochBranchId(pindex->GetHeight(), Params().GetConsensus());
3178 std::vector<PrecomputedTransactionData> txdata;
3179 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
3180 for (unsigned int i = 0; i < block.vtx.size(); i++)
3182 const CTransaction &tx = block.vtx[i];
3183 const uint256 txhash = tx.GetHash();
3184 nInputs += tx.vin.size();
3185 nSigOps += GetLegacySigOpCount(tx);
3186 if (nSigOps > MAX_BLOCK_SIGOPS)
3187 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3188 REJECT_INVALID, "bad-blk-sigops");
3189 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->GetHeight(),tx.nLockTime);
3192 if (!view.HaveInputs(tx))
3194 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
3195 REJECT_INVALID, "bad-txns-inputs-missingorspent");
3197 // are the JoinSplit's requirements met?
3198 if (!view.HaveJoinSplitRequirements(tx))
3199 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
3200 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
3201 if (fAddressIndex || fSpentIndex)
3203 for (size_t j = 0; j < tx.vin.size(); j++) {
3205 const CTxIn input = tx.vin[j];
3206 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
3210 if (prevout.scriptPubKey.IsPayToScriptHash()) {
3211 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
3214 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
3215 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
3218 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
3219 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
3222 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
3223 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
3227 hashBytes.SetNull();
3231 if (fAddressIndex && addressType > 0) {
3232 // record spending activity
3233 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->GetHeight(), i, txhash, j, true), prevout.nValue * -1));
3235 // remove address from unspent index
3236 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
3240 // add the spent index to determine the txid and input that spent an output
3241 // and to find the amount and address from an input
3242 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->GetHeight(), prevout.nValue, addressType, hashBytes)));
3247 // Add in sigops done by pay-to-script-hash inputs;
3248 // this is to prevent a "rogue miner" from creating
3249 // an incredibly-expensive-to-validate block.
3250 nSigOps += GetP2SHSigOpCount(tx, view);
3251 if (nSigOps > MAX_BLOCK_SIGOPS)
3252 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3253 REJECT_INVALID, "bad-blk-sigops");
3256 txdata.emplace_back(tx);
3258 if (!tx.IsCoinBase())
3260 nFees += view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
3263 std::vector<CScriptCheck> vChecks;
3264 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
3266 control.Add(vChecks);
3269 if (fAddressIndex) {
3270 for (unsigned int k = 0; k < tx.vout.size(); k++) {
3271 const CTxOut &out = tx.vout[k];
3272 //fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
3273 if (out.scriptPubKey.IsPayToScriptHash()) {
3274 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
3276 // record receiving activity
3277 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3279 // record unspent output
3280 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3283 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
3284 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
3286 // record receiving activity
3287 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3289 // record unspent output
3290 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3293 else if (out.scriptPubKey.IsPayToPublicKey()) {
3294 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
3296 // record receiving activity
3297 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3299 // record unspent output
3300 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3303 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
3304 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
3306 // record receiving activity
3307 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3309 // record unspent output
3310 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3320 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3321 // komodo_earned_interest(pindex->GetHeight(),sum);
3324 blockundo.vtxundo.push_back(CTxUndo());
3326 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight());
3328 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
3329 BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
3330 // Insert the note commitments into our temporary tree.
3332 sprout_tree.append(note_commitment);
3336 BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) {
3337 sapling_tree.append(outputDescription.cm);
3340 vPos.push_back(std::make_pair(tx.GetHash(), pos));
3341 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
3344 view.PushAnchor(sprout_tree);
3345 view.PushAnchor(sapling_tree);
3347 pindex->hashFinalSproutRoot = sprout_tree.root();
3349 blockundo.old_sprout_tree_root = old_sprout_tree_root;
3351 // If Sapling is active, block.hashFinalSaplingRoot must be the
3352 // same as the root of the Sapling tree
3353 if (NetworkUpgradeActive(pindex->GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3354 if (block.hashFinalSaplingRoot != sapling_tree.root()) {
3355 return state.DoS(100,
3356 error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"),
3357 REJECT_INVALID, "bad-sapling-root-in-block");
3360 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3361 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);
3363 CAmount blockReward = nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum;
3364 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
3366 uint64_t checktoshis;
3367 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
3369 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
3370 blockReward += checktoshis;
3371 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
3374 if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward)
3376 return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
3377 REJECT_INVALID, "bad-cb-amount");
3379 if ( block.vtx[0].GetValueOut() > blockReward+1 )
3381 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->GetHeight() >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
3383 return state.DoS(100,
3384 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3385 block.vtx[0].GetValueOut(), blockReward),
3386 REJECT_INVALID, "bad-cb-amount");
3387 } else if ( IS_KOMODO_NOTARY != 0 )
3388 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));
3390 if (!control.Wait())
3391 return state.DoS(100, false);
3392 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3393 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);
3398 // Write undo information to disk
3399 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
3401 if (pindex->GetUndoPos().IsNull()) {
3403 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
3404 return error("ConnectBlock(): FindUndoPos failed");
3405 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
3406 return AbortNode(state, "Failed to write undo data");
3408 // update nUndoPos in block index
3409 pindex->nUndoPos = pos.nPos;
3410 pindex->nStatus |= BLOCK_HAVE_UNDO;
3413 // Now that all consensus rules have been validated, set nCachedBranchId.
3414 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3415 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
3416 "nCachedBranchId must be set after all consensus rules have been validated.");
3417 if (IsActivationHeightForAnyUpgrade(pindex->GetHeight(), Params().GetConsensus())) {
3418 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
3419 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->GetHeight(), chainparams.GetConsensus());
3420 } else if (pindex->pprev) {
3421 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
3424 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
3425 setDirtyBlockIndex.insert(pindex);
3428 ConnectNotarisations(block, pindex->GetHeight());
3431 if (!pblocktree->WriteTxIndex(vPos))
3432 return AbortNode(state, "Failed to write transaction index");
3433 if (fAddressIndex) {
3434 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3435 return AbortNode(state, "Failed to write address index");
3438 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3439 return AbortNode(state, "Failed to write address unspent index");
3444 if (!pblocktree->UpdateSpentIndex(spentIndex))
3445 return AbortNode(state, "Failed to write transaction index");
3447 if (fTimestampIndex) {
3448 unsigned int logicalTS = pindex->nTime;
3449 unsigned int prevLogicalTS = 0;
3451 // retrieve logical timestamp of the previous block
3453 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3454 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3456 if (logicalTS <= prevLogicalTS) {
3457 logicalTS = prevLogicalTS + 1;
3458 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3461 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3462 return AbortNode(state, "Failed to write timestamp index");
3464 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3465 return AbortNode(state, "Failed to write blockhash index");
3468 // add this block to the view's block chain
3469 view.SetBestBlock(pindex->GetBlockHash());
3471 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3472 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
3474 // Watch for changes to the previous coinbase transaction.
3475 static uint256 hashPrevBestCoinBase;
3476 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
3477 hashPrevBestCoinBase = block.vtx[0].GetHash();
3479 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3480 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
3482 //FlushStateToDisk();
3483 komodo_connectblock(pindex,*(CBlock *)&block);
3487 enum FlushStateMode {
3489 FLUSH_STATE_IF_NEEDED,
3490 FLUSH_STATE_PERIODIC,
3495 * Update the on-disk chain state.
3496 * The caches and indexes are flushed depending on the mode we're called with
3497 * if they're too large, if it's been a while since the last write,
3498 * or always and in all cases if we're in prune mode and are deleting files.
3500 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
3501 LOCK2(cs_main, cs_LastBlockFile);
3502 static int64_t nLastWrite = 0;
3503 static int64_t nLastFlush = 0;
3504 static int64_t nLastSetChain = 0;
3505 std::set<int> setFilesToPrune;
3506 bool fFlushForPrune = false;
3508 if (fPruneMode && fCheckForPruning && !fReindex) {
3509 FindFilesToPrune(setFilesToPrune);
3510 fCheckForPruning = false;
3511 if (!setFilesToPrune.empty()) {
3512 fFlushForPrune = true;
3514 pblocktree->WriteFlag("prunedblockfiles", true);
3519 int64_t nNow = GetTimeMicros();
3520 // Avoid writing/flushing immediately after startup.
3521 if (nLastWrite == 0) {
3524 if (nLastFlush == 0) {
3527 if (nLastSetChain == 0) {
3528 nLastSetChain = nNow;
3530 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3531 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3532 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3533 // The cache is over the limit, we have to write now.
3534 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3535 // 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.
3536 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3537 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3538 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3539 // Combine all conditions that result in a full cache flush.
3540 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3541 // Write blocks and block index to disk.
3542 if (fDoFullFlush || fPeriodicWrite) {
3543 // Depend on nMinDiskSpace to ensure we can write block index
3544 if (!CheckDiskSpace(0))
3545 return state.Error("out of disk space");
3546 // First make sure all block and undo data is flushed to disk.
3548 // Then update all block file information (which may refer to block and undo files).
3550 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3551 vFiles.reserve(setDirtyFileInfo.size());
3552 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3553 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3554 setDirtyFileInfo.erase(it++);
3556 std::vector<const CBlockIndex*> vBlocks;
3557 vBlocks.reserve(setDirtyBlockIndex.size());
3558 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3559 vBlocks.push_back(*it);
3560 setDirtyBlockIndex.erase(it++);
3562 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3563 return AbortNode(state, "Files to write to block index database");
3566 // Finally remove any pruned files
3568 UnlinkPrunedFiles(setFilesToPrune);
3571 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3573 // Typical CCoins structures on disk are around 128 bytes in size.
3574 // Pushing a new one to the database can cause it to be written
3575 // twice (once in the log, and once in the tables). This is already
3576 // an overestimation, as most will delete an existing entry or
3577 // overwrite one. Still, use a conservative safety factor of 2.
3578 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3579 return state.Error("out of disk space");
3580 // Flush the chainstate (which may refer to block index entries).
3581 if (!pcoinsTip->Flush())
3582 return AbortNode(state, "Failed to write to coin database");
3585 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3586 // Update best block in wallet (so we can detect restored wallets).
3587 GetMainSignals().SetBestChain(chainActive.GetLocator());
3588 nLastSetChain = nNow;
3590 } catch (const std::runtime_error& e) {
3591 return AbortNode(state, std::string("System error while flushing: ") + e.what());
3596 void FlushStateToDisk() {
3597 CValidationState state;
3598 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3601 void PruneAndFlush() {
3602 CValidationState state;
3603 fCheckForPruning = true;
3604 FlushStateToDisk(state, FLUSH_STATE_NONE);
3607 /** Update chainActive and related internal data structures. */
3608 void static UpdateTip(CBlockIndex *pindexNew) {
3609 const CChainParams& chainParams = Params();
3610 chainActive.SetTip(pindexNew);
3613 nTimeBestReceived = GetTime();
3614 mempool.AddTransactionsUpdated(1);
3617 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
3618 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
3620 int32_t longestchain = komodo_longestchain();
3621 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
3624 LogPrintf("%s: new best=%s height=%d log2_work=%.8g log2_stake=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
3625 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3626 log(chainActive.Tip()->chainPower.chainWork.getdouble())/log(2.0),
3627 log(chainActive.Tip()->chainPower.chainStake.getdouble())/log(2.0),
3628 (unsigned long)chainActive.LastTip()->nChainTx,
3629 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
3630 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3632 cvBlockChange.notify_all();
3634 // Check the version of the last 100 blocks to see if we need to upgrade:
3635 static bool fWarned = false;
3636 if (!IsInitialBlockDownload() && !fWarned)
3639 const CBlockIndex* pindex = chainActive.Tip();
3640 for (int i = 0; i < 100 && pindex != NULL; i++)
3642 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3644 pindex = pindex->pprev;
3647 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3648 if (nUpgraded > 100/2)
3650 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3651 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3652 CAlert::Notify(strMiscWarning, true);
3659 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3660 * mempool.removeWithoutBranchId after this, with cs_main held.
3662 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3663 CBlockIndex *pindexDelete = chainActive.Tip();
3664 assert(pindexDelete);
3665 // Read block from disk.
3667 if (!ReadBlockFromDisk(block, pindexDelete,1))
3668 return AbortNode(state, "Failed to read block");
3669 // Apply the block atomically to the chain state.
3670 uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3671 uint256 saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3672 int64_t nStart = GetTimeMicros();
3674 CCoinsViewCache view(pcoinsTip);
3675 if (!DisconnectBlock(block, state, pindexDelete, view))
3676 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3677 assert(view.Flush());
3678 DisconnectNotarisations(block);
3680 pindexDelete->segid = -2;
3681 pindexDelete->newcoins = 0;
3682 pindexDelete->zfunds = 0;
3684 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3685 uint256 sproutAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3686 uint256 saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3687 // Write the chain state to disk, if necessary.
3688 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3692 // resurrect mempool transactions from the disconnected block.
3693 for (int i = 0; i < block.vtx.size(); i++)
3695 // ignore validation errors in resurrected transactions
3696 CTransaction &tx = block.vtx[i];
3697 list<CTransaction> removed;
3698 CValidationState stateDummy;
3699 // don't keep staking or invalid transactions
3700 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (komodo_isPoS((CBlock *)&block) != 0))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3702 mempool.remove(tx, removed, true);
3705 if (sproutAnchorBeforeDisconnect != sproutAnchorAfterDisconnect) {
3706 // The anchor may not change between block disconnects,
3707 // in which case we don't want to evict from the mempool yet!
3708 mempool.removeWithAnchor(sproutAnchorBeforeDisconnect, SPROUT);
3710 if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) {
3711 // The anchor may not change between block disconnects,
3712 // in which case we don't want to evict from the mempool yet!
3713 mempool.removeWithAnchor(saplingAnchorBeforeDisconnect, SAPLING);
3717 // Update chainActive and related variables.
3718 UpdateTip(pindexDelete->pprev);
3720 // Get the current commitment tree
3721 SproutMerkleTree newSproutTree;
3722 SaplingMerkleTree newSaplingTree;
3723 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
3724 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
3725 // Let wallets know transactions went from 1-confirmed to
3726 // 0-confirmed or conflicted:
3727 for (int i = 0; i < block.vtx.size(); i++)
3729 CTransaction &tx = block.vtx[i];
3730 if ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
3732 EraseFromWallets(tx.GetHash());
3736 SyncWithWallets(tx, NULL);
3739 // Update cached incremental witnesses
3740 GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
3744 static int64_t nTimeReadFromDisk = 0;
3745 static int64_t nTimeConnectTotal = 0;
3746 static int64_t nTimeFlush = 0;
3747 static int64_t nTimeChainState = 0;
3748 static int64_t nTimePostConnect = 0;
3751 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3752 * corresponding to pindexNew, to bypass loading it again from disk.
3753 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3755 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3757 assert(pindexNew->pprev == chainActive.Tip());
3758 // Read block from disk.
3759 int64_t nTime1 = GetTimeMicros();
3762 if (!ReadBlockFromDisk(block, pindexNew,1))
3763 return AbortNode(state, "Failed to read block");
3766 KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight();
3767 // Get the current commitment tree
3768 SproutMerkleTree oldSproutTree;
3769 SaplingMerkleTree oldSaplingTree;
3770 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
3771 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
3772 // Apply the block atomically to the chain state.
3773 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3775 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3777 CCoinsViewCache view(pcoinsTip);
3778 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3779 KOMODO_CONNECTING = -1;
3780 GetMainSignals().BlockChecked(*pblock, state);
3782 if (state.IsInvalid())
3783 InvalidBlockFound(pindexNew, state);
3784 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3786 mapBlockSource.erase(pindexNew->GetBlockHash());
3787 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3788 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3789 assert(view.Flush());
3791 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3792 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3793 // Write the chain state to disk, if necessary.
3794 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3796 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3797 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3798 // Remove conflicting transactions from the mempool.
3799 list<CTransaction> txConflicted;
3800 mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload());
3802 // Remove transactions that expire at new block height from mempool
3803 mempool.removeExpired(pindexNew->GetHeight());
3805 // Update chainActive & related variables.
3806 UpdateTip(pindexNew);
3807 // Tell wallet about transactions that went from mempool
3809 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3810 SyncWithWallets(tx, NULL);
3812 // ... and about transactions that got confirmed:
3813 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3814 SyncWithWallets(tx, pblock);
3816 // Update cached incremental witnesses
3817 GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
3819 EnforceNodeDeprecation(pindexNew->GetHeight());
3821 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3822 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3823 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3824 if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->GetHeight() >= KOMODO_LONGESTCHAIN )
3826 else KOMODO_INSYNC = 0;
3827 //fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->GetHeight(),KOMODO_INSYNC);
3828 if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
3829 komodo_broadcast(pblock,8);
3834 * Return the tip of the chain with the most work in it, that isn't
3835 * known to be invalid (it's however far from certain to be valid).
3837 static CBlockIndex* FindMostWorkChain() {
3839 CBlockIndex *pindexNew = NULL;
3841 // Find the best candidate header.
3843 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3844 if (it == setBlockIndexCandidates.rend())
3849 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3850 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3851 CBlockIndex *pindexTest = pindexNew;
3852 bool fInvalidAncestor = false;
3853 while (pindexTest && !chainActive.Contains(pindexTest)) {
3854 assert(pindexTest->nChainTx || pindexTest->GetHeight() == 0);
3856 // Pruned nodes may have entries in setBlockIndexCandidates for
3857 // which block files have been deleted. Remove those as candidates
3858 // for the most work chain if we come across them; we can't switch
3859 // to a chain unless we have all the non-active-chain parent blocks.
3860 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3861 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3862 if (fFailedChain || fMissingData) {
3863 // Candidate chain is not usable (either invalid or missing data)
3864 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->chainPower > pindexBestInvalid->chainPower))
3865 pindexBestInvalid = pindexNew;
3866 CBlockIndex *pindexFailed = pindexNew;
3867 // Remove the entire chain from the set.
3868 while (pindexTest != pindexFailed) {
3870 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3871 } else if (fMissingData) {
3872 // If we're missing data, then add back to mapBlocksUnlinked,
3873 // so that if the block arrives in the future we can try adding
3874 // to setBlockIndexCandidates again.
3875 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3877 setBlockIndexCandidates.erase(pindexFailed);
3878 pindexFailed = pindexFailed->pprev;
3880 setBlockIndexCandidates.erase(pindexTest);
3881 fInvalidAncestor = true;
3884 pindexTest = pindexTest->pprev;
3886 if (!fInvalidAncestor)
3891 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3892 static void PruneBlockIndexCandidates() {
3893 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3894 // reorganization to a better block fails.
3895 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3896 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
3897 setBlockIndexCandidates.erase(it++);
3899 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3900 assert(!setBlockIndexCandidates.empty());
3904 * Try to make some progress towards making pindexMostWork the active block.
3905 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3907 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3908 AssertLockHeld(cs_main);
3909 bool fInvalidFound = false;
3910 const CBlockIndex *pindexOldTip = chainActive.Tip();
3911 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3913 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3914 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3915 // then pindexFork will be null, and we would need to remove the entire chain including
3916 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3917 auto reorgLength = pindexOldTip ? pindexOldTip->GetHeight() - (pindexFork ? pindexFork->GetHeight() : -1) : 0;
3918 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3919 if (reorgLength > MAX_REORG_LENGTH) {
3920 auto msg = strprintf(_(
3921 "A block chain reorganization has been detected that would roll back %d blocks! "
3922 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3923 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3924 _("Reorganization details") + ":\n" +
3925 "- " + strprintf(_("Current tip: %s, height %d, work %s\nstake %s"),
3926 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex(),
3927 pindexOldTip->chainPower.chainStake.GetHex()) + "\n" +
3928 "- " + strprintf(_("New tip: %s, height %d, work %s\nstake %s"),
3929 pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex(),
3930 pindexMostWork->chainPower.chainStake.GetHex()) + "\n" +
3931 "- " + strprintf(_("Fork point: %s %s, height %d"),
3932 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n\n" +
3933 _("Please help, human!");
3934 LogPrintf("*** %s\n", msg);
3935 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3940 // Disconnect active blocks which are no longer in the best chain.
3941 bool fBlocksDisconnected = false;
3942 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3943 if (!DisconnectTip(state))
3945 fBlocksDisconnected = true;
3947 if ( KOMODO_REWIND != 0 )
3949 CBlockIndex *tipindex;
3950 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->GetHeight(),KOMODO_REWIND);
3951 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->GetHeight() > KOMODO_REWIND )
3953 fBlocksDisconnected = true;
3954 fprintf(stderr,"%d ",(int32_t)tipindex->GetHeight());
3955 InvalidateBlock(state,tipindex);
3956 if ( !DisconnectTip(state) )
3959 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3961 fprintf(stderr,"resuming normal operations\n");
3965 // Build list of new blocks to connect.
3966 std::vector<CBlockIndex*> vpindexToConnect;
3967 bool fContinue = true;
3968 int nHeight = pindexFork ? pindexFork->GetHeight() : -1;
3969 while (fContinue && nHeight != pindexMostWork->GetHeight()) {
3970 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3971 // a few blocks along the way.
3972 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->GetHeight());
3973 vpindexToConnect.clear();
3974 vpindexToConnect.reserve(nTargetHeight - nHeight);
3975 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3976 while (pindexIter && pindexIter->GetHeight() != nHeight) {
3977 vpindexToConnect.push_back(pindexIter);
3978 pindexIter = pindexIter->pprev;
3980 nHeight = nTargetHeight;
3982 // Connect new blocks.
3983 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
3984 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
3985 if (state.IsInvalid()) {
3986 // The block violates a consensus rule.
3987 if (!state.CorruptionPossible())
3988 InvalidChainFound(vpindexToConnect.back());
3989 state = CValidationState();
3990 fInvalidFound = true;
3994 // A system error occurred (disk space, database error, ...).
3998 PruneBlockIndexCandidates();
3999 if (!pindexOldTip || chainActive.Tip()->chainPower > pindexOldTip->chainPower) {
4000 // We're in a better position than we were. Return temporarily to release the lock.
4008 if (fBlocksDisconnected) {
4009 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4011 mempool.removeWithoutBranchId(
4012 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4013 mempool.check(pcoinsTip);
4015 // Callbacks/notifications for a new best chain.
4017 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
4019 CheckForkWarningConditions();
4025 * Make the best chain active, in multiple steps. The result is either failure
4026 * or an activated best chain. pblock is either NULL or a pointer to a block
4027 * that is already loaded (to avoid loading it again from disk).
4029 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
4030 CBlockIndex *pindexNewTip = NULL;
4031 CBlockIndex *pindexMostWork = NULL;
4032 const CChainParams& chainParams = Params();
4034 boost::this_thread::interruption_point();
4036 bool fInitialDownload;
4039 pindexMostWork = FindMostWorkChain();
4041 // Whether we have anything to do at all.
4042 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
4045 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
4047 pindexNewTip = chainActive.Tip();
4048 fInitialDownload = IsInitialBlockDownload();
4050 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
4052 // Notifications/callbacks that can run without cs_main
4053 if (!fInitialDownload) {
4054 uint256 hashNewTip = pindexNewTip->GetBlockHash();
4055 // Relay inventory, but don't relay old inventory during initial block download.
4056 int nBlockEstimate = 0;
4057 if (fCheckpointsEnabled)
4058 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
4059 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
4060 // in a stalled download if the block file is pruned before the request.
4061 if (nLocalServices & NODE_NETWORK) {
4063 BOOST_FOREACH(CNode* pnode, vNodes)
4064 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
4065 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
4067 // Notify external listeners about the new tip.
4068 GetMainSignals().UpdatedBlockTip(pindexNewTip);
4069 uiInterface.NotifyBlockTip(hashNewTip);
4070 } //else fprintf(stderr,"initial download skips propagation\n");
4071 } while(pindexMostWork != chainActive.Tip());
4074 // Write changes periodically to disk, after relay.
4075 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
4082 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
4083 AssertLockHeld(cs_main);
4085 // Mark the block itself as invalid.
4086 pindex->nStatus |= BLOCK_FAILED_VALID;
4087 setDirtyBlockIndex.insert(pindex);
4088 setBlockIndexCandidates.erase(pindex);
4090 while (chainActive.Contains(pindex)) {
4091 CBlockIndex *pindexWalk = chainActive.Tip();
4092 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
4093 setDirtyBlockIndex.insert(pindexWalk);
4094 setBlockIndexCandidates.erase(pindexWalk);
4095 // ActivateBestChain considers blocks already in chainActive
4096 // unconditionally valid already, so force disconnect away from it.
4097 if (!DisconnectTip(state)) {
4098 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4099 mempool.removeWithoutBranchId(
4100 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4104 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
4106 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
4108 BlockMap::iterator it = mapBlockIndex.begin();
4109 while (it != mapBlockIndex.end() && it->second != 0 ) {
4110 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
4111 setBlockIndexCandidates.insert(it->second);
4116 InvalidChainFound(pindex);
4117 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4118 mempool.removeWithoutBranchId(
4119 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4123 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
4124 AssertLockHeld(cs_main);
4126 int nHeight = pindex->GetHeight();
4128 // Remove the invalidity flag from this block and all its descendants.
4129 BlockMap::iterator it = mapBlockIndex.begin();
4130 while (it != mapBlockIndex.end()) {
4131 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
4132 it->second->nStatus &= ~BLOCK_FAILED_MASK;
4133 setDirtyBlockIndex.insert(it->second);
4134 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
4135 setBlockIndexCandidates.insert(it->second);
4137 if (it->second == pindexBestInvalid) {
4138 // Reset invalid block marker if it was pointing to one of those.
4139 pindexBestInvalid = NULL;
4145 // Remove the invalidity flag from all ancestors too.
4146 while (pindex != NULL) {
4147 if (pindex->nStatus & BLOCK_FAILED_MASK) {
4148 pindex->nStatus &= ~BLOCK_FAILED_MASK;
4149 setDirtyBlockIndex.insert(pindex);
4151 pindex = pindex->pprev;
4156 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
4158 // Check for duplicate
4159 uint256 hash = block.GetHash();
4160 BlockMap::iterator it = mapBlockIndex.find(hash);
4161 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
4162 if (it != mapBlockIndex.end())
4164 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
4166 // 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
4167 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
4170 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
4172 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
4173 return(0); // return here to avoid the state of pindex->GetHeight() not set and pprev NULL
4176 // Construct new block index object
4177 CBlockIndex* pindexNew = new CBlockIndex(block);
4179 // We assign the sequence id to blocks only when the full data is available,
4180 // to avoid miners withholding blocks but broadcasting headers, to get a
4181 // competitive advantage.
4182 pindexNew->nSequenceId = 0;
4183 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4184 pindexNew->phashBlock = &((*mi).first);
4185 if (miPrev != mapBlockIndex.end())
4187 if ( (pindexNew->pprev= (*miPrev).second) != 0 )
4188 pindexNew->SetHeight(pindexNew->pprev->GetHeight() + 1);
4189 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
4190 pindexNew->BuildSkip();
4192 pindexNew->chainPower = (pindexNew->pprev ? CChainPower(pindexNew) + pindexNew->pprev->chainPower : CChainPower(pindexNew)) + GetBlockProof(*pindexNew);
4193 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
4194 if (pindexBestHeader == NULL || pindexBestHeader->chainPower < pindexNew->chainPower)
4195 pindexBestHeader = pindexNew;
4197 setDirtyBlockIndex.insert(pindexNew);
4198 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
4199 mi->second = pindexNew;
4203 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
4204 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
4206 pindexNew->nTx = block.vtx.size();
4207 pindexNew->nChainTx = 0;
4208 CAmount sproutValue = 0;
4209 CAmount saplingValue = 0;
4210 for (auto tx : block.vtx) {
4211 // Negative valueBalance "takes" money from the transparent value pool
4212 // and adds it to the Sapling value pool. Positive valueBalance "gives"
4213 // money to the transparent value pool, removing from the Sapling value
4214 // pool. So we invert the sign here.
4215 saplingValue += -tx.valueBalance;
4217 for (auto js : tx.vjoinsplit) {
4218 sproutValue += js.vpub_old;
4219 sproutValue -= js.vpub_new;
4222 pindexNew->nSproutValue = sproutValue;
4223 pindexNew->nChainSproutValue = boost::none;
4224 pindexNew->nSaplingValue = saplingValue;
4225 pindexNew->nChainSaplingValue = boost::none;
4226 pindexNew->nFile = pos.nFile;
4227 pindexNew->nDataPos = pos.nPos;
4228 pindexNew->nUndoPos = 0;
4229 pindexNew->nStatus |= BLOCK_HAVE_DATA;
4230 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
4231 setDirtyBlockIndex.insert(pindexNew);
4233 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
4234 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
4235 deque<CBlockIndex*> queue;
4236 queue.push_back(pindexNew);
4238 // Recursively process any descendant blocks that now may be eligible to be connected.
4239 while (!queue.empty()) {
4240 CBlockIndex *pindex = queue.front();
4242 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
4243 if (pindex->pprev) {
4244 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4245 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4247 pindex->nChainSproutValue = boost::none;
4249 if (pindex->pprev->nChainSaplingValue) {
4250 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
4252 pindex->nChainSaplingValue = boost::none;
4255 pindex->nChainSproutValue = pindex->nSproutValue;
4256 pindex->nChainSaplingValue = pindex->nSaplingValue;
4259 LOCK(cs_nBlockSequenceId);
4260 pindex->nSequenceId = nBlockSequenceId++;
4262 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
4263 setBlockIndexCandidates.insert(pindex);
4265 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
4266 while (range.first != range.second) {
4267 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
4268 queue.push_back(it->second);
4270 mapBlocksUnlinked.erase(it);
4274 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
4275 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
4282 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
4284 LOCK(cs_LastBlockFile);
4286 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
4287 if (vinfoBlockFile.size() <= nFile) {
4288 vinfoBlockFile.resize(nFile + 1);
4292 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
4294 if (vinfoBlockFile.size() <= nFile) {
4295 vinfoBlockFile.resize(nFile + 1);
4299 pos.nPos = vinfoBlockFile[nFile].nSize;
4302 if (nFile != nLastBlockFile) {
4304 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
4306 FlushBlockFile(!fKnown);
4307 nLastBlockFile = nFile;
4310 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
4312 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
4314 vinfoBlockFile[nFile].nSize += nAddSize;
4317 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4318 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4319 if (nNewChunks > nOldChunks) {
4321 fCheckForPruning = true;
4322 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
4323 FILE *file = OpenBlockFile(pos);
4325 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
4326 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
4331 return state.Error("out of disk space");
4335 setDirtyFileInfo.insert(nFile);
4339 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
4343 LOCK(cs_LastBlockFile);
4345 unsigned int nNewSize;
4346 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
4347 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
4348 setDirtyFileInfo.insert(nFile);
4350 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4351 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4352 if (nNewChunks > nOldChunks) {
4354 fCheckForPruning = true;
4355 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
4356 FILE *file = OpenUndoFile(pos);
4358 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
4359 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
4364 return state.Error("out of disk space");
4370 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
4375 uint256 hash; int32_t i;
4376 hash = blockhdr.GetHash();
4377 for (i=31; i>=0; i--)
4378 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4379 fprintf(stderr," <- CheckBlockHeader\n");
4380 if ( chainActive.LastTip() != 0 )
4382 hash = chainActive.LastTip()->GetBlockHash();
4383 for (i=31; i>=0; i--)
4384 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4385 fprintf(stderr," <- chainTip\n");
4389 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
4391 CBlockIndex *tipindex;
4392 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
4393 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
4395 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
4396 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4398 //fprintf(stderr,"now its valid\n");
4402 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4404 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
4405 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4408 // Check block version
4409 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
4410 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
4412 // Check Equihash solution is valid
4415 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4416 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4418 // Check proof of work matches claimed amount
4419 /*komodo_index2pubkey33(pubkey33,pindex,height);
4420 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
4421 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
4425 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
4426 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
4428 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
4429 libzcash::ProofVerifier& verifier,
4430 bool fCheckPOW, bool fCheckMerkleRoot)
4432 uint8_t pubkey33[33]; uint256 hash;
4433 // These are checks that are independent of context.
4434 hash = block.GetHash();
4435 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
4436 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
4438 if ( *futureblockp == 0 )
4440 LogPrintf("CheckBlock header error");
4446 //if ( !CheckEquihashSolution(&block, Params()) )
4447 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4448 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
4449 if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
4451 int32_t z; for (z=31; z>=0; z--)
4452 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
4453 fprintf(stderr," failed hash ht.%d\n",height);
4454 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
4456 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
4457 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4459 // Check the merkle root.
4460 if (fCheckMerkleRoot) {
4462 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4463 if (block.hashMerkleRoot != hashMerkleRoot2)
4464 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
4465 REJECT_INVALID, "bad-txnmrklroot", true);
4467 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4468 // of transactions in a block without affecting the merkle root of a block,
4469 // while still invalidating it.
4471 return state.DoS(100, error("CheckBlock: duplicate transaction"),
4472 REJECT_INVALID, "bad-txns-duplicate", true);
4475 // All potential-corruption validation must be done before we do any
4476 // transaction validation, as otherwise we may mark the header as invalid
4477 // because we receive the wrong transactions for it.
4480 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
4481 return state.DoS(100, error("CheckBlock: size limits failed"),
4482 REJECT_INVALID, "bad-blk-length");
4484 // First transaction must be coinbase, the rest must not be
4485 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
4486 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
4487 REJECT_INVALID, "bad-cb-missing");
4489 for (unsigned int i = 1; i < block.vtx.size(); i++)
4490 if (block.vtx[i].IsCoinBase())
4491 return state.DoS(100, error("CheckBlock: more than one coinbase"),
4492 REJECT_INVALID, "bad-cb-multiple");
4494 // Check transactions
4495 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
4497 CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
4498 //fprintf(stderr,"put block's tx into mempool\n");
4501 for (i=0; i<block.vtx.size(); i++)
4503 CTransaction Tx; const CTransaction &tx = (CTransaction)block.vtx[i];
4504 if ( tx.IsCoinBase() != 0 )
4506 else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || komodo_isPoS((CBlock *)&block) != 0) )
4509 if ( myAddtomempool(Tx) == false ) // happens with out of order tx in block on resync
4512 if ( rejects == 0 || rejects == lastrejects )
4514 if ( 0 && lastrejects != 0 )
4515 fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
4518 //fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
4519 lastrejects = rejects;
4522 //fprintf(stderr,"done putting block's tx into mempool\n");
4524 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4526 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
4527 return error("CheckBlock: komodo_validate_interest failed");
4528 if (!CheckTransaction(tx, state, verifier))
4529 return error("CheckBlock: CheckTransaction failed");
4531 unsigned int nSigOps = 0;
4532 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4534 nSigOps += GetLegacySigOpCount(tx);
4536 if (nSigOps > MAX_BLOCK_SIGOPS)
4537 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
4538 REJECT_INVALID, "bad-blk-sigops", true);
4539 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
4541 //static uint32_t counter;
4542 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
4543 // fprintf(stderr,"check deposit rejection\n");
4544 LogPrintf("CheckBlockHeader komodo_check_deposit error");
4550 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4552 const CChainParams& chainParams = Params();
4553 const Consensus::Params& consensusParams = chainParams.GetConsensus();
4554 uint256 hash = block.GetHash();
4555 if (hash == consensusParams.hashGenesisBlock)
4560 int nHeight = pindexPrev->GetHeight()+1;
4562 // Check proof of work
4563 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
4565 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) <<
4566 " for block #" << nHeight << endl;
4567 return state.DoS(100, error("%s: incorrect proof of work", __func__),
4568 REJECT_INVALID, "bad-diffbits");
4571 // Check timestamp against prev
4572 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
4574 return state.Invalid(error("%s: block's timestamp is too early", __func__),
4575 REJECT_INVALID, "time-too-old");
4578 // Check that timestamp is not too far in the future
4579 if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
4581 return state.Invalid(error("%s: block timestamp too far in the future", __func__),
4582 REJECT_INVALID, "time-too-new");
4585 if (fCheckpointsEnabled)
4587 // Check that the block chain matches the known block chain up to a checkpoint
4588 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
4590 /*CBlockIndex *heightblock = chainActive[nHeight];
4591 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4593 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4596 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
4598 // Don't accept any forks from the main chain prior to last checkpoint
4599 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
4600 int32_t notarized_height;
4601 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() > 1 )
4603 CBlockIndex *heightblock = chainActive[nHeight];
4604 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4606 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
4610 if ( pcheckpoint != 0 && nHeight < pcheckpoint->GetHeight() )
4611 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->GetHeight()));
4612 if ( komodo_checkpoint(¬arized_height,nHeight,hash) < 0 )
4614 CBlockIndex *heightblock = chainActive[nHeight];
4615 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4617 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4619 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4623 // Reject block.nVersion < 4 blocks
4624 if (block.nVersion < 4)
4625 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4626 REJECT_OBSOLETE, "bad-version");
4631 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4633 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->GetHeight() + 1;
4634 const Consensus::Params& consensusParams = Params().GetConsensus();
4636 // Check that all transactions are finalized
4637 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
4639 // Check transaction contextually against consensus rules at block height
4640 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4641 return false; // Failure reason has been set in validation state object
4644 int nLockTimeFlags = 0;
4645 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4646 ? pindexPrev->GetMedianTimePast()
4647 : block.GetBlockTime();
4648 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4649 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4653 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4654 // In Zcash this has been enforced since launch, except that the genesis
4655 // block didn't include the height in the coinbase (see Zcash protocol spec
4656 // section '6.8 Bitcoin Improvement Proposals').
4659 CScript expect = CScript() << nHeight;
4660 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4661 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4662 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4668 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4670 static uint256 zero;
4671 const CChainParams& chainparams = Params();
4672 AssertLockHeld(cs_main);
4674 // Check for duplicate
4675 uint256 hash = block.GetHash();
4676 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4677 CBlockIndex *pindex = NULL;
4678 if (miSelf != mapBlockIndex.end())
4680 // Block header is already known.
4681 if ( (pindex= miSelf->second) == 0 )
4682 miSelf->second = pindex = AddToBlockIndex(block);
4685 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4686 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4687 /*if ( pindex != 0 && hash == komodo_requestedhash )
4689 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4690 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4691 komodo_requestedcount = 0;
4694 //if ( pindex == 0 )
4695 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4698 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state,0))
4700 if ( *futureblockp == 0 )
4702 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4706 // Get prev block index
4707 CBlockIndex* pindexPrev = NULL;
4708 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4710 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4711 if (mi == mapBlockIndex.end())
4713 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4715 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4717 pindexPrev = (*mi).second;
4718 if (pindexPrev == 0 )
4720 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4723 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4724 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4726 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4728 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4729 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4734 if ( (pindex= AddToBlockIndex(block)) != 0 )
4736 miSelf = mapBlockIndex.find(hash);
4737 if (miSelf != mapBlockIndex.end())
4738 miSelf->second = pindex;
4739 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4744 /*if ( pindex != 0 && hash == komodo_requestedhash )
4746 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4747 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4748 komodo_requestedcount = 0;
4753 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4755 const CChainParams& chainparams = Params();
4756 AssertLockHeld(cs_main);
4758 CBlockIndex *&pindex = *ppindex;
4759 if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
4761 if ( *futureblockp == 0 )
4763 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4769 LogPrintf("AcceptBlock null pindex\n");
4770 *futureblockp = true;
4773 //fprintf(stderr,"acceptblockheader passed\n");
4774 // Try to process all requested blocks that we don't have, but only
4775 // process an unrequested block if it's new and has enough work to
4776 // advance our tip, and isn't too many blocks ahead.
4777 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4778 bool fHasMoreWork = (chainActive.Tip() ? pindex->chainPower > chainActive.Tip()->chainPower : true);
4779 // Blocks that are too out-of-order needlessly limit the effectiveness of
4780 // pruning, because pruning will not delete block files that contain any
4781 // blocks which are too close in height to the tip. Apply this test
4782 // regardless of whether pruning is enabled; it should generally be safe to
4783 // not process unrequested blocks.
4784 bool fTooFarAhead = (pindex->GetHeight() > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4786 // TODO: deal better with return value and error conditions for duplicate
4787 // and unrequested blocks.
4788 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4789 if (fAlreadyHave) return true;
4790 if (!fRequested) { // If we didn't ask for it:
4791 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4792 if (!fHasMoreWork) return true; // Don't process less-work chains
4793 if (fTooFarAhead) return true; // Block height is too high
4796 // See method docstring for why this is always disabled
4797 auto verifier = libzcash::ProofVerifier::Disabled();
4798 if ((!CheckBlock(futureblockp,pindex->GetHeight(),pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4800 if ( *futureblockp == 0 )
4802 if (state.IsInvalid() && !state.CorruptionPossible()) {
4803 pindex->nStatus |= BLOCK_FAILED_VALID;
4804 setDirtyBlockIndex.insert(pindex);
4806 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4811 int nHeight = pindex->GetHeight();
4812 // Write block to history file
4814 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4815 CDiskBlockPos blockPos;
4818 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4819 return error("AcceptBlock(): FindBlockPos failed");
4821 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4822 AbortNode(state, "Failed to write block");
4823 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4824 return error("AcceptBlock(): ReceivedBlockTransactions failed");
4825 } catch (const std::runtime_error& e) {
4826 return AbortNode(state, std::string("System error: ") + e.what());
4829 if (fCheckForPruning)
4830 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4831 if ( *futureblockp == 0 )
4833 LogPrintf("AcceptBlock block from future error\n");
4837 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4839 unsigned int nFound = 0;
4840 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4842 if (pstart->nVersion >= minVersion)
4844 pstart = pstart->pprev;
4846 return (nFound >= nRequired);
4849 void komodo_currentheight_set(int32_t height);
4851 CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4853 CBlockIndex *pindex = 0;
4854 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4855 if ( miSelf != mapBlockIndex.end() )
4857 if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4859 miSelf->second = AddToBlockIndex(*pblock);
4860 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4862 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4864 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4865 if ( miSelf != mapBlockIndex.end() )
4867 if ( miSelf->second == 0 )
4869 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4870 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4878 CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
4880 CBlockIndex *pindex=0,*previndex=0;
4881 if ( (pindex= mapBlockIndex[hash]) == 0 )
4883 pindex = new CBlockIndex();
4885 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4886 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4887 pindex->phashBlock = &((*mi).first);
4889 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4890 if ( miSelf == mapBlockIndex.end() )
4892 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4895 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4899 pindex = AddToBlockIndex(*pblock);
4900 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4904 miSelf->second = pindex;
4905 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4906 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4908 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4910 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4911 if ( miSelf == mapBlockIndex.end() )
4912 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4913 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4915 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4917 if ( previndex == 0 )
4918 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4919 if ( previndex != 0 )
4921 miSelf->second = previndex;
4922 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4923 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4925 } else LogPrintf("komodo_ensure unexpected null miprev\n");
4931 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
4933 // Preliminary checks
4934 bool checked; uint256 hash; int32_t futureblock=0;
4935 auto verifier = libzcash::ProofVerifier::Disabled();
4936 hash = pblock->GetHash();
4937 //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
4940 if ( chainActive.LastTip() != 0 )
4941 komodo_currentheight_set(chainActive.LastTip()->GetHeight());
4942 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
4943 bool fRequested = MarkBlockAsReceived(hash);
4944 fRequested |= fForceProcessing;
4945 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
4948 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
4950 if (!checked && futureblock == 0)
4954 Misbehaving(pfrom->GetId(), 1);
4956 return error("%s: CheckBlock FAILED", __func__);
4959 CBlockIndex *pindex = NULL;
4962 // // without the komodo_ensure call, it is quite possible to get a non-error but null pindex returned from AcceptBlockHeader. In a 2 node network, it will be a long time before that block is reprocessed. Even though restarting makes it rescan, it seems much better to keep the nodes in sync
4963 // komodo_ensure(pblock, hash);
4965 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
4966 if (pindex && pfrom) {
4967 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
4970 if (!ret && futureblock == 0)
4971 return error("%s: AcceptBlock FAILED", __func__);
4972 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
4975 if (futureblock == 0 && !ActivateBestChain(state, pblock))
4976 return error("%s: ActivateBestChain failed", __func__);
4977 //fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
4982 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4984 AssertLockHeld(cs_main);
4985 assert(pindexPrev == chainActive.Tip());
4987 CCoinsViewCache viewNew(pcoinsTip);
4988 CBlockIndex indexDummy(block);
4989 indexDummy.pprev = pindexPrev;
4990 indexDummy.SetHeight(pindexPrev->GetHeight() + 1);
4991 // JoinSplit proofs are verified in ConnectBlock
4992 auto verifier = libzcash::ProofVerifier::Disabled();
4993 // NOTE: CheckBlockHeader is called by CheckBlock
4994 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4996 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
4999 int32_t futureblock;
5000 if (!CheckBlock(&futureblock,indexDummy.GetHeight(),0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
5002 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
5005 if (!ContextualCheckBlock(block, state, pindexPrev))
5007 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
5010 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
5012 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
5015 assert(state.IsValid());
5016 if ( futureblock != 0 )
5022 * BLOCK PRUNING CODE
5025 /* Calculate the amount of disk space the block & undo files currently use */
5026 uint64_t CalculateCurrentUsage()
5028 uint64_t retval = 0;
5029 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
5030 retval += file.nSize + file.nUndoSize;
5035 /* Prune a block file (modify associated database entries)*/
5036 void PruneOneBlockFile(const int fileNumber)
5038 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
5039 CBlockIndex* pindex = it->second;
5040 if (pindex->nFile == fileNumber) {
5041 pindex->nStatus &= ~BLOCK_HAVE_DATA;
5042 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
5044 pindex->nDataPos = 0;
5045 pindex->nUndoPos = 0;
5046 setDirtyBlockIndex.insert(pindex);
5048 // Prune from mapBlocksUnlinked -- any block we prune would have
5049 // to be downloaded again in order to consider its chain, at which
5050 // point it would be considered as a candidate for
5051 // mapBlocksUnlinked or setBlockIndexCandidates.
5052 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
5053 while (range.first != range.second) {
5054 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
5056 if (it->second == pindex) {
5057 mapBlocksUnlinked.erase(it);
5063 vinfoBlockFile[fileNumber].SetNull();
5064 setDirtyFileInfo.insert(fileNumber);
5068 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
5070 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
5071 CDiskBlockPos pos(*it, 0);
5072 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
5073 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
5074 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
5078 /* Calculate the block/rev files that should be deleted to remain under target*/
5079 void FindFilesToPrune(std::set<int>& setFilesToPrune)
5081 LOCK2(cs_main, cs_LastBlockFile);
5082 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
5085 if (chainActive.Tip()->GetHeight() <= Params().PruneAfterHeight()) {
5088 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->GetHeight() - MIN_BLOCKS_TO_KEEP;
5089 uint64_t nCurrentUsage = CalculateCurrentUsage();
5090 // We don't check to prune until after we've allocated new space for files
5091 // So we should leave a buffer under our target to account for another allocation
5092 // before the next pruning.
5093 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
5094 uint64_t nBytesToPrune;
5097 if (nCurrentUsage + nBuffer >= nPruneTarget) {
5098 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
5099 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
5101 if (vinfoBlockFile[fileNumber].nSize == 0)
5104 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
5107 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
5108 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
5111 PruneOneBlockFile(fileNumber);
5112 // Queue up the files for removal
5113 setFilesToPrune.insert(fileNumber);
5114 nCurrentUsage -= nBytesToPrune;
5119 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
5120 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
5121 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
5122 nLastBlockWeCanPrune, count);
5125 bool CheckDiskSpace(uint64_t nAdditionalBytes)
5127 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
5129 // Check for nMinDiskSpace bytes (currently 50MB)
5130 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
5131 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
5136 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
5138 static int32_t didinit[64];
5141 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5142 boost::filesystem::create_directories(path.parent_path());
5143 FILE* file = fopen(path.string().c_str(), "rb+");
5144 if (!file && !fReadOnly)
5145 file = fopen(path.string().c_str(), "wb+");
5147 LogPrintf("Unable to open file %s\n", path.string());
5150 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
5152 komodo_prefetch(file);
5153 didinit[pos.nFile] = 1;
5156 if (fseek(file, pos.nPos, SEEK_SET)) {
5157 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5165 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
5166 return OpenDiskFile(pos, "blk", fReadOnly);
5169 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5170 return OpenDiskFile(pos, "rev", fReadOnly);
5173 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
5175 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
5178 CBlockIndex * InsertBlockIndex(uint256 hash)
5184 BlockMap::iterator mi = mapBlockIndex.find(hash);
5185 if (mi != mapBlockIndex.end())
5186 return (*mi).second;
5189 CBlockIndex* pindexNew = new CBlockIndex();
5191 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
5192 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
5193 pindexNew->phashBlock = &((*mi).first);
5194 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
5199 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
5201 bool static LoadBlockIndexDB()
5203 const CChainParams& chainparams = Params();
5204 LogPrintf("%s: start loading guts\n", __func__);
5205 if (!pblocktree->LoadBlockIndexGuts())
5207 LogPrintf("%s: loaded guts\n", __func__);
5208 boost::this_thread::interruption_point();
5210 // Calculate chainPower
5211 vector<pair<int, CBlockIndex*> > vSortedByHeight;
5212 vSortedByHeight.reserve(mapBlockIndex.size());
5213 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5215 CBlockIndex* pindex = item.second;
5216 vSortedByHeight.push_back(make_pair(pindex->GetHeight(), pindex));
5217 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5219 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
5220 sort(vSortedByHeight.begin(), vSortedByHeight.end());
5221 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
5222 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
5224 CBlockIndex* pindex = item.second;
5225 pindex->chainPower = (pindex->pprev ? CChainPower(pindex) + pindex->pprev->chainPower : CChainPower(pindex)) + GetBlockProof(*pindex);
5226 // We can link the chain of blocks for which we've received transactions at some point.
5227 // Pruned nodes may have deleted the block.
5228 if (pindex->nTx > 0) {
5229 if (pindex->pprev) {
5230 if (pindex->pprev->nChainTx) {
5231 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
5232 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
5233 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
5235 pindex->nChainSproutValue = boost::none;
5237 if (pindex->pprev->nChainSaplingValue) {
5238 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
5240 pindex->nChainSaplingValue = boost::none;
5243 pindex->nChainTx = 0;
5244 pindex->nChainSproutValue = boost::none;
5245 pindex->nChainSaplingValue = boost::none;
5246 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
5249 pindex->nChainTx = pindex->nTx;
5250 pindex->nChainSproutValue = pindex->nSproutValue;
5251 pindex->nChainSaplingValue = pindex->nSaplingValue;
5254 // Construct in-memory chain of branch IDs.
5255 // Relies on invariant: a block that does not activate a network upgrade
5256 // will always be valid under the same consensus rules as its parent.
5257 // Genesis block has a branch ID of zero by definition, but has no
5258 // validity status because it is side-loaded into a fresh chain.
5259 // Activation blocks will have branch IDs set (read from disk).
5260 if (pindex->pprev) {
5261 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
5262 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
5265 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
5267 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
5268 setBlockIndexCandidates.insert(pindex);
5269 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->chainPower > pindexBestInvalid->chainPower))
5270 pindexBestInvalid = pindex;
5272 pindex->BuildSkip();
5273 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
5274 pindexBestHeader = pindex;
5275 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5277 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
5279 // Load block file info
5280 pblocktree->ReadLastBlockFile(nLastBlockFile);
5281 vinfoBlockFile.resize(nLastBlockFile + 1);
5282 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
5283 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
5284 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
5286 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
5287 for (int nFile = nLastBlockFile + 1; true; nFile++) {
5288 CBlockFileInfo info;
5289 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
5290 vinfoBlockFile.push_back(info);
5296 // Check presence of blk files
5297 LogPrintf("Checking all blk files are present...\n");
5298 set<int> setBlkDataFiles;
5299 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5301 CBlockIndex* pindex = item.second;
5302 if (pindex->nStatus & BLOCK_HAVE_DATA) {
5303 setBlkDataFiles.insert(pindex->nFile);
5305 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5307 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
5308 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
5310 CDiskBlockPos pos(*it, 0);
5311 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
5316 // Check whether we have ever pruned block & undo files
5317 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
5319 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
5321 // Check whether we need to continue reindexing
5322 bool fReindexing = false;
5323 pblocktree->ReadReindexing(fReindexing);
5324 fReindex |= fReindexing;
5326 // Check whether we have a transaction index
5327 pblocktree->ReadFlag("txindex", fTxIndex);
5328 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
5329 // Check whether we have an address index
5330 pblocktree->ReadFlag("addressindex", fAddressIndex);
5331 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
5333 // Check whether we have a timestamp index
5334 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
5335 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
5337 // Check whether we have a spent index
5338 pblocktree->ReadFlag("spentindex", fSpentIndex);
5339 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
5341 // Fill in-memory data
5342 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5344 CBlockIndex* pindex = item.second;
5345 // - This relationship will always be true even if pprev has multiple
5346 // children, because hashSproutAnchor is technically a property of pprev,
5347 // not its children.
5348 // - This will miss chain tips; we handle the best tip below, and other
5349 // tips will be handled by ConnectTip during a re-org.
5350 if (pindex->pprev) {
5351 pindex->pprev->hashFinalSproutRoot = pindex->hashSproutAnchor;
5353 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5356 // Load pointer to end of best chain
5357 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
5358 if (it == mapBlockIndex.end())
5361 chainActive.SetTip(it->second);
5363 // Set hashFinalSproutRoot for the end of best chain
5364 it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT);
5366 PruneBlockIndexCandidates();
5369 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
5370 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
5372 int32_t longestchain = komodo_longestchain();
5373 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
5374 // runs, which makes it return 0, so we guess 50% for now
5375 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
5378 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
5379 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
5380 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
5383 EnforceNodeDeprecation(chainActive.Height(), true);
5388 CVerifyDB::CVerifyDB()
5390 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
5393 CVerifyDB::~CVerifyDB()
5395 uiInterface.ShowProgress("", 100);
5398 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
5401 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
5404 // Verify blocks in the best chain
5405 if (nCheckDepth <= 0)
5406 nCheckDepth = 1000000000; // suffices until the year 19000
5407 if (nCheckDepth > chainActive.Height())
5408 nCheckDepth = chainActive.Height();
5409 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
5410 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
5411 CCoinsViewCache coins(coinsview);
5412 CBlockIndex* pindexState = chainActive.Tip();
5413 CBlockIndex* pindexFailure = NULL;
5414 int nGoodTransactions = 0;
5415 CValidationState state;
5416 // No need to verify JoinSplits twice
5417 auto verifier = libzcash::ProofVerifier::Disabled();
5418 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
5419 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
5421 boost::this_thread::interruption_point();
5422 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
5423 if (pindex->GetHeight() < chainActive.Height()-nCheckDepth)
5426 // check level 0: read from disk
5427 if (!ReadBlockFromDisk(block, pindex,0))
5428 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5429 // check level 1: verify block validity
5430 int32_t futureblock;
5431 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, verifier,0) )
5432 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5433 // check level 2: verify undo validity
5434 if (nCheckLevel >= 2 && pindex) {
5436 CDiskBlockPos pos = pindex->GetUndoPos();
5437 if (!pos.IsNull()) {
5438 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5439 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5442 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
5443 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
5445 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5446 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5447 pindexState = pindex->pprev;
5449 nGoodTransactions = 0;
5450 pindexFailure = pindex;
5452 nGoodTransactions += block.vtx.size();
5454 if (ShutdownRequested())
5457 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
5459 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->GetHeight() + 1, nGoodTransactions);
5461 // check level 4: try reconnecting blocks
5462 if (nCheckLevel >= 4) {
5463 CBlockIndex *pindex = pindexState;
5464 while (pindex != chainActive.Tip()) {
5465 boost::this_thread::interruption_point();
5466 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * 50))));
5467 pindex = chainActive.Next(pindex);
5469 if (!ReadBlockFromDisk(block, pindex,0))
5470 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5471 if (!ConnectBlock(block, state, pindex, coins,false, true))
5472 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5476 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions);
5481 bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches)
5485 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
5486 // index will have nCachedBranchId set based on the values previously persisted
5487 // to disk. By definition, a set nCachedBranchId means that the block was
5488 // fully-validated under the corresponding consensus rules. Thus we can quickly
5489 // identify whether the current active chain matches our expected sequence of
5490 // consensus rule changes, with two checks:
5492 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
5493 // - nCachedBranchId for each block matches what we expect.
5494 auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) {
5495 auto consensus = params.GetConsensus();
5496 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5497 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->GetHeight(), consensus);
5498 return fFlagSet == fFlagExpected &&
5499 pindex->nCachedBranchId &&
5500 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->GetHeight(), consensus);
5504 while (nHeight <= chainActive.Height()) {
5505 if (!sufficientlyValidated(chainActive[nHeight])) {
5511 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
5512 auto rewindLength = chainActive.Height() - nHeight;
5513 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH)
5515 auto pindexOldTip = chainActive.Tip();
5516 auto pindexRewind = chainActive[nHeight - 1];
5517 auto msg = strprintf(_(
5518 "A block chain rewind has been detected that would roll back %d blocks! "
5519 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5520 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5521 _("Rewind details") + ":\n" +
5522 "- " + strprintf(_("Current tip: %s, height %d"),
5523 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight()) + "\n" +
5524 "- " + strprintf(_("Rewinding to: %s, height %d"),
5525 pindexRewind->phashBlock->GetHex(), pindexRewind->GetHeight()) + "\n\n" +
5526 _("Please help, human!");
5527 LogPrintf("*** %s\n", msg);
5528 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5533 CValidationState state;
5534 CBlockIndex* pindex = chainActive.Tip();
5535 while (chainActive.Height() >= nHeight) {
5536 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5537 // If pruning, don't try rewinding past the HAVE_DATA point;
5538 // since older blocks can't be served anyway, there's
5539 // no need to walk further, and trying to DisconnectTip()
5540 // will fail (and require a needless reindex/redownload
5541 // of the blockchain).
5544 if (!DisconnectTip(state, true)) {
5545 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->GetHeight());
5547 // Occasionally flush state to disk.
5548 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5552 // Reduce validity flag and have-data flags.
5554 // Collect blocks to be removed (blocks in mapBlockIndex must be at least BLOCK_VALID_TREE).
5555 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5556 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5557 std::vector<const CBlockIndex*> vBlocks;
5558 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5559 CBlockIndex* pindexIter = it->second;
5561 // Note: If we encounter an insufficiently validated block that
5562 // is on chainActive, it must be because we are a pruning node, and
5563 // this block or some successor doesn't HAVE_DATA, so we were unable to
5564 // rewind all the way. Blocks remaining on chainActive at this point
5565 // must not have their validity reduced.
5566 if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
5568 pindexIter->nStatus =
5569 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5570 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
5571 // Remove have-data flags
5572 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
5574 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
5575 pindexIter->nCachedBranchId = boost::none;
5576 // Remove storage location
5577 pindexIter->nFile = 0;
5578 pindexIter->nDataPos = 0;
5579 pindexIter->nUndoPos = 0;
5580 // Remove various other things
5581 pindexIter->nTx = 0;
5582 pindexIter->nChainTx = 0;
5583 pindexIter->nSproutValue = boost::none;
5584 pindexIter->nChainSproutValue = boost::none;
5585 pindexIter->nSaplingValue = 0;
5586 pindexIter->nChainSaplingValue = boost::none;
5587 pindexIter->nSequenceId = 0;
5589 // Make sure it gets written
5590 /* corresponds to commented out block below as an alternative to setDirtyBlockIndex
5591 vBlocks.push_back(pindexIter);
5593 setDirtyBlockIndex.insert(pindexIter);
5594 if (pindexIter == pindexBestInvalid)
5596 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
5597 pindexBestInvalid = NULL;
5601 setBlockIndexCandidates.erase(pindexIter);
5602 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
5603 while (ret.first != ret.second) {
5604 if (ret.first->second == pindexIter) {
5605 mapBlocksUnlinked.erase(ret.first++);
5610 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5611 setBlockIndexCandidates.insert(pindexIter);
5616 // Set pindexBestHeader to the current chain tip
5617 // (since we are about to delete the block it is pointing to)
5618 pindexBestHeader = chainActive.Tip();
5620 // Erase block indices on-disk
5621 if (!pblocktree->EraseBatchSync(vBlocks)) {
5622 return AbortNode(state, "Failed to erase from block index database");
5625 // Erase block indices in-memory
5626 for (auto pindex : vBlocks) {
5627 auto ret = mapBlockIndex.find(*pindex->phashBlock);
5628 if (ret != mapBlockIndex.end()) {
5629 mapBlockIndex.erase(ret);
5635 PruneBlockIndexCandidates();
5639 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5646 void UnloadBlockIndex()
5649 setBlockIndexCandidates.clear();
5650 chainActive.SetTip(NULL);
5651 pindexBestInvalid = NULL;
5652 pindexBestHeader = NULL;
5654 mapOrphanTransactions.clear();
5655 mapOrphanTransactionsByPrev.clear();
5657 mapBlocksUnlinked.clear();
5658 vinfoBlockFile.clear();
5660 nBlockSequenceId = 1;
5661 mapBlockSource.clear();
5662 mapBlocksInFlight.clear();
5663 nQueuedValidatedHeaders = 0;
5664 nPreferredDownload = 0;
5665 setDirtyBlockIndex.clear();
5666 setDirtyFileInfo.clear();
5667 mapNodeState.clear();
5668 recentRejects.reset(NULL);
5670 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5671 delete entry.second;
5673 mapBlockIndex.clear();
5674 fHavePruned = false;
5677 bool LoadBlockIndex()
5679 // Load block index from databases
5680 KOMODO_LOADINGBLOCKS = 1;
5681 if (!fReindex && !LoadBlockIndexDB())
5683 KOMODO_LOADINGBLOCKS = 0;
5686 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5691 bool InitBlockIndex() {
5692 const CChainParams& chainparams = Params();
5695 // Initialize global variables that cannot be constructed at startup.
5696 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5697 // Check whether we're already initialized
5698 if (chainActive.Genesis() != NULL)
5702 // Use the provided setting for -txindex in the new database
5703 fTxIndex = GetBoolArg("-txindex", true);
5704 pblocktree->WriteFlag("txindex", fTxIndex);
5705 // Use the provided setting for -addressindex in the new database
5706 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5707 pblocktree->WriteFlag("addressindex", fAddressIndex);
5709 // Use the provided setting for -timestampindex in the new database
5710 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5711 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5713 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5714 pblocktree->WriteFlag("spentindex", fSpentIndex);
5715 fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
5716 LogPrintf("Initializing databases...\n");
5718 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5721 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5722 // Start new block file
5723 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5724 CDiskBlockPos blockPos;
5725 CValidationState state;
5726 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5727 return error("LoadBlockIndex(): FindBlockPos failed");
5728 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5729 return error("LoadBlockIndex(): writing genesis block to disk failed");
5730 CBlockIndex *pindex = AddToBlockIndex(block);
5732 return error("LoadBlockIndex(): couldnt add to block index");
5733 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5734 return error("LoadBlockIndex(): genesis block not accepted");
5735 if (!ActivateBestChain(state, &block))
5736 return error("LoadBlockIndex(): genesis block cannot be activated");
5737 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5738 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5739 } catch (const std::runtime_error& e) {
5740 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5749 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5751 const CChainParams& chainparams = Params();
5752 // Map of disk positions for blocks with unknown parent (only used for reindex)
5753 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5754 int64_t nStart = GetTimeMillis();
5758 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5759 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5760 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5761 uint64_t nRewind = blkdat.GetPos();
5762 while (!blkdat.eof()) {
5763 boost::this_thread::interruption_point();
5765 blkdat.SetPos(nRewind);
5766 nRewind++; // start one byte further next time, in case of failure
5767 blkdat.SetLimit(); // remove former limit
5768 unsigned int nSize = 0;
5771 unsigned char buf[MESSAGE_START_SIZE];
5772 blkdat.FindByte(Params().MessageStart()[0]);
5773 nRewind = blkdat.GetPos()+1;
5774 blkdat >> FLATDATA(buf);
5775 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5779 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5781 } catch (const std::exception&) {
5782 // no valid block header found; don't complain
5787 uint64_t nBlockPos = blkdat.GetPos();
5789 dbp->nPos = nBlockPos;
5790 blkdat.SetLimit(nBlockPos + nSize);
5791 blkdat.SetPos(nBlockPos);
5794 nRewind = blkdat.GetPos();
5796 // detect out of order blocks, and store them for later
5797 uint256 hash = block.GetHash();
5798 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5799 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5800 block.hashPrevBlock.ToString());
5802 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5806 // process in case the block isn't known yet
5807 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5808 CValidationState state;
5809 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5811 if (state.IsError())
5813 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->GetHeight() % 1000 == 0) {
5814 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->GetHeight());
5817 // Recursively process earlier encountered successors of this block
5818 deque<uint256> queue;
5819 queue.push_back(hash);
5820 while (!queue.empty()) {
5821 uint256 head = queue.front();
5823 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5824 while (range.first != range.second) {
5825 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5826 if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->GetHeight():0,block, it->second,1))
5828 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5830 CValidationState dummy;
5831 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5834 queue.push_back(block.GetHash());
5838 mapBlocksUnknownParent.erase(it);
5841 } catch (const std::exception& e) {
5842 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5845 } catch (const std::runtime_error& e) {
5846 AbortNode(std::string("System error: ") + e.what());
5849 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5853 void static CheckBlockIndex()
5855 const Consensus::Params& consensusParams = Params().GetConsensus();
5856 if (!fCheckBlockIndex) {
5862 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5863 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5864 // iterating the block tree require that chainActive has been initialized.)
5865 if (chainActive.Height() < 0) {
5866 assert(mapBlockIndex.size() <= 1);
5870 // Build forward-pointing map of the entire block tree.
5871 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5872 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5873 if ( it->second != 0 )
5874 forward.insert(std::make_pair(it->second->pprev, it->second));
5876 if ( Params().NetworkIDString() != "regtest" )
5877 assert(forward.size() == mapBlockIndex.size());
5879 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5880 CBlockIndex *pindex = rangeGenesis.first->second;
5881 rangeGenesis.first++;
5882 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5884 // Iterate over the entire block tree, using depth-first search.
5885 // Along the way, remember whether there are blocks on the path from genesis
5886 // block being explored which are the first to have certain properties.
5889 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5890 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5891 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5892 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5893 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5894 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5895 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5896 while (pindex != NULL) {
5898 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5899 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5900 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5901 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5902 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5903 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5904 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5906 // Begin: actual consistency checks.
5907 if (pindex->pprev == NULL) {
5908 // Genesis block checks.
5909 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5910 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5912 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
5913 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5914 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5916 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5917 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5918 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5920 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5921 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5923 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5924 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5925 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5926 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5927 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5928 assert(pindex->GetHeight() == nHeight); // nHeight must be consistent.
5929 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.
5930 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->GetHeight() < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5931 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5932 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5933 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5934 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5935 if (pindexFirstInvalid == NULL) {
5936 // Checks for not-invalid blocks.
5937 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5939 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5940 if (pindexFirstInvalid == NULL) {
5941 // If this block sorts at least as good as the current tip and
5942 // is valid and we have all data for its parents, it must be in
5943 // setBlockIndexCandidates. chainActive.Tip() must also be there
5944 // even if some data has been pruned.
5945 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5946 assert(setBlockIndexCandidates.count(pindex));
5948 // If some parent is missing, then it could be that this block was in
5949 // setBlockIndexCandidates but had to be removed because of the missing data.
5950 // In this case it must be in mapBlocksUnlinked -- see test below.
5952 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
5953 assert(setBlockIndexCandidates.count(pindex) == 0);
5955 // Check whether this block is in mapBlocksUnlinked.
5956 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5957 bool foundInUnlinked = false;
5958 while (rangeUnlinked.first != rangeUnlinked.second) {
5959 assert(rangeUnlinked.first->first == pindex->pprev);
5960 if (rangeUnlinked.first->second == pindex) {
5961 foundInUnlinked = true;
5964 rangeUnlinked.first++;
5966 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5967 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5968 assert(foundInUnlinked);
5970 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5971 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5972 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5973 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5974 assert(fHavePruned); // We must have pruned.
5975 // This block may have entered mapBlocksUnlinked if:
5976 // - it has a descendant that at some point had more work than the
5978 // - we tried switching to that descendant but were missing
5979 // data for some intermediate block between chainActive and the
5981 // So if this block is itself better than chainActive.Tip() and it wasn't in
5982 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5983 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5984 if (pindexFirstInvalid == NULL) {
5985 assert(foundInUnlinked);
5989 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5990 // End: actual consistency checks.
5992 // Try descending into the first subnode.
5993 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5994 if (range.first != range.second) {
5995 // A subnode was found.
5996 pindex = range.first->second;
6000 // This is a leaf node.
6001 // Move upwards until we reach a node of which we have not yet visited the last child.
6003 // We are going to either move to a parent or a sibling of pindex.
6004 // If pindex was the first with a certain property, unset the corresponding variable.
6005 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
6006 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
6007 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
6008 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
6009 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
6010 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
6011 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
6013 CBlockIndex* pindexPar = pindex->pprev;
6014 // Find which child we just visited.
6015 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
6016 while (rangePar.first->second != pindex) {
6017 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
6020 // Proceed to the next one.
6022 if (rangePar.first != rangePar.second) {
6023 // Move to the sibling.
6024 pindex = rangePar.first->second;
6035 // Check that we actually traversed the entire map.
6036 assert(nNodes == forward.size());
6039 //////////////////////////////////////////////////////////////////////////////
6044 std::string GetWarnings(const std::string& strFor)
6047 string strStatusBar;
6050 if (!CLIENT_VERSION_IS_RELEASE)
6051 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
6053 if (GetBoolArg("-testsafemode", false))
6054 strStatusBar = strRPC = "testsafemode enabled";
6056 // Misc warnings like out of disk space and clock is wrong
6057 if (strMiscWarning != "")
6060 strStatusBar = strMiscWarning;
6063 if (fLargeWorkForkFound)
6066 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
6068 else if (fLargeWorkInvalidChainFound)
6071 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.");
6077 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6079 const CAlert& alert = item.second;
6080 if (alert.AppliesToMe() && alert.nPriority > nPriority)
6082 nPriority = alert.nPriority;
6083 strStatusBar = alert.strStatusBar;
6084 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
6085 strRPC = alert.strRPCError;
6091 if (strFor == "statusbar")
6092 return strStatusBar;
6093 else if (strFor == "rpc")
6095 assert(!"GetWarnings(): invalid parameter");
6106 //////////////////////////////////////////////////////////////////////////////
6112 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
6118 assert(recentRejects);
6119 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
6121 // If the chain tip has changed previously rejected transactions
6122 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
6123 // or a double-spend. Reset the rejects filter and give those
6124 // txs a second chance.
6125 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
6126 recentRejects->reset();
6129 return recentRejects->contains(inv.hash) ||
6130 mempool.exists(inv.hash) ||
6131 mapOrphanTransactions.count(inv.hash) ||
6132 pcoinsTip->HaveCoins(inv.hash);
6135 return mapBlockIndex.count(inv.hash);
6137 // Don't know what it is, just say we already got one
6141 void static ProcessGetData(CNode* pfrom)
6143 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
6145 vector<CInv> vNotFound;
6149 while (it != pfrom->vRecvGetData.end()) {
6150 // Don't bother if send buffer is too full to respond anyway
6151 if (pfrom->nSendSize >= SendBufferSize())
6154 const CInv &inv = *it;
6156 boost::this_thread::interruption_point();
6159 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6162 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
6163 if (mi != mapBlockIndex.end())
6165 if (chainActive.Contains(mi->second)) {
6168 static const int nOneMonth = 30 * 24 * 60 * 60;
6169 // To prevent fingerprinting attacks, only send blocks outside of the active
6170 // chain if they are valid, and no more than a month older (both in time, and in
6171 // best equivalent proof of work) than the best header chain we know about.
6172 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
6173 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
6174 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
6176 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
6180 // Pruned nodes may have deleted the block, so check whether
6181 // it's available before trying to send.
6182 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
6184 // Send block from disk
6186 if (!ReadBlockFromDisk(block, (*mi).second,1))
6188 assert(!"cannot load block from disk");
6192 if (inv.type == MSG_BLOCK)
6194 //uint256 hash; int32_t z;
6195 //hash = block.GetHash();
6196 //for (z=31; z>=0; z--)
6197 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
6198 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
6199 pfrom->PushMessage("block", block);
6201 else // MSG_FILTERED_BLOCK)
6203 LOCK(pfrom->cs_filter);
6206 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
6207 pfrom->PushMessage("merkleblock", merkleBlock);
6208 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
6209 // This avoids hurting performance by pointlessly requiring a round-trip
6210 // Note that there is currently no way for a node to request any single transactions we didn't send here -
6211 // they must either disconnect and retry or request the full block.
6212 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
6213 // however we MUST always provide at least what the remote peer needs
6214 typedef std::pair<unsigned int, uint256> PairType;
6215 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
6216 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
6217 pfrom->PushMessage("tx", block.vtx[pair.first]);
6223 // Trigger the peer node to send a getblocks request for the next batch of inventory
6224 if (inv.hash == pfrom->hashContinue)
6226 // Bypass PushInventory, this must send even if redundant,
6227 // and we want it right after the last block so they don't
6228 // wait for other stuff first.
6230 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
6231 pfrom->PushMessage("inv", vInv);
6232 pfrom->hashContinue.SetNull();
6236 else if (inv.IsKnownType())
6238 // Send stream from relay memory
6239 bool pushed = false;
6242 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
6243 if (mi != mapRelay.end()) {
6244 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
6248 if (!pushed && inv.type == MSG_TX) {
6250 if (mempool.lookup(inv.hash, tx)) {
6251 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
6254 pfrom->PushMessage("tx", ss);
6259 vNotFound.push_back(inv);
6263 // Track requests for our stuff.
6264 GetMainSignals().Inventory(inv.hash);
6266 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6271 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
6273 if (!vNotFound.empty()) {
6274 // Let the peer know that we didn't find what it asked for, so it doesn't
6275 // have to wait around forever. Currently only SPV clients actually care
6276 // about this message: it's needed when they are recursively walking the
6277 // dependencies of relevant unconfirmed transactions. SPV clients want to
6278 // do that because they want to know about (and store and rebroadcast and
6279 // risk analyze) the dependencies of transactions relevant to them, without
6280 // having to download the entire memory pool.
6281 pfrom->PushMessage("notfound", vNotFound);
6285 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
6287 const CChainParams& chainparams = Params();
6288 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
6289 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
6290 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
6292 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
6296 if (strCommand == "version")
6298 // Each connection can only send one version message
6299 if (pfrom->nVersion != 0)
6301 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
6302 Misbehaving(pfrom->GetId(), 1);
6309 uint64_t nNonce = 1;
6310 int nVersion; // use temporary for version, don't set version number until validated as connected
6311 vRecv >> nVersion >> pfrom->nServices >> nTime >> addrMe;
6312 if (nVersion == 10300)
6315 if (nVersion < MIN_PEER_PROTO_VERSION)
6317 // disconnect from peers older than this proto version
6318 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6319 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6320 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
6321 pfrom->fDisconnect = true;
6325 // Reject incoming connections from nodes that don't know about the current epoch
6326 const Consensus::Params& params = Params().GetConsensus();
6327 auto currentEpoch = CurrentEpoch(GetHeight(), params);
6328 if (nVersion < params.vUpgrades[currentEpoch].nProtocolVersion)
6330 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion);
6331 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6332 strprintf("Version must be %d or greater",
6333 params.vUpgrades[currentEpoch].nProtocolVersion));
6334 pfrom->fDisconnect = true;
6339 vRecv >> addrFrom >> nNonce;
6340 if (!vRecv.empty()) {
6341 vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
6342 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
6345 vRecv >> pfrom->nStartingHeight;
6347 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
6349 pfrom->fRelayTxes = true;
6351 // Disconnect if we connected to ourself
6352 if (nNonce == nLocalHostNonce && nNonce > 1)
6354 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
6355 pfrom->fDisconnect = true;
6359 pfrom->nVersion = nVersion;
6361 pfrom->addrLocal = addrMe;
6362 if (pfrom->fInbound && addrMe.IsRoutable())
6367 // Be shy and don't send version until we hear
6368 if (pfrom->fInbound)
6369 pfrom->PushVersion();
6371 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
6373 // Potentially mark this peer as a preferred download peer.
6374 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
6377 pfrom->PushMessage("verack");
6378 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6380 if (!pfrom->fInbound)
6382 // Advertise our address
6383 if (fListen && !IsInitialBlockDownload())
6385 CAddress addr = GetLocalAddress(&pfrom->addr);
6386 if (addr.IsRoutable())
6388 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6389 pfrom->PushAddress(addr);
6390 } else if (IsPeerAddrLocalGood(pfrom)) {
6391 addr.SetIP(pfrom->addrLocal);
6392 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6393 pfrom->PushAddress(addr);
6397 // Get recent addresses
6398 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
6400 pfrom->PushMessage("getaddr");
6401 pfrom->fGetAddr = true;
6403 addrman.Good(pfrom->addr);
6405 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
6407 addrman.Add(addrFrom, addrFrom);
6408 addrman.Good(addrFrom);
6415 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6416 item.second.RelayTo(pfrom);
6419 pfrom->fSuccessfullyConnected = true;
6423 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
6425 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
6426 pfrom->cleanSubVer, pfrom->nVersion,
6427 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
6430 int64_t nTimeOffset = nTime - GetTime();
6431 pfrom->nTimeOffset = nTimeOffset;
6432 AddTimeData(pfrom->addr, nTimeOffset);
6436 else if (pfrom->nVersion == 0)
6438 // Must have a version message before anything else
6439 Misbehaving(pfrom->GetId(), 1);
6444 else if (strCommand == "verack")
6446 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6448 // Mark this node as currently connected, so we update its timestamp later.
6449 if (pfrom->fNetworkNode) {
6451 State(pfrom->GetId())->fCurrentlyConnected = true;
6456 // Disconnect existing peer connection when:
6457 // 1. The version message has been received
6458 // 2. Peer version is below the minimum version for the current epoch
6459 else if (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[
6460 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion)
6462 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6463 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6464 strprintf("Version must be %d or greater",
6465 chainparams.GetConsensus().vUpgrades[
6466 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion));
6467 pfrom->fDisconnect = true;
6472 else if (strCommand == "addr")
6474 vector<CAddress> vAddr;
6477 // Don't want addr from older versions unless seeding
6478 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
6480 if (vAddr.size() > 1000)
6482 Misbehaving(pfrom->GetId(), 20);
6483 return error("message addr size() = %u", vAddr.size());
6486 // Store the new addresses
6487 vector<CAddress> vAddrOk;
6488 int64_t nNow = GetAdjustedTime();
6489 int64_t nSince = nNow - 10 * 60;
6490 BOOST_FOREACH(CAddress& addr, vAddr)
6492 boost::this_thread::interruption_point();
6494 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6495 addr.nTime = nNow - 5 * 24 * 60 * 60;
6496 pfrom->AddAddressKnown(addr);
6497 bool fReachable = IsReachable(addr);
6498 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
6500 // Relay to a limited number of other nodes
6503 // Use deterministic randomness to send to the same nodes for 24 hours
6504 // at a time so the addrKnowns of the chosen nodes prevent repeats
6505 static uint256 hashSalt;
6506 if (hashSalt.IsNull())
6507 hashSalt = GetRandHash();
6508 uint64_t hashAddr = addr.GetHash();
6509 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
6510 hashRand = Hash(BEGIN(hashRand), END(hashRand));
6511 multimap<uint256, CNode*> mapMix;
6512 BOOST_FOREACH(CNode* pnode, vNodes)
6514 if (pnode->nVersion < CADDR_TIME_VERSION)
6516 unsigned int nPointer;
6517 memcpy(&nPointer, &pnode, sizeof(nPointer));
6518 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
6519 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6520 mapMix.insert(make_pair(hashKey, pnode));
6522 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
6523 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6524 ((*mi).second)->PushAddress(addr);
6527 // Do not store addresses outside our network
6529 vAddrOk.push_back(addr);
6531 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
6532 if (vAddr.size() < 1000)
6533 pfrom->fGetAddr = false;
6534 if (pfrom->fOneShot)
6535 pfrom->fDisconnect = true;
6539 else if (strCommand == "inv")
6543 if (vInv.size() > MAX_INV_SZ)
6545 Misbehaving(pfrom->GetId(), 20);
6546 return error("message inv size() = %u", vInv.size());
6551 std::vector<CInv> vToFetch;
6553 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
6555 const CInv &inv = vInv[nInv];
6557 boost::this_thread::interruption_point();
6558 pfrom->AddInventoryKnown(inv);
6560 bool fAlreadyHave = AlreadyHave(inv);
6561 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
6563 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6566 if (inv.type == MSG_BLOCK) {
6567 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
6568 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
6569 // First request the headers preceding the announced block. In the normal fully-synced
6570 // case where a new block is announced that succeeds the current tip (no reorganization),
6571 // there are no such headers.
6572 // Secondly, and only when we are close to being synced, we request the announced block directly,
6573 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6574 // time the block arrives, the header chain leading up to it is already validated. Not
6575 // doing this will result in the received block being rejected as an orphan in case it is
6576 // not a direct successor.
6577 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
6578 CNodeState *nodestate = State(pfrom->GetId());
6579 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
6580 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6581 vToFetch.push_back(inv);
6582 // Mark block as in flight already, even though the actual "getdata" message only goes out
6583 // later (within the same cs_main lock, though).
6584 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
6586 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->GetHeight(), inv.hash.ToString(), pfrom->id);
6590 // Track requests for our stuff
6591 GetMainSignals().Inventory(inv.hash);
6593 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6594 Misbehaving(pfrom->GetId(), 50);
6595 return error("send buffer size() = %u", pfrom->nSendSize);
6599 if (!vToFetch.empty())
6600 pfrom->PushMessage("getdata", vToFetch);
6604 else if (strCommand == "getdata")
6608 if (vInv.size() > MAX_INV_SZ)
6610 Misbehaving(pfrom->GetId(), 20);
6611 return error("message getdata size() = %u", vInv.size());
6614 if (fDebug || (vInv.size() != 1))
6615 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
6617 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
6618 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
6620 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6621 ProcessGetData(pfrom);
6625 else if (strCommand == "getblocks")
6627 CBlockLocator locator;
6629 vRecv >> locator >> hashStop;
6633 // Find the last block the caller has in the main chain
6634 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
6636 // Send the rest of the chain
6638 pindex = chainActive.Next(pindex);
6640 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
6641 for (; pindex; pindex = chainActive.Next(pindex))
6643 if (pindex->GetBlockHash() == hashStop)
6645 LogPrint("net", " getblocks stopping at %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6648 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6651 // When this block is requested, we'll send an inv that'll
6652 // trigger the peer to getblocks the next batch of inventory.
6653 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6654 pfrom->hashContinue = pindex->GetBlockHash();
6661 else if (strCommand == "getheaders")
6663 CBlockLocator locator;
6665 vRecv >> locator >> hashStop;
6669 if (IsInitialBlockDownload())
6672 CBlockIndex* pindex = NULL;
6673 if (locator.IsNull())
6675 // If locator is null, return the hashStop block
6676 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6677 if (mi == mapBlockIndex.end())
6679 pindex = (*mi).second;
6683 // Find the last block the caller has in the main chain
6684 pindex = FindForkInGlobalIndex(chainActive, locator);
6686 pindex = chainActive.Next(pindex);
6689 // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6690 vector<CNetworkBlockHeader> vHeaders;
6691 int nLimit = MAX_HEADERS_RESULTS;
6692 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.ToString(), pfrom->id);
6693 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->GetHeight() : -1) )// no need to ever suppress this
6695 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->GetHeight() : -1);
6696 for (; pindex; pindex = chainActive.Next(pindex))
6698 CBlockHeader h = pindex->GetBlockHeader();
6699 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6700 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
6701 vHeaders.push_back(pindex->GetBlockHeader());
6702 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6705 pfrom->PushMessage("headers", vHeaders);
6707 /*else if ( IS_KOMODO_NOTARY != 0 )
6709 static uint32_t counter;
6710 if ( counter++ < 3 )
6711 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);
6716 else if (strCommand == "tx")
6718 vector<uint256> vWorkQueue;
6719 vector<uint256> vEraseQueue;
6723 CInv inv(MSG_TX, tx.GetHash());
6724 pfrom->AddInventoryKnown(inv);
6728 bool fMissingInputs = false;
6729 CValidationState state;
6731 pfrom->setAskFor.erase(inv.hash);
6732 mapAlreadyAskedFor.erase(inv);
6734 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6736 mempool.check(pcoinsTip);
6737 RelayTransaction(tx);
6738 vWorkQueue.push_back(inv.hash);
6740 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6741 pfrom->id, pfrom->cleanSubVer,
6742 tx.GetHash().ToString(),
6743 mempool.mapTx.size());
6745 // Recursively process any orphan transactions that depended on this one
6746 set<NodeId> setMisbehaving;
6747 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6749 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6750 if (itByPrev == mapOrphanTransactionsByPrev.end())
6752 for (set<uint256>::iterator mi = itByPrev->second.begin();
6753 mi != itByPrev->second.end();
6756 const uint256& orphanHash = *mi;
6757 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6758 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6759 bool fMissingInputs2 = false;
6760 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6761 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6762 // anyone relaying LegitTxX banned)
6763 CValidationState stateDummy;
6766 if (setMisbehaving.count(fromPeer))
6768 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6770 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
6771 RelayTransaction(orphanTx);
6772 vWorkQueue.push_back(orphanHash);
6773 vEraseQueue.push_back(orphanHash);
6775 else if (!fMissingInputs2)
6778 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6780 // Punish peer that gave us an invalid orphan tx
6781 Misbehaving(fromPeer, nDos);
6782 setMisbehaving.insert(fromPeer);
6783 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6785 // Has inputs but not accepted to mempool
6786 // Probably non-standard or insufficient fee/priority
6787 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
6788 vEraseQueue.push_back(orphanHash);
6789 assert(recentRejects);
6790 recentRejects->insert(orphanHash);
6792 mempool.check(pcoinsTip);
6796 BOOST_FOREACH(uint256 hash, vEraseQueue)
6797 EraseOrphanTx(hash);
6799 // TODO: currently, prohibit joinsplits from entering mapOrphans
6800 else if (fMissingInputs && tx.vjoinsplit.size() == 0)
6802 AddOrphanTx(tx, pfrom->GetId());
6804 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6805 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6806 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6808 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6810 assert(recentRejects);
6811 recentRejects->insert(tx.GetHash());
6813 if (pfrom->fWhitelisted) {
6814 // Always relay transactions received from whitelisted peers, even
6815 // if they were already in the mempool or rejected from it due
6816 // to policy, allowing the node to function as a gateway for
6817 // nodes hidden behind it.
6819 // Never relay transactions that we would assign a non-zero DoS
6820 // score for, as we expect peers to do the same with us in that
6823 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6824 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6825 RelayTransaction(tx);
6827 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6828 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6833 if (state.IsInvalid(nDoS))
6835 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6836 pfrom->id, pfrom->cleanSubVer,
6837 state.GetRejectReason());
6838 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6839 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6841 Misbehaving(pfrom->GetId(), nDoS);
6845 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6847 std::vector<CBlockHeader> headers;
6849 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6850 unsigned int nCount = ReadCompactSize(vRecv);
6851 if (nCount > MAX_HEADERS_RESULTS) {
6852 Misbehaving(pfrom->GetId(), 20);
6853 return error("headers message size = %u", nCount);
6855 headers.resize(nCount);
6856 for (unsigned int n = 0; n < nCount; n++) {
6857 vRecv >> headers[n];
6858 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6864 // Nothing interesting. Stop asking this peers for more headers.
6868 CBlockIndex *pindexLast = NULL;
6869 BOOST_FOREACH(const CBlockHeader& header, headers) {
6870 //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6871 //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
6873 CValidationState state;
6874 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6875 Misbehaving(pfrom->GetId(), 20);
6876 return error("non-continuous headers sequence");
6878 int32_t futureblock;
6879 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6881 if (state.IsInvalid(nDoS) && futureblock == 0)
6883 if (nDoS > 0 && futureblock == 0)
6884 Misbehaving(pfrom->GetId(), nDoS/nDoS);
6885 return error("invalid header received");
6891 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6893 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6894 // Headers message had its maximum size; the peer may have more headers.
6895 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6896 // from there instead.
6897 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->GetHeight() != pfrom->sendhdrsreq )
6899 pfrom->sendhdrsreq = (int32_t)pindexLast->GetHeight();
6900 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->GetHeight(), pfrom->id, pfrom->nStartingHeight);
6901 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6908 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6913 CInv inv(MSG_BLOCK, block.GetHash());
6914 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6916 pfrom->AddInventoryKnown(inv);
6918 CValidationState state;
6919 // Process all blocks from whitelisted peers, even if not requested,
6920 // unless we're still syncing with the network.
6921 // Such an unrequested block may still be processed, subject to the
6922 // conditions in AcceptBlock().
6923 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6924 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
6926 if (state.IsInvalid(nDoS)) {
6927 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6928 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6931 Misbehaving(pfrom->GetId(), nDoS);
6938 // This asymmetric behavior for inbound and outbound connections was introduced
6939 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
6940 // to users' AddrMan and later request them by sending getaddr messages.
6941 // Making nodes which are behind NAT and can only make outgoing connections ignore
6942 // the getaddr message mitigates the attack.
6943 else if ((strCommand == "getaddr") && (pfrom->fInbound))
6945 // Only send one GetAddr response per connection to reduce resource waste
6946 // and discourage addr stamping of INV announcements.
6947 if (pfrom->fSentAddr) {
6948 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6951 pfrom->fSentAddr = true;
6953 pfrom->vAddrToSend.clear();
6954 vector<CAddress> vAddr = addrman.GetAddr();
6955 BOOST_FOREACH(const CAddress &addr, vAddr)
6956 pfrom->PushAddress(addr);
6960 else if (strCommand == "mempool")
6962 LOCK2(cs_main, pfrom->cs_filter);
6964 std::vector<uint256> vtxid;
6965 mempool.queryHashes(vtxid);
6967 BOOST_FOREACH(uint256& hash, vtxid) {
6968 CInv inv(MSG_TX, hash);
6969 if (pfrom->pfilter) {
6971 bool fInMemPool = mempool.lookup(hash, tx);
6972 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
6973 if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
6975 vInv.push_back(inv);
6976 if (vInv.size() == MAX_INV_SZ) {
6977 pfrom->PushMessage("inv", vInv);
6981 if (vInv.size() > 0)
6982 pfrom->PushMessage("inv", vInv);
6986 else if (strCommand == "ping")
6988 if (pfrom->nVersion > BIP0031_VERSION)
6992 // Echo the message back with the nonce. This allows for two useful features:
6994 // 1) A remote node can quickly check if the connection is operational
6995 // 2) Remote nodes can measure the latency of the network thread. If this node
6996 // is overloaded it won't respond to pings quickly and the remote node can
6997 // avoid sending us more work, like chain download requests.
6999 // The nonce stops the remote getting confused between different pings: without
7000 // it, if the remote node sends a ping once per second and this node takes 5
7001 // seconds to respond to each, the 5th ping the remote sends would appear to
7002 // return very quickly.
7003 pfrom->PushMessage("pong", nonce);
7008 else if (strCommand == "pong")
7010 int64_t pingUsecEnd = nTimeReceived;
7012 size_t nAvail = vRecv.in_avail();
7013 bool bPingFinished = false;
7014 std::string sProblem;
7016 if (nAvail >= sizeof(nonce)) {
7019 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
7020 if (pfrom->nPingNonceSent != 0) {
7021 if (nonce == pfrom->nPingNonceSent) {
7022 // Matching pong received, this ping is no longer outstanding
7023 bPingFinished = true;
7024 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
7025 if (pingUsecTime > 0) {
7026 // Successful ping time measurement, replace previous
7027 pfrom->nPingUsecTime = pingUsecTime;
7028 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
7030 // This should never happen
7031 sProblem = "Timing mishap";
7034 // Nonce mismatches are normal when pings are overlapping
7035 sProblem = "Nonce mismatch";
7037 // This is most likely a bug in another implementation somewhere; cancel this ping
7038 bPingFinished = true;
7039 sProblem = "Nonce zero";
7043 sProblem = "Unsolicited pong without ping";
7046 // This is most likely a bug in another implementation somewhere; cancel this ping
7047 bPingFinished = true;
7048 sProblem = "Short payload";
7051 if (!(sProblem.empty())) {
7052 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
7056 pfrom->nPingNonceSent,
7060 if (bPingFinished) {
7061 pfrom->nPingNonceSent = 0;
7066 else if (fAlerts && strCommand == "alert")
7071 uint256 alertHash = alert.GetHash();
7072 if (pfrom->setKnown.count(alertHash) == 0)
7074 if (alert.ProcessAlert(Params().AlertKey()))
7077 pfrom->setKnown.insert(alertHash);
7080 BOOST_FOREACH(CNode* pnode, vNodes)
7081 alert.RelayTo(pnode);
7085 // Small DoS penalty so peers that send us lots of
7086 // duplicate/expired/invalid-signature/whatever alerts
7087 // eventually get banned.
7088 // This isn't a Misbehaving(100) (immediate ban) because the
7089 // peer might be an older or different implementation with
7090 // a different signature key, etc.
7091 Misbehaving(pfrom->GetId(), 10);
7096 else if (!(nLocalServices & NODE_BLOOM) &&
7097 (strCommand == "filterload" ||
7098 strCommand == "filteradd"))
7100 if (pfrom->nVersion >= NO_BLOOM_VERSION) {
7101 Misbehaving(pfrom->GetId(), 100);
7103 } else if (GetBoolArg("-enforcenodebloom", false)) {
7104 pfrom->fDisconnect = true;
7110 else if (strCommand == "filterload")
7112 CBloomFilter filter;
7115 if (!filter.IsWithinSizeConstraints())
7116 // There is no excuse for sending a too-large filter
7117 Misbehaving(pfrom->GetId(), 100);
7120 LOCK(pfrom->cs_filter);
7121 delete pfrom->pfilter;
7122 pfrom->pfilter = new CBloomFilter(filter);
7123 pfrom->pfilter->UpdateEmptyFull();
7125 pfrom->fRelayTxes = true;
7129 else if (strCommand == "filteradd")
7131 vector<unsigned char> vData;
7134 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
7135 // and thus, the maximum size any matched object can have) in a filteradd message
7136 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
7138 Misbehaving(pfrom->GetId(), 100);
7140 LOCK(pfrom->cs_filter);
7142 pfrom->pfilter->insert(vData);
7144 Misbehaving(pfrom->GetId(), 100);
7149 else if (strCommand == "filterclear")
7151 LOCK(pfrom->cs_filter);
7152 if (nLocalServices & NODE_BLOOM) {
7153 delete pfrom->pfilter;
7154 pfrom->pfilter = new CBloomFilter();
7156 pfrom->fRelayTxes = true;
7160 else if (strCommand == "reject")
7164 string strMsg; unsigned char ccode; string strReason;
7165 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
7168 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
7170 if (strMsg == "block" || strMsg == "tx")
7174 ss << ": hash " << hash.ToString();
7176 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
7177 } catch (const std::ios_base::failure&) {
7178 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
7179 LogPrint("net", "Unparseable reject message received\n");
7183 else if (strCommand == "notfound") {
7184 // We do not care about the NOTFOUND message, but logging an Unknown Command
7185 // message would be undesirable as we transmit it ourselves.
7189 // Ignore unknown commands for extensibility
7190 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
7198 // requires LOCK(cs_vRecvMsg)
7199 bool ProcessMessages(CNode* pfrom)
7202 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
7206 // (4) message start
7214 if (!pfrom->vRecvGetData.empty())
7215 ProcessGetData(pfrom);
7217 // this maintains the order of responses
7218 if (!pfrom->vRecvGetData.empty()) return fOk;
7220 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
7221 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
7222 // Don't bother if send buffer is too full to respond anyway
7223 if (pfrom->nSendSize >= SendBufferSize())
7227 CNetMessage& msg = *it;
7230 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
7231 // msg.hdr.nMessageSize, msg.vRecv.size(),
7232 // msg.complete() ? "Y" : "N");
7234 // end, if an incomplete message is found
7235 if (!msg.complete())
7238 // at this point, any failure means we can delete the current message
7241 // Scan for message start
7242 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
7243 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
7249 CMessageHeader& hdr = msg.hdr;
7250 if (!hdr.IsValid(Params().MessageStart()))
7252 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
7255 string strCommand = hdr.GetCommand();
7258 unsigned int nMessageSize = hdr.nMessageSize;
7261 CDataStream& vRecv = msg.vRecv;
7262 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
7263 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
7264 if (nChecksum != hdr.nChecksum)
7266 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
7267 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
7275 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
7276 boost::this_thread::interruption_point();
7278 catch (const std::ios_base::failure& e)
7280 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
7281 if (strstr(e.what(), "end of data"))
7283 // Allow exceptions from under-length message on vRecv
7284 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());
7286 else if (strstr(e.what(), "size too large"))
7288 // Allow exceptions from over-long size
7289 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
7293 //PrintExceptionContinue(&e, "ProcessMessages()");
7296 catch (const boost::thread_interrupted&) {
7299 catch (const std::exception& e) {
7300 PrintExceptionContinue(&e, "ProcessMessages()");
7302 PrintExceptionContinue(NULL, "ProcessMessages()");
7306 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
7311 // In case the connection got shut down, its receive buffer was wiped
7312 if (!pfrom->fDisconnect)
7313 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
7319 bool SendMessages(CNode* pto, bool fSendTrickle)
7321 const Consensus::Params& consensusParams = Params().GetConsensus();
7323 // Don't send anything until we get its version message
7324 if (pto->nVersion == 0)
7330 bool pingSend = false;
7331 if (pto->fPingQueued) {
7332 // RPC ping request by user
7335 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
7336 // Ping automatically sent as a latency probe & keepalive.
7341 while (nonce == 0) {
7342 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
7344 pto->fPingQueued = false;
7345 pto->nPingUsecStart = GetTimeMicros();
7346 if (pto->nVersion > BIP0031_VERSION) {
7347 pto->nPingNonceSent = nonce;
7348 pto->PushMessage("ping", nonce);
7350 // Peer is too old to support ping command with nonce, pong will never arrive.
7351 pto->nPingNonceSent = 0;
7352 pto->PushMessage("ping");
7356 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
7360 // Address refresh broadcast
7361 static int64_t nLastRebroadcast;
7362 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
7365 BOOST_FOREACH(CNode* pnode, vNodes)
7367 // Periodically clear addrKnown to allow refresh broadcasts
7368 if (nLastRebroadcast)
7369 pnode->addrKnown.reset();
7371 // Rebroadcast our address
7372 AdvertizeLocal(pnode);
7374 if (!vNodes.empty())
7375 nLastRebroadcast = GetTime();
7383 vector<CAddress> vAddr;
7384 vAddr.reserve(pto->vAddrToSend.size());
7385 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
7387 if (!pto->addrKnown.contains(addr.GetKey()))
7389 pto->addrKnown.insert(addr.GetKey());
7390 vAddr.push_back(addr);
7391 // receiver rejects addr messages larger than 1000
7392 if (vAddr.size() >= 1000)
7394 pto->PushMessage("addr", vAddr);
7399 pto->vAddrToSend.clear();
7401 pto->PushMessage("addr", vAddr);
7404 CNodeState &state = *State(pto->GetId());
7405 if (state.fShouldBan) {
7406 if (pto->fWhitelisted)
7407 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
7409 pto->fDisconnect = true;
7410 if (pto->addr.IsLocal())
7411 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
7414 CNode::Ban(pto->addr);
7417 state.fShouldBan = false;
7420 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
7421 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
7422 state.rejects.clear();
7425 if (pindexBestHeader == NULL)
7426 pindexBestHeader = chainActive.Tip();
7427 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.
7428 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
7429 // Only actively request headers from a single peer, unless we're close to today.
7430 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
7431 state.fSyncStarted = true;
7433 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
7434 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->GetHeight(), pto->id, pto->nStartingHeight);
7435 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
7439 // Resend wallet transactions that haven't gotten in a block yet
7440 // Except during reindex, importing and IBD, when old wallet
7441 // transactions become unconfirmed and spams other nodes.
7442 if (!fReindex && !fImporting && !IsInitialBlockDownload())
7444 GetMainSignals().Broadcast(nTimeBestReceived);
7448 // Message: inventory
7451 vector<CInv> vInvWait;
7453 LOCK(pto->cs_inventory);
7454 vInv.reserve(pto->vInventoryToSend.size());
7455 vInvWait.reserve(pto->vInventoryToSend.size());
7456 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
7458 if (pto->setInventoryKnown.count(inv))
7461 // trickle out tx inv to protect privacy
7462 if (inv.type == MSG_TX && !fSendTrickle)
7464 // 1/4 of tx invs blast to all immediately
7465 static uint256 hashSalt;
7466 if (hashSalt.IsNull())
7467 hashSalt = GetRandHash();
7468 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
7469 hashRand = Hash(BEGIN(hashRand), END(hashRand));
7470 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
7474 vInvWait.push_back(inv);
7479 // returns true if wasn't already contained in the set
7480 if (pto->setInventoryKnown.insert(inv).second)
7482 vInv.push_back(inv);
7483 if (vInv.size() >= 1000)
7485 pto->PushMessage("inv", vInv);
7490 pto->vInventoryToSend = vInvWait;
7493 pto->PushMessage("inv", vInv);
7495 // Detect whether we're stalling
7496 int64_t nNow = GetTimeMicros();
7497 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7498 // Stalling only triggers when the block download window cannot move. During normal steady state,
7499 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7500 // should only happen during initial block download.
7501 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
7502 pto->fDisconnect = true;
7504 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
7505 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7506 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7507 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
7508 // to unreasonably increase our timeout.
7509 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7510 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7511 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7512 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7513 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7514 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7515 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
7516 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
7517 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7518 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7519 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7521 if (queuedBlock.nTimeDisconnect < nNow) {
7522 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7523 pto->fDisconnect = true;
7528 // Message: getdata (blocks)
7530 static uint256 zero;
7531 vector<CInv> vGetData;
7532 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
7533 vector<CBlockIndex*> vToDownload;
7534 NodeId staller = -1;
7535 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7536 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7537 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
7538 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
7539 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
7540 pindex->GetHeight(), pto->id);
7542 if (state.nBlocksInFlight == 0 && staller != -1) {
7543 if (State(staller)->nStallingSince == 0) {
7544 State(staller)->nStallingSince = nNow;
7545 LogPrint("net", "Stall started peer=%d\n", staller);
7549 /*CBlockIndex *pindex;
7550 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
7552 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7553 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7554 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7555 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
7556 komodo_requestedcount++;
7557 if ( komodo_requestedcount > 16 )
7559 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7560 komodo_requestedcount = 0;
7565 // Message: getdata (non-blocks)
7567 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
7569 const CInv& inv = (*pto->mapAskFor.begin()).second;
7570 if (!AlreadyHave(inv))
7573 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
7574 vGetData.push_back(inv);
7575 if (vGetData.size() >= 1000)
7577 pto->PushMessage("getdata", vGetData);
7581 //If we're not going to ask, don't expect a response.
7582 pto->setAskFor.erase(inv.hash);
7584 pto->mapAskFor.erase(pto->mapAskFor.begin());
7586 if (!vGetData.empty())
7587 pto->PushMessage("getdata", vGetData);
7593 std::string CBlockFileInfo::ToString() const {
7594 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));
7599 static class CMainCleanup
7605 BlockMap::iterator it1 = mapBlockIndex.begin();
7606 for (; it1 != mapBlockIndex.end(); it1++)
7607 delete (*it1).second;
7608 mapBlockIndex.clear();
7610 // orphan transactions
7611 mapOrphanTransactions.clear();
7612 mapOrphanTransactionsByPrev.clear();
7614 } instance_of_cmaincleanup;
7616 extern "C" const char* getDataDir()
7618 return GetDataDir().string().c_str();
7622 // Set default values of new CMutableTransaction based on consensus rules at given height.
7623 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7625 CMutableTransaction mtx;
7627 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7628 if (isOverwintered) {
7629 mtx.fOverwintered = true;
7630 mtx.nExpiryHeight = nHeight + expiryDelta;
7632 if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) {
7633 mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
7634 mtx.nVersion = SAPLING_TX_VERSION;
7636 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7637 mtx.nVersion = OVERWINTER_TX_VERSION;
7638 mtx.nExpiryHeight = std::min(
7640 static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));