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(): overwinter is not active yet"),
1018 REJECT_INVALID, "tx-overwinter-not-active");
1021 if (saplingActive) {
1022 // Reject transactions with valid version but missing overwintered flag
1023 if (tx.nVersion >= SAPLING_MIN_TX_VERSION && !tx.fOverwintered) {
1024 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwintered flag must be set"),
1025 REJECT_INVALID, "tx-overwintered-flag-not-set");
1028 // Reject transactions with non-Sapling version group ID
1029 if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1030 return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),
1031 REJECT_INVALID, "bad-sapling-tx-version-group-id");
1034 // Reject transactions with invalid version
1035 if (tx.fOverwintered && tx.nVersion < SAPLING_MIN_TX_VERSION ) {
1036 return state.DoS(100, error("CheckTransaction(): Sapling version too low"),
1037 REJECT_INVALID, "bad-tx-sapling-version-too-low");
1040 // Reject transactions with invalid version
1041 if (tx.fOverwintered && tx.nVersion > SAPLING_MAX_TX_VERSION ) {
1042 return state.DoS(100, error("CheckTransaction(): Sapling version too high"),
1043 REJECT_INVALID, "bad-tx-sapling-version-too-high");
1045 } else if (overwinterActive) {
1046 // Reject transactions with valid version but missing overwinter flag
1047 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
1048 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
1049 REJECT_INVALID, "tx-overwinter-flag-not-set");
1052 // Reject transactions with non-Overwinter version group ID
1053 if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1054 return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),
1055 REJECT_INVALID, "bad-overwinter-tx-version-group-id");
1058 // Reject transactions with invalid version
1059 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
1060 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
1061 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
1065 // Rules that apply to Overwinter or later:
1066 if (overwinterActive) {
1067 // Reject transactions intended for Sprout
1068 if (!tx.fOverwintered) {
1069 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
1070 REJECT_INVALID, "tx-overwinter-active");
1073 // Check that all transactions are unexpired
1074 if (IsExpiredTx(tx, nHeight)) {
1075 // Don't increase banscore if the transaction only just expired
1076 int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? dosLevel : 0;
1077 return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
1081 // Rules that apply before Sapling:
1082 if (!saplingActive) {
1084 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1085 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_BEFORE_SAPLING)
1086 return state.DoS(100, error("ContextualCheckTransaction(): size limits failed"),
1087 REJECT_INVALID, "bad-txns-oversize");
1090 uint256 dataToBeSigned;
1093 (!tx.vjoinsplit.empty() ||
1094 !tx.vShieldedSpend.empty() ||
1095 !tx.vShieldedOutput.empty()))
1097 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
1098 // Empty output script.
1101 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1102 } catch (std::logic_error ex) {
1103 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
1104 REJECT_INVALID, "error-computing-signature-hash");
1109 if (!(tx.IsMint() || tx.vjoinsplit.empty()))
1111 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
1113 // We rely on libsodium to check that the signature is canonical.
1114 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1115 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1116 dataToBeSigned.begin(), 32,
1117 tx.joinSplitPubKey.begin()
1119 return state.DoS(isInitBlockDownload() ? 0 : 100,
1120 error("CheckTransaction(): invalid joinsplit signature"),
1121 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1125 if (tx.IsCoinBase())
1127 if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1128 return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1129 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
1132 if (!tx.vShieldedSpend.empty() ||
1133 !tx.vShieldedOutput.empty())
1135 auto ctx = librustzcash_sapling_verification_ctx_init();
1137 for (const SpendDescription &spend : tx.vShieldedSpend) {
1138 if (!librustzcash_sapling_check_spend(
1141 spend.anchor.begin(),
1142 spend.nullifier.begin(),
1144 spend.zkproof.begin(),
1145 spend.spendAuthSig.begin(),
1146 dataToBeSigned.begin()
1149 librustzcash_sapling_verification_ctx_free(ctx);
1150 return state.DoS(100, error("ContextualCheckTransaction(): Sapling spend description invalid"),
1151 REJECT_INVALID, "bad-txns-sapling-spend-description-invalid");
1155 for (const OutputDescription &output : tx.vShieldedOutput) {
1156 if (!librustzcash_sapling_check_output(
1160 output.ephemeralKey.begin(),
1161 output.zkproof.begin()
1164 librustzcash_sapling_verification_ctx_free(ctx);
1165 return state.DoS(100, error("ContextualCheckTransaction(): Sapling output description invalid"),
1166 REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
1170 if (!librustzcash_sapling_final_check(
1173 tx.bindingSig.begin(),
1174 dataToBeSigned.begin()
1177 librustzcash_sapling_verification_ctx_free(ctx);
1178 return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
1179 REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
1182 librustzcash_sapling_verification_ctx_free(ctx);
1187 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1188 libzcash::ProofVerifier& verifier)
1190 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1191 if ( *(int32_t *)&array[0] == 0 )
1192 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1196 for (k=0; k<numbanned; k++)
1198 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1200 static uint32_t counter;
1201 if ( counter++ < 100 )
1202 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->GetHeight(),j);
1207 // Don't count coinbase transactions because mining skews the count
1208 if (!tx.IsCoinBase()) {
1209 transactionsValidated.increment();
1212 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1215 // Ensure that zk-SNARKs v|| y
1216 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1217 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1218 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1219 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1226 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1228 // Basic checks that don't depend on any context
1232 * 1. The consensus rule below was:
1233 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1234 * which checked if tx.nVersion fell within the range:
1235 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1236 * 2. The parser allowed tx.nVersion to be negative
1239 * 1. The consensus rule checks to see if tx.Version falls within the range:
1240 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1241 * 2. The previous consensus rule checked for negative values within the range:
1242 * INT32_MIN <= tx.nVersion < 0
1243 * This is unnecessary for Overwinter transactions since the parser now
1244 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1245 * and when Overwinter is not active ContextualCheckTransaction rejects
1246 * transactions with fOverwintered set. When fOverwintered is set,
1247 * this function and ContextualCheckTransaction will together check to
1248 * ensure tx.nVersion avoids the following ranges:
1249 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1250 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1252 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1253 return state.DoS(100, error("CheckTransaction(): version too low"),
1254 REJECT_INVALID, "bad-txns-version-too-low");
1256 else if (tx.fOverwintered) {
1257 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1258 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1259 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1261 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID &&
1262 tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1263 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1264 REJECT_INVALID, "bad-tx-version-group-id");
1266 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1267 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1268 REJECT_INVALID, "bad-tx-expiry-height-too-high");
1272 // Transactions containing empty `vin` must have either non-empty
1273 // `vjoinsplit` or non-empty `vShieldedSpend`.
1274 if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
1275 return state.DoS(10, error("CheckTransaction(): vin empty"),
1276 REJECT_INVALID, "bad-txns-vin-empty");
1277 // Transactions containing empty `vout` must have either non-empty
1278 // `vjoinsplit` or non-empty `vShieldedOutput`.
1279 if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
1280 return state.DoS(10, error("CheckTransaction(): vout empty"),
1281 REJECT_INVALID, "bad-txns-vout-empty");
1284 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE >= MAX_TX_SIZE_AFTER_SAPLING); // sanity
1285 BOOST_STATIC_ASSERT(MAX_TX_SIZE_AFTER_SAPLING > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1286 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_AFTER_SAPLING)
1287 return state.DoS(100, error("CheckTransaction(): size limits failed"),
1288 REJECT_INVALID, "bad-txns-oversize");
1290 // Check for negative or overflow output values
1291 CAmount nValueOut = 0;
1292 int32_t iscoinbase = tx.IsCoinBase();
1293 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1295 if (txout.nValue < 0)
1296 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1297 REJECT_INVALID, "bad-txns-vout-negative");
1298 if (txout.nValue > MAX_MONEY)
1300 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1301 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1303 if ( ASSETCHAINS_PRIVATE != 0 )
1305 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
1306 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetValueOut() > 0 )
1307 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
1309 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
1310 return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative");
1311 nValueOut += txout.nValue;
1312 if (!MoneyRange(nValueOut))
1313 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1314 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1317 // Check for non-zero valueBalance when there are no Sapling inputs or outputs
1318 if (tx.vShieldedSpend.empty() && tx.vShieldedOutput.empty() && tx.valueBalance != 0) {
1319 return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"),
1320 REJECT_INVALID, "bad-txns-valuebalance-nonzero");
1323 // Check for overflow valueBalance
1324 if (tx.valueBalance > MAX_MONEY || tx.valueBalance < -MAX_MONEY) {
1325 return state.DoS(100, error("CheckTransaction(): abs(tx.valueBalance) too large"),
1326 REJECT_INVALID, "bad-txns-valuebalance-toolarge");
1329 if (tx.valueBalance <= 0) {
1330 // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
1331 nValueOut += -tx.valueBalance;
1333 if (!MoneyRange(nValueOut)) {
1334 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1335 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1339 // Ensure that joinsplit values are well-formed
1340 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1342 if ( ASSETCHAINS_PUBLIC != 0 )
1344 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1345 REJECT_INVALID, "bad-txns-acprivacy-chain");
1347 if (joinsplit.vpub_old < 0) {
1348 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1349 REJECT_INVALID, "bad-txns-vpub_old-negative");
1352 if (joinsplit.vpub_new < 0) {
1353 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1354 REJECT_INVALID, "bad-txns-vpub_new-negative");
1357 if (joinsplit.vpub_old > MAX_MONEY) {
1358 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1359 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1362 if (joinsplit.vpub_new > MAX_MONEY) {
1363 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1364 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1367 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1368 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1369 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1372 nValueOut += joinsplit.vpub_old;
1373 if (!MoneyRange(nValueOut)) {
1374 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1375 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1379 // Ensure input values do not exceed MAX_MONEY
1380 // We have not resolved the txin values at this stage,
1381 // but we do know what the joinsplits claim to add
1382 // to the value pool.
1384 CAmount nValueIn = 0;
1385 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1387 nValueIn += it->vpub_new;
1389 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1390 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1391 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1395 // Also check for Sapling
1396 if (tx.valueBalance >= 0) {
1397 // NB: positive valueBalance "adds" money to the transparent value pool, just as inputs do
1398 nValueIn += tx.valueBalance;
1400 if (!MoneyRange(nValueIn)) {
1401 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1402 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1407 // Check for duplicate inputs
1408 set<COutPoint> vInOutPoints;
1409 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1411 if (vInOutPoints.count(txin.prevout))
1412 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1413 REJECT_INVALID, "bad-txns-inputs-duplicate");
1414 vInOutPoints.insert(txin.prevout);
1417 // Check for duplicate joinsplit nullifiers in this transaction
1419 set<uint256> vJoinSplitNullifiers;
1420 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1422 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1424 if (vJoinSplitNullifiers.count(nf))
1425 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1426 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1428 vJoinSplitNullifiers.insert(nf);
1433 // Check for duplicate sapling nullifiers in this transaction
1435 set<uint256> vSaplingNullifiers;
1436 BOOST_FOREACH(const SpendDescription& spend_desc, tx.vShieldedSpend)
1438 if (vSaplingNullifiers.count(spend_desc.nullifier))
1439 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1440 REJECT_INVALID, "bad-spend-description-nullifiers-duplicate");
1442 vSaplingNullifiers.insert(spend_desc.nullifier);
1448 // There should be no joinsplits in a coinbase transaction
1449 if (tx.vjoinsplit.size() > 0)
1450 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1451 REJECT_INVALID, "bad-cb-has-joinsplits");
1453 // A coinbase transaction cannot have spend descriptions or output descriptions
1454 if (tx.vShieldedSpend.size() > 0)
1455 return state.DoS(100, error("CheckTransaction(): coinbase has spend descriptions"),
1456 REJECT_INVALID, "bad-cb-has-spend-description");
1457 if (tx.vShieldedOutput.size() > 0)
1458 return state.DoS(100, error("CheckTransaction(): coinbase has output descriptions"),
1459 REJECT_INVALID, "bad-cb-has-output-description");
1461 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1462 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1463 REJECT_INVALID, "bad-cb-length");
1467 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1468 if (txin.prevout.IsNull())
1469 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1470 REJECT_INVALID, "bad-txns-prevout-null");
1476 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1478 extern int32_t KOMODO_ON_DEMAND;
1481 uint256 hash = tx.GetHash();
1482 double dPriorityDelta = 0;
1483 CAmount nFeeDelta = 0;
1484 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1485 if (dPriorityDelta > 0 || nFeeDelta > 0)
1489 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1493 // There is a free transaction area in blocks created by most miners,
1494 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1495 // to be considered to fall into this category. We don't want to encourage sending
1496 // multiple transactions instead of one big transaction to avoid fees.
1497 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1501 if (!MoneyRange(nMinFee))
1502 nMinFee = MAX_MONEY;
1507 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
1509 AssertLockHeld(cs_main);
1510 if (pfMissingInputs)
1511 *pfMissingInputs = false;
1513 int flag=0,nextBlockHeight = chainActive.Height() + 1;
1514 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1516 // Node operator can choose to reject tx by number of transparent inputs
1517 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1518 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1519 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
1523 size_t n = tx.vin.size();
1525 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1530 auto verifier = libzcash::ProofVerifier::Strict();
1531 if ( komodo_validate_interest(tx,chainActive.LastTip()->GetHeight()+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
1533 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1534 return error("AcceptToMemoryPool: komodo_validate_interest failed");
1536 if (!CheckTransaction(tx, state, verifier))
1538 return error("AcceptToMemoryPool: CheckTransaction failed");
1540 // DoS level set to 10 to be more forgiving.
1541 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1542 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10))
1544 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1547 // Coinbase is only valid in a block, not as a loose transaction
1548 if (tx.IsCoinBase())
1550 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1551 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1553 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1555 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1557 //fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
1558 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1560 // Only accept nLockTime-using transactions that can be mined in the next
1561 // block; we don't want our mempool filled up with transactions that can't
1563 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1565 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1566 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1568 // is it already in the memory pool?
1569 uint256 hash = tx.GetHash();
1570 if (pool.exists(hash))
1572 //fprintf(stderr,"already in mempool\n");
1573 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
1576 // Check for conflicts with in-memory transactions
1578 LOCK(pool.cs); // protect pool.mapNextTx
1579 for (unsigned int i = 0; i < tx.vin.size(); i++)
1581 COutPoint outpoint = tx.vin[i].prevout;
1582 if (pool.mapNextTx.count(outpoint))
1584 // Disable replacement feature for now
1588 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1589 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
1590 if (pool.nullifierExists(nf, SPROUT)) {
1591 fprintf(stderr,"pool.mapNullifiers.count\n");
1596 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
1597 if (pool.nullifierExists(spendDescription.nullifier, SAPLING)) {
1605 CCoinsViewCache view(&dummy);
1607 CAmount nValueIn = 0;
1610 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1611 view.SetBackend(viewMemPool);
1613 // do we already have it?
1614 if (view.HaveCoins(hash))
1616 //fprintf(stderr,"view.HaveCoins(hash) error\n");
1617 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
1620 if (tx.IsCoinImport())
1622 // Inverse of normal case; if input exists, it's been spent
1623 if (ExistsImportTombstone(tx, view))
1624 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
1628 // do all inputs exist?
1629 // Note that this does not check for the presence of actual outputs (see the next check for that),
1630 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1631 BOOST_FOREACH(const CTxIn txin, tx.vin)
1633 if (!view.HaveCoins(txin.prevout.hash))
1635 if (pfMissingInputs)
1636 *pfMissingInputs = true;
1637 //fprintf(stderr,"missing inputs\n");
1642 // are the actual inputs available?
1643 if (!view.HaveInputs(tx))
1645 //fprintf(stderr,"accept failure.1\n");
1646 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1649 // are the joinsplit's requirements met?
1650 if (!view.HaveJoinSplitRequirements(tx))
1652 //fprintf(stderr,"accept failure.2\n");
1653 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1656 // Bring the best block into scope
1657 view.GetBestBlock();
1659 nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
1660 if ( 0 && interest != 0 )
1661 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1662 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1663 view.SetBackend(dummy);
1666 // Check for non-standard pay-to-script-hash in inputs
1667 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1668 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1670 // Check that the transaction doesn't have an excessive number of
1671 // sigops, making it impossible to mine. Since the coinbase transaction
1672 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1673 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1674 // merely non-standard transaction.
1675 unsigned int nSigOps = GetLegacySigOpCount(tx);
1676 nSigOps += GetP2SHSigOpCount(tx, view);
1677 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1679 fprintf(stderr,"accept failure.4\n");
1680 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");
1683 CAmount nValueOut = tx.GetValueOut();
1684 CAmount nFees = nValueIn-nValueOut;
1685 double dPriority = view.GetPriority(tx, chainActive.Height());
1687 // Keep track of transactions that spend a coinbase, which we re-scan
1688 // during reorgs to ensure COINBASE_MATURITY is still met.
1689 bool fSpendsCoinbase = false;
1690 if (!tx.IsCoinImport()) {
1691 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1692 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1693 if (coins->IsCoinBase()) {
1694 fSpendsCoinbase = true;
1700 // Grab the branch ID we expect this transaction to commit to. We don't
1701 // yet know if it does, but if the entry gets added to the mempool, then
1702 // it has passed ContextualCheckInputs and therefore this is correct.
1703 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1705 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1706 unsigned int nSize = entry.GetTxSize();
1708 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1709 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1710 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1712 // Don't accept it if it can't get into a block
1713 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1714 if (fLimitFree && nFees < txMinFee)
1716 //fprintf(stderr,"accept failure.5\n");
1717 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1721 // Require that free transactions have sufficient priority to be mined in the next block.
1722 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1723 fprintf(stderr,"accept failure.6\n");
1724 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1727 // Continuously rate-limit free (really, very-low-fee) transactions
1728 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1729 // be annoying or make others' transactions take longer to confirm.
1730 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1732 static CCriticalSection csFreeLimiter;
1733 static double dFreeCount;
1734 static int64_t nLastTime;
1735 int64_t nNow = GetTime();
1737 LOCK(csFreeLimiter);
1739 // Use an exponentially decaying ~10-minute window:
1740 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1742 // -limitfreerelay unit is thousand-bytes-per-minute
1743 // At default rate it would take over a month to fill 1GB
1744 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1746 fprintf(stderr,"accept failure.7\n");
1747 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1749 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1750 dFreeCount += nSize;
1753 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
1755 string errmsg = strprintf("absurdly high fees %s, %d > %d",
1757 nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1758 LogPrint("mempool", errmsg.c_str());
1759 return state.Error("AcceptToMemoryPool: " + errmsg);
1762 // Check against previous transactions
1763 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1764 PrecomputedTransactionData txdata(tx);
1765 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1767 //fprintf(stderr,"accept failure.9\n");
1768 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1771 // Check again against just the consensus-critical mandatory script
1772 // verification flags, in case of bugs in the standard flags that cause
1773 // transactions to pass as valid when they're actually invalid. For
1774 // instance the STRICTENC flag was incorrectly allowing certain
1775 // CHECKSIG NOT scripts to pass, even though they were invalid.
1777 // There is a similar check in CreateNewBlock() to prevent creating
1778 // invalid blocks, however allowing such transactions into the mempool
1779 // can be exploited as a DoS attack.
1780 // XXX: is this neccesary for CryptoConditions?
1781 if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 )
1784 KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
1786 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1789 KOMODO_CONNECTING = -1;
1790 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1793 KOMODO_CONNECTING = -1;
1795 // Store transaction in memory
1796 if ( komodo_is_notarytx(tx) == 0 )
1798 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1800 if (!tx.IsCoinImport())
1802 // Add memory address index
1803 if (fAddressIndex) {
1804 pool.addAddressIndex(entry, view);
1807 // Add memory spent index
1809 pool.addSpentIndex(entry, view);
1814 SyncWithWallets(tx, NULL);
1819 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1821 if (!fTimestampIndex)
1822 return error("Timestamp index not enabled");
1824 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1825 return error("Unable to get hashes for timestamps");
1830 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1835 if (mempool.getSpentIndex(key, value))
1838 if (!pblocktree->ReadSpentIndex(key, value))
1844 bool GetAddressIndex(uint160 addressHash, int type,
1845 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1848 return error("address index not enabled");
1850 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1851 return error("unable to get txids for address");
1856 bool GetAddressUnspent(uint160 addressHash, int type,
1857 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1860 return error("address index not enabled");
1862 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1863 return error("unable to get txids for address");
1868 /*uint64_t myGettxout(uint256 hash,int32_t n)
1871 LOCK2(cs_main,mempool.cs);
1872 CCoinsViewMemPool view(pcoinsTip, mempool);
1873 if (!view.GetCoins(hash, coins))
1875 if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
1877 else return(coins.vout[n].nValue);
1880 bool myAddtomempool(CTransaction &tx)
1882 CValidationState state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
1883 if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
1884 return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
1888 bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1890 // need a GetTransaction without lock so the validation code for assets can run without deadlock
1892 //fprintf(stderr,"check mempool\n");
1893 if (mempool.lookup(hash, txOut))
1895 //fprintf(stderr,"found in mempool\n");
1899 //fprintf(stderr,"check disk\n");
1903 //fprintf(stderr,"ReadTxIndex\n");
1904 if (pblocktree->ReadTxIndex(hash, postx)) {
1905 //fprintf(stderr,"OpenBlockFile\n");
1906 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1908 return error("%s: OpenBlockFile failed", __func__);
1909 CBlockHeader header;
1910 //fprintf(stderr,"seek and read\n");
1913 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1915 } catch (const std::exception& e) {
1916 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1918 hashBlock = header.GetHash();
1919 if (txOut.GetHash() != hash)
1920 return error("%s: txid mismatch", __func__);
1921 //fprintf(stderr,"found on disk\n");
1925 //fprintf(stderr,"not found\n");
1929 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1930 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1932 CBlockIndex *pindexSlow = NULL;
1936 if (mempool.lookup(hash, txOut))
1943 if (pblocktree->ReadTxIndex(hash, postx)) {
1944 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1946 return error("%s: OpenBlockFile failed", __func__);
1947 CBlockHeader header;
1950 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1952 } catch (const std::exception& e) {
1953 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1955 hashBlock = header.GetHash();
1956 if (txOut.GetHash() != hash)
1957 return error("%s: txid mismatch", __func__);
1962 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1965 CCoinsViewCache &view = *pcoinsTip;
1966 const CCoins* coins = view.AccessCoins(hash);
1968 nHeight = coins->nHeight;
1971 pindexSlow = chainActive[nHeight];
1976 if (ReadBlockFromDisk(block, pindexSlow,1)) {
1977 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1978 if (tx.GetHash() == hash) {
1980 hashBlock = pindexSlow->GetBlockHash();
1990 /*char *komodo_getspendscript(uint256 hash,int32_t n)
1992 CTransaction tx; uint256 hashBlock;
1993 if ( !GetTransaction(hash,tx,hashBlock,true) )
1995 printf("null GetTransaction\n");
1998 if ( n >= 0 && n < tx.vout.size() )
1999 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
2000 else printf("getspendscript illegal n.%d\n",n);
2005 //////////////////////////////////////////////////////////////////////////////
2007 // CBlock and CBlockIndex
2010 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
2012 // Open history file to append
2013 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
2014 if (fileout.IsNull())
2015 return error("WriteBlockToDisk: OpenBlockFile failed");
2017 // Write index header
2018 unsigned int nSize = GetSerializeSize(fileout, block);
2019 fileout << FLATDATA(messageStart) << nSize;
2022 long fileOutPos = ftell(fileout.Get());
2024 return error("WriteBlockToDisk: ftell failed");
2025 pos.nPos = (unsigned int)fileOutPos;
2031 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
2033 uint8_t pubkey33[33];
2036 // Open history file to read
2037 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
2038 if (filein.IsNull())
2040 //fprintf(stderr,"readblockfromdisk err A\n");
2041 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
2048 catch (const std::exception& e) {
2049 fprintf(stderr,"readblockfromdisk err B\n");
2050 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
2053 if ( 0 && checkPOW != 0 )
2055 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
2056 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
2058 int32_t i; for (i=0; i<33; i++)
2059 fprintf(stderr,"%02x",pubkey33[i]);
2060 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
2062 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
2068 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
2072 if (!ReadBlockFromDisk(pindex->GetHeight(),block, pindex->GetBlockPos(),checkPOW))
2074 if (block.GetHash() != pindex->GetBlockHash())
2075 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
2076 pindex->ToString(), pindex->GetBlockPos().ToString());
2080 //uint64_t komodo_moneysupply(int32_t height);
2081 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
2082 extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
2083 extern uint32_t ASSETCHAINS_MAGIC;
2084 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
2085 extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
2087 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
2089 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
2090 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2093 return(100000000 * COIN); // ICO allocation
2094 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
2100 return(komodo_ac_block_subsidy(nHeight));
2103 // Mining slow start
2104 // The subsidy is ramped up linearly, skipping the middle payout of
2105 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
2106 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
2107 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2108 nSubsidy *= nHeight;
2110 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
2111 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2112 nSubsidy *= (nHeight+1);
2116 assert(nHeight > consensusParams.SubsidySlowStartShift());
2117 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
2118 // Force block reward to zero when right shift is undefined.
2119 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
2120 //if (halvings >= 64)
2123 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
2124 //nSubsidy >>= halvings;
2128 bool IsInitialBlockDownload()
2130 const CChainParams& chainParams = Params();
2132 // Once this function has returned false, it must remain false.
2133 static std::atomic<bool> latchToFalse{false};
2134 // Optimization: pre-test latch before taking the lock.
2135 if (latchToFalse.load(std::memory_order_relaxed))
2139 if (latchToFalse.load(std::memory_order_relaxed))
2142 if (fImporting || fReindex)
2144 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2148 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2150 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload - %d blocks\n", Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2155 arith_uint256 bigZero = arith_uint256();
2156 arith_uint256 minWork = UintToArith256(chainParams.GetConsensus().nMinimumChainWork);
2157 CBlockIndex *ptr = chainActive.Tip();
2161 if (ptr->chainPower < CChainPower(ptr, bigZero, minWork))
2164 state = ((chainActive.Height() < ptr->GetHeight() - 24*60) ||
2165 ptr->GetBlockTime() < (GetTime() - nMaxTipAge));
2167 //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()));
2170 LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
2171 latchToFalse.store(true, std::memory_order_relaxed);
2176 // determine if we are in sync with the best chain
2179 const CChainParams& chainParams = Params();
2182 if (fImporting || fReindex)
2184 //fprintf(stderr,"IsInSync: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2187 if (fCheckpointsEnabled)
2189 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2191 //fprintf(stderr,"IsInSync: checkpoint -> initialdownload chainActive.Height().%d GetTotalBlocksEstimate(chainParams.Checkpoints().%d\n", chainActive.Height(), Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2196 CBlockIndex *pbi = chainActive.Tip();
2197 int longestchain = komodo_longestchain();
2199 (pindexBestHeader == 0) ||
2200 ((pindexBestHeader->GetHeight() - 1) > pbi->GetHeight()) ||
2201 (longestchain != 0 && longestchain > pbi->GetHeight()) )
2207 static bool fLargeWorkForkFound = false;
2208 static bool fLargeWorkInvalidChainFound = false;
2209 static CBlockIndex *pindexBestForkTip = NULL;
2210 static CBlockIndex *pindexBestForkBase = NULL;
2212 void CheckForkWarningConditions()
2214 AssertLockHeld(cs_main);
2215 // Before we get past initial download, we cannot reliably alert about forks
2216 // (we assume we don't get stuck on a fork before finishing our initial sync)
2217 if (IsInitialBlockDownload())
2220 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
2221 // of our head, drop it
2222 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->GetHeight() >= 288)
2223 pindexBestForkTip = NULL;
2225 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->chainPower > (chainActive.LastTip()->chainPower + (GetBlockProof(*chainActive.LastTip()) * 6))))
2227 if (!fLargeWorkForkFound && pindexBestForkBase)
2229 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
2230 pindexBestForkBase->phashBlock->ToString() + std::string("'");
2231 CAlert::Notify(warning, true);
2233 if (pindexBestForkTip && pindexBestForkBase)
2235 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__,
2236 pindexBestForkBase->GetHeight(), pindexBestForkBase->phashBlock->ToString(),
2237 pindexBestForkTip->GetHeight(), pindexBestForkTip->phashBlock->ToString());
2238 fLargeWorkForkFound = true;
2242 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
2243 LogPrintf("%s: %s\n", warning.c_str(), __func__);
2244 CAlert::Notify(warning, true);
2245 fLargeWorkInvalidChainFound = true;
2250 fLargeWorkForkFound = false;
2251 fLargeWorkInvalidChainFound = false;
2255 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
2257 AssertLockHeld(cs_main);
2258 // If we are on a fork that is sufficiently large, set a warning flag
2259 CBlockIndex* pfork = pindexNewForkTip;
2260 CBlockIndex* plonger = chainActive.LastTip();
2261 while (pfork && pfork != plonger)
2263 while (plonger && plonger->GetHeight() > pfork->GetHeight())
2264 plonger = plonger->pprev;
2265 if (pfork == plonger)
2267 pfork = pfork->pprev;
2270 // We define a condition where we should warn the user about as a fork of at least 7 blocks
2271 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
2272 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
2273 // hash rate operating on the fork.
2274 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
2275 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
2276 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
2277 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->GetHeight() > pindexBestForkTip->GetHeight())) &&
2278 pindexNewForkTip->chainPower - pfork->chainPower > (GetBlockProof(*pfork) * 7) &&
2279 chainActive.Height() - pindexNewForkTip->GetHeight() < 72)
2281 pindexBestForkTip = pindexNewForkTip;
2282 pindexBestForkBase = pfork;
2285 CheckForkWarningConditions();
2288 // Requires cs_main.
2289 void Misbehaving(NodeId pnode, int howmuch)
2294 CNodeState *state = State(pnode);
2298 state->nMisbehavior += howmuch;
2299 int banscore = GetArg("-banscore", 101);
2300 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
2302 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2303 state->fShouldBan = true;
2305 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2308 void static InvalidChainFound(CBlockIndex* pindexNew)
2310 if (!pindexBestInvalid || pindexNew->chainPower > pindexBestInvalid->chainPower)
2311 pindexBestInvalid = pindexNew;
2313 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2314 pindexNew->GetBlockHash().ToString(), pindexNew->GetHeight(),
2315 log(pindexNew->chainPower.chainWork.getdouble())/log(2.0),
2316 log(pindexNew->chainPower.chainStake.getdouble())/log(2.0),
2317 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()));
2318 CBlockIndex *tip = chainActive.LastTip();
2320 LogPrintf("%s: current best=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2321 tip->GetBlockHash().ToString(), chainActive.Height(),
2322 log(tip->chainPower.chainWork.getdouble())/log(2.0),
2323 log(tip->chainPower.chainStake.getdouble())/log(2.0),
2324 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
2325 CheckForkWarningConditions();
2328 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2330 if (state.IsInvalid(nDoS)) {
2331 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2332 if (it != mapBlockSource.end() && State(it->second)) {
2333 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
2334 State(it->second)->rejects.push_back(reject);
2336 Misbehaving(it->second, nDoS);
2339 if (!state.CorruptionPossible()) {
2340 pindex->nStatus |= BLOCK_FAILED_VALID;
2341 setDirtyBlockIndex.insert(pindex);
2342 setBlockIndexCandidates.erase(pindex);
2343 InvalidChainFound(pindex);
2347 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
2349 if (!tx.IsMint()) // mark inputs spent
2351 txundo.vprevout.reserve(tx.vin.size());
2352 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
2353 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2354 unsigned nPos = txin.prevout.n;
2356 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2358 // mark an outpoint spent, and construct undo information
2359 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2361 if (coins->vout.size() == 0) {
2362 CTxInUndo& undo = txundo.vprevout.back();
2363 undo.nHeight = coins->nHeight;
2364 undo.fCoinBase = coins->fCoinBase;
2365 undo.nVersion = coins->nVersion;
2371 inputs.SetNullifiers(tx, true);
2373 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2376 if (tx.IsCoinImport()) {
2377 // add a tombstone for the burnTx
2378 AddImportTombstone(tx, inputs, nHeight);
2382 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2385 UpdateCoins(tx, inputs, txundo, nHeight);
2388 bool CScriptCheck::operator()() {
2389 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2390 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2391 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
2392 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2397 int GetSpendHeight(const CCoinsViewCache& inputs)
2400 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2401 return pindexPrev->GetHeight() + 1;
2404 namespace Consensus {
2405 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2407 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2408 // for an attacker to attempt to split the network.
2409 if (!inputs.HaveInputs(tx))
2410 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2412 // are the JoinSplit's requirements met?
2413 if (!inputs.HaveJoinSplitRequirements(tx))
2414 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2416 CAmount nValueIn = 0;
2418 for (unsigned int i = 0; i < tx.vin.size(); i++)
2420 const COutPoint &prevout = tx.vin[i].prevout;
2421 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2424 if (coins->IsCoinBase()) {
2425 // Ensure that coinbases are matured
2426 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2427 return state.Invalid(
2428 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2429 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2432 // ensure that output of coinbases are not still time locked
2433 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2434 if (nSpendHeight < unlockTime && coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE) {
2435 return state.Invalid(
2436 error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2437 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2440 // Ensure that coinbases cannot be spent to transparent outputs
2441 // Disabled on regtest
2442 if (fCoinbaseEnforcedProtectionEnabled &&
2443 consensusParams.fCoinbaseMustBeProtected &&
2445 (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
2446 return state.Invalid(
2447 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2448 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2452 // Check for negative or overflow input values
2453 nValueIn += coins->vout[prevout.n].nValue;
2454 #ifdef KOMODO_ENABLE_INTEREST
2455 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() >= 60000 )
2457 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2459 int64_t interest; int32_t txheight; uint32_t locktime;
2460 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2462 //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);
2463 nValueIn += interest;
2468 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2469 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2470 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2474 nValueIn += tx.GetShieldedValueIn();
2475 if (!MoneyRange(nValueIn))
2476 return state.DoS(100, error("CheckInputs(): shielded input to transparent value pool out of range"),
2477 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2479 if (nValueIn < tx.GetValueOut())
2481 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2482 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2483 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2485 // Tally transaction fees
2486 CAmount nTxFee = nValueIn - tx.GetValueOut();
2488 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2489 REJECT_INVALID, "bad-txns-fee-negative");
2491 if (!MoneyRange(nFees))
2492 return state.DoS(100, error("CheckInputs(): nFees out of range"),
2493 REJECT_INVALID, "bad-txns-fee-outofrange");
2496 }// namespace Consensus
2498 bool ContextualCheckInputs(
2499 const CTransaction& tx,
2500 CValidationState &state,
2501 const CCoinsViewCache &inputs,
2505 PrecomputedTransactionData& txdata,
2506 const Consensus::Params& consensusParams,
2507 uint32_t consensusBranchId,
2508 std::vector<CScriptCheck> *pvChecks)
2512 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2517 pvChecks->reserve(tx.vin.size());
2519 // The first loop above does all the inexpensive checks.
2520 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2521 // Helps prevent CPU exhaustion attacks.
2523 // Skip ECDSA signature verification when connecting blocks
2524 // before the last block chain checkpoint. This is safe because block merkle hashes are
2525 // still computed and checked, and any change will be caught at the next checkpoint.
2526 if (fScriptChecks) {
2527 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2528 const COutPoint &prevout = tx.vin[i].prevout;
2529 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2533 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2535 pvChecks->push_back(CScriptCheck());
2536 check.swap(pvChecks->back());
2537 } else if (!check()) {
2538 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2539 // Check whether the failure was caused by a
2540 // non-mandatory script verification check, such as
2541 // non-standard DER encodings or non-null dummy
2542 // arguments; if so, don't trigger DoS protection to
2543 // avoid splitting the network between upgraded and
2544 // non-upgraded nodes.
2545 CScriptCheck check2(*coins, tx, i,
2546 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2548 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2550 // Failures of other flags indicate a transaction that is
2551 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2552 // such nodes as they are not following the protocol. That
2553 // said during an upgrade careful thought should be taken
2554 // as to the correct behavior - we may want to continue
2555 // peering with non-upgraded nodes even after a soft-fork
2556 // super-majority vote has passed.
2557 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2563 if (tx.IsCoinImport())
2565 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2566 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2573 /*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)
2575 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2576 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2580 if (!tx.IsCoinBase())
2582 // While checking, GetBestBlock() refers to the parent block.
2583 // This is also true for mempool checks.
2584 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2585 int nSpendHeight = pindexPrev->GetHeight() + 1;
2586 for (unsigned int i = 0; i < tx.vin.size(); i++)
2588 const COutPoint &prevout = tx.vin[i].prevout;
2589 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2590 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2594 // If prev is coinbase, check that it's matured
2595 if (coins->IsCoinBase()) {
2596 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2597 COINBASE_MATURITY = _COINBASE_MATURITY;
2598 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2599 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2601 return state.Invalid(
2602 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2613 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2615 // Open history file to append
2616 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2617 if (fileout.IsNull())
2618 return error("%s: OpenUndoFile failed", __func__);
2620 // Write index header
2621 unsigned int nSize = GetSerializeSize(fileout, blockundo);
2622 fileout << FLATDATA(messageStart) << nSize;
2625 long fileOutPos = ftell(fileout.Get());
2627 return error("%s: ftell failed", __func__);
2628 pos.nPos = (unsigned int)fileOutPos;
2629 fileout << blockundo;
2631 // calculate & write checksum
2632 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2633 hasher << hashBlock;
2634 hasher << blockundo;
2635 fileout << hasher.GetHash();
2640 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2642 // Open history file to read
2643 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2644 if (filein.IsNull())
2645 return error("%s: OpenBlockFile failed", __func__);
2648 uint256 hashChecksum;
2650 filein >> blockundo;
2651 filein >> hashChecksum;
2653 catch (const std::exception& e) {
2654 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2657 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2658 hasher << hashBlock;
2659 hasher << blockundo;
2660 if (hashChecksum != hasher.GetHash())
2661 return error("%s: Checksum mismatch", __func__);
2666 /** Abort with a message */
2667 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2669 strMiscWarning = strMessage;
2670 LogPrintf("*** %s\n", strMessage);
2671 uiInterface.ThreadSafeMessageBox(
2672 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2673 "", CClientUIInterface::MSG_ERROR);
2678 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2680 AbortNode(strMessage, userMessage);
2681 return state.Error(strMessage);
2687 * Apply the undo operation of a CTxInUndo to the given chain state.
2688 * @param undo The undo object.
2689 * @param view The coins view to which to apply the changes.
2690 * @param out The out point that corresponds to the tx input.
2691 * @return True on success.
2693 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2697 CCoinsModifier coins = view.ModifyCoins(out.hash);
2698 if (undo.nHeight != 0) {
2699 // undo data contains height: this is the last output of the prevout tx being spent
2700 if (!coins->IsPruned())
2701 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2703 coins->fCoinBase = undo.fCoinBase;
2704 coins->nHeight = undo.nHeight;
2705 coins->nVersion = undo.nVersion;
2707 if (coins->IsPruned())
2708 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2710 if (coins->IsAvailable(out.n))
2711 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2712 if (coins->vout.size() < out.n+1)
2713 coins->vout.resize(out.n+1);
2714 coins->vout[out.n] = undo.txout;
2720 void ConnectNotarisations(const CBlock &block, int height)
2722 // Record Notarisations
2723 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2724 if (notarisations.size() > 0) {
2725 CDBBatch batch = CDBBatch(*pnotarisations);
2726 batch.Write(block.GetHash(), notarisations);
2727 WriteBackNotarisations(notarisations, batch);
2728 pnotarisations->WriteBatch(batch, true);
2729 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2730 notarisations.size(), block.GetHash().GetHex().data());
2735 void DisconnectNotarisations(const CBlock &block)
2737 // Delete from notarisations cache
2738 NotarisationsInBlock nibs;
2739 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2740 CDBBatch batch = CDBBatch(*pnotarisations);
2741 batch.Erase(block.GetHash());
2742 EraseBackNotarisations(nibs, batch);
2743 pnotarisations->WriteBatch(batch, true);
2744 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2745 nibs.size(), block.GetHash().GetHex().data());
2750 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2752 assert(pindex->GetBlockHash() == view.GetBestBlock());
2758 komodo_disconnect(pindex,block);
2759 CBlockUndo blockUndo;
2760 CDiskBlockPos pos = pindex->GetUndoPos();
2762 return error("DisconnectBlock(): no undo data available");
2763 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2764 return error("DisconnectBlock(): failure reading undo data");
2766 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2767 return error("DisconnectBlock(): block and undo data inconsistent");
2768 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2769 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2770 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2772 // undo transactions in reverse order
2773 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2774 const CTransaction &tx = block.vtx[i];
2775 uint256 hash = tx.GetHash();
2776 if (fAddressIndex) {
2778 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2779 const CTxOut &out = tx.vout[k];
2781 if (out.scriptPubKey.IsPayToScriptHash()) {
2782 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2784 // undo receiving activity
2785 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2787 // undo unspent index
2788 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2791 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2792 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2794 // undo receiving activity
2795 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2797 // undo unspent index
2798 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2801 else if (out.scriptPubKey.IsPayToPublicKey()) {
2802 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2804 // undo receiving activity
2805 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2807 // undo unspent index
2808 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2811 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2812 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2814 // undo receiving activity
2815 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2817 // undo unspent index
2818 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2829 // Check that all outputs are available and match the outputs in the block itself
2832 CCoinsModifier outs = view.ModifyCoins(hash);
2833 outs->ClearUnspendable();
2835 CCoins outsBlock(tx, pindex->GetHeight());
2836 // The CCoins serialization does not serialize negative numbers.
2837 // No network rules currently depend on the version here, so an inconsistency is harmless
2838 // but it must be corrected before txout nversion ever influences a network rule.
2839 if (outsBlock.nVersion < 0)
2840 outs->nVersion = outsBlock.nVersion;
2841 if (*outs != outsBlock)
2842 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2848 // unspend nullifiers
2849 view.SetNullifiers(tx, false);
2853 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2854 if (txundo.vprevout.size() != tx.vin.size())
2855 return error("DisconnectBlock(): transaction and undo data inconsistent");
2856 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2857 const COutPoint &out = tx.vin[j].prevout;
2858 const CTxInUndo &undo = txundo.vprevout[j];
2859 if (!ApplyTxInUndo(undo, view, out))
2862 const CTxIn input = tx.vin[j];
2865 // undo and delete the spent index
2866 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2869 if (fAddressIndex) {
2870 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2871 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2872 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2874 // undo spending activity
2875 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2877 // restore unspent index
2878 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2882 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2883 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2885 // undo spending activity
2886 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2888 // restore unspent index
2889 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2892 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2893 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2895 // undo spending activity
2896 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2898 // restore unspent index
2899 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2902 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2903 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2905 // undo spending activity
2906 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2908 // restore unspent index
2909 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2918 else if (tx.IsCoinImport())
2920 RemoveImportTombstone(tx, view);
2924 // set the old best Sprout anchor back
2925 view.PopAnchor(blockUndo.old_sprout_tree_root, SPROUT);
2927 // set the old best Sapling anchor back
2928 // We can get this from the `hashFinalSaplingRoot` of the last block
2929 // However, this is only reliable if the last block was on or after
2930 // the Sapling activation height. Otherwise, the last anchor was the
2932 if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2933 view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING);
2935 view.PopAnchor(SaplingMerkleTree::empty_root(), SAPLING);
2938 // move best block pointer to prevout block
2939 view.SetBestBlock(pindex->pprev->GetBlockHash());
2946 if (fAddressIndex) {
2947 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2948 return AbortNode(state, "Failed to delete address index");
2950 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2951 return AbortNode(state, "Failed to write address unspent index");
2958 void static FlushBlockFile(bool fFinalize = false)
2960 LOCK(cs_LastBlockFile);
2962 CDiskBlockPos posOld(nLastBlockFile, 0);
2964 FILE *fileOld = OpenBlockFile(posOld);
2967 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2968 FileCommit(fileOld);
2972 fileOld = OpenUndoFile(posOld);
2975 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2976 FileCommit(fileOld);
2981 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
2983 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
2985 void ThreadScriptCheck() {
2986 RenameThread("zcash-scriptch");
2987 scriptcheckqueue.Thread();
2991 // Called periodically asynchronously; alerts if it smells like
2992 // we're being fed a bad chain (blocks being generated much
2993 // too slowly or too quickly).
2995 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2996 int64_t nPowTargetSpacing)
2998 if (bestHeader == NULL || initialDownloadCheck()) return;
3000 static int64_t lastAlertTime = 0;
3001 int64_t now = GetAdjustedTime();
3002 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
3004 const int SPAN_HOURS=4;
3005 const int SPAN_SECONDS=SPAN_HOURS*60*60;
3006 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
3008 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
3010 std::string strWarning;
3011 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
3014 const CBlockIndex* i = bestHeader;
3016 while (i->GetBlockTime() >= startTime) {
3019 if (i == NULL) return; // Ran out of chain, we must not be fully synced
3022 // How likely is it to find that many by chance?
3023 double p = boost::math::pdf(poisson, nBlocks);
3025 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
3026 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
3028 // Aim for one false-positive about every fifty years of normal running:
3029 const int FIFTY_YEARS = 50*365*24*60*60;
3030 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
3032 if (bestHeader->GetHeight() > BLOCKS_EXPECTED)
3034 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
3036 // Many fewer blocks than expected: alert!
3037 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
3038 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3040 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
3042 // Many more blocks than expected: alert!
3043 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
3044 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3047 if (!strWarning.empty())
3049 strMiscWarning = strWarning;
3050 CAlert::Notify(strWarning, true);
3051 lastAlertTime = now;
3056 static int64_t nTimeVerify = 0;
3057 static int64_t nTimeConnect = 0;
3058 static int64_t nTimeIndex = 0;
3059 static int64_t nTimeCallbacks = 0;
3060 static int64_t nTimeTotal = 0;
3062 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
3064 const CChainParams& chainparams = Params();
3065 if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT )
3067 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
3068 AssertLockHeld(cs_main);
3069 bool fExpensiveChecks = true;
3070 if (fCheckpointsEnabled) {
3071 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
3072 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->GetHeight()) == pindex) {
3073 // This block is an ancestor of a checkpoint: disable script checks
3074 fExpensiveChecks = false;
3077 auto verifier = libzcash::ProofVerifier::Strict();
3078 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
3079 int32_t futureblock;
3080 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
3081 if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
3083 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
3087 // verify that the view's current state corresponds to the previous block
3088 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
3089 if ( hashPrevBlock != view.GetBestBlock() )
3091 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
3092 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
3093 REJECT_INVALID, "hashPrevBlock-not-bestblock");
3095 assert(hashPrevBlock == view.GetBestBlock());
3097 // Special case for the genesis block, skipping connection of its transactions
3098 // (its coinbase is unspendable)
3099 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
3101 view.SetBestBlock(pindex->GetBlockHash());
3102 // Before the genesis block, there was an empty tree
3103 SproutMerkleTree tree;
3104 pindex->hashSproutAnchor = tree.root();
3105 // The genesis block contained no JoinSplits
3106 pindex->hashFinalSproutRoot = pindex->hashSproutAnchor;
3111 bool fScriptChecks = (!fCheckpointsEnabled || pindex->GetHeight() >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
3112 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->GetHeight() > KOMODO_TESTNET_EXPIRATION ) // "testnet"
3114 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
3115 // unless those are already completely spent.
3116 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
3117 const CCoins* coins = view.AccessCoins(tx.GetHash());
3118 if (coins && !coins->IsPruned())
3119 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
3120 REJECT_INVALID, "bad-txns-BIP30");
3123 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
3125 // DERSIG (BIP66) is also always enforced, but does not have a flag.
3127 CBlockUndo blockundo;
3129 if ( ASSETCHAINS_CC != 0 )
3131 if ( scriptcheckqueue.IsIdle() == 0 )
3133 fprintf(stderr,"scriptcheckqueue isnt idle\n");
3137 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
3139 int64_t nTimeStart = GetTimeMicros();
3142 int64_t interest,sum = 0;
3143 unsigned int nSigOps = 0;
3144 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
3145 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
3146 vPos.reserve(block.vtx.size());
3147 blockundo.vtxundo.reserve(block.vtx.size() - 1);
3148 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
3149 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
3150 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
3151 // Construct the incremental merkle tree at the current
3153 auto old_sprout_tree_root = view.GetBestAnchor(SPROUT);
3154 // saving the top anchor in the block index as we go.
3156 pindex->hashSproutAnchor = old_sprout_tree_root;
3159 SproutMerkleTree sprout_tree;
3161 // This should never fail: we should always be able to get the root
3162 // that is on the tip of our chain
3163 assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
3166 // Consistency check: the root of the tree we're given should
3167 // match what we asked for.
3168 assert(sprout_tree.root() == old_sprout_tree_root);
3171 SaplingMerkleTree sapling_tree;
3172 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
3174 // Grab the consensus branch ID for the block's height
3175 auto consensusBranchId = CurrentEpochBranchId(pindex->GetHeight(), Params().GetConsensus());
3177 std::vector<PrecomputedTransactionData> txdata;
3178 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
3179 for (unsigned int i = 0; i < block.vtx.size(); i++)
3181 const CTransaction &tx = block.vtx[i];
3182 const uint256 txhash = tx.GetHash();
3183 nInputs += tx.vin.size();
3184 nSigOps += GetLegacySigOpCount(tx);
3185 if (nSigOps > MAX_BLOCK_SIGOPS)
3186 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3187 REJECT_INVALID, "bad-blk-sigops");
3188 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->GetHeight(),tx.nLockTime);
3191 if (!view.HaveInputs(tx))
3193 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
3194 REJECT_INVALID, "bad-txns-inputs-missingorspent");
3196 // are the JoinSplit's requirements met?
3197 if (!view.HaveJoinSplitRequirements(tx))
3198 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
3199 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
3200 if (fAddressIndex || fSpentIndex)
3202 for (size_t j = 0; j < tx.vin.size(); j++) {
3204 const CTxIn input = tx.vin[j];
3205 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
3209 if (prevout.scriptPubKey.IsPayToScriptHash()) {
3210 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
3213 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
3214 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
3217 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
3218 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
3221 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
3222 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
3226 hashBytes.SetNull();
3230 if (fAddressIndex && addressType > 0) {
3231 // record spending activity
3232 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->GetHeight(), i, txhash, j, true), prevout.nValue * -1));
3234 // remove address from unspent index
3235 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
3239 // add the spent index to determine the txid and input that spent an output
3240 // and to find the amount and address from an input
3241 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->GetHeight(), prevout.nValue, addressType, hashBytes)));
3246 // Add in sigops done by pay-to-script-hash inputs;
3247 // this is to prevent a "rogue miner" from creating
3248 // an incredibly-expensive-to-validate block.
3249 nSigOps += GetP2SHSigOpCount(tx, view);
3250 if (nSigOps > MAX_BLOCK_SIGOPS)
3251 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3252 REJECT_INVALID, "bad-blk-sigops");
3255 txdata.emplace_back(tx);
3257 if (!tx.IsCoinBase())
3259 nFees += view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
3262 std::vector<CScriptCheck> vChecks;
3263 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
3265 control.Add(vChecks);
3268 if (fAddressIndex) {
3269 for (unsigned int k = 0; k < tx.vout.size(); k++) {
3270 const CTxOut &out = tx.vout[k];
3271 //fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
3272 if (out.scriptPubKey.IsPayToScriptHash()) {
3273 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
3275 // record receiving activity
3276 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3278 // record unspent output
3279 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3282 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
3283 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
3285 // record receiving activity
3286 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3288 // record unspent output
3289 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3292 else if (out.scriptPubKey.IsPayToPublicKey()) {
3293 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
3295 // record receiving activity
3296 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3298 // record unspent output
3299 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3302 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
3303 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
3305 // record receiving activity
3306 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3308 // record unspent output
3309 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3319 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3320 // komodo_earned_interest(pindex->GetHeight(),sum);
3323 blockundo.vtxundo.push_back(CTxUndo());
3325 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight());
3327 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
3328 BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
3329 // Insert the note commitments into our temporary tree.
3331 sprout_tree.append(note_commitment);
3335 BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) {
3336 sapling_tree.append(outputDescription.cm);
3339 vPos.push_back(std::make_pair(tx.GetHash(), pos));
3340 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
3343 view.PushAnchor(sprout_tree);
3344 view.PushAnchor(sapling_tree);
3346 pindex->hashFinalSproutRoot = sprout_tree.root();
3348 blockundo.old_sprout_tree_root = old_sprout_tree_root;
3350 // If Sapling is active, block.hashFinalSaplingRoot must be the
3351 // same as the root of the Sapling tree
3352 if (NetworkUpgradeActive(pindex->GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3353 if (block.hashFinalSaplingRoot != sapling_tree.root()) {
3354 return state.DoS(100,
3355 error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"),
3356 REJECT_INVALID, "bad-sapling-root-in-block");
3359 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3360 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);
3362 CAmount blockReward = nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum;
3363 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
3365 uint64_t checktoshis;
3366 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
3368 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
3369 blockReward += checktoshis;
3370 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
3373 if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward)
3375 return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
3376 REJECT_INVALID, "bad-cb-amount");
3378 if ( block.vtx[0].GetValueOut() > blockReward+1 )
3380 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->GetHeight() >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
3382 return state.DoS(100,
3383 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3384 block.vtx[0].GetValueOut(), blockReward),
3385 REJECT_INVALID, "bad-cb-amount");
3386 } else if ( IS_KOMODO_NOTARY != 0 )
3387 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));
3389 if (!control.Wait())
3390 return state.DoS(100, false);
3391 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3392 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);
3397 // Write undo information to disk
3398 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
3400 if (pindex->GetUndoPos().IsNull()) {
3402 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
3403 return error("ConnectBlock(): FindUndoPos failed");
3404 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
3405 return AbortNode(state, "Failed to write undo data");
3407 // update nUndoPos in block index
3408 pindex->nUndoPos = pos.nPos;
3409 pindex->nStatus |= BLOCK_HAVE_UNDO;
3412 // Now that all consensus rules have been validated, set nCachedBranchId.
3413 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3414 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
3415 "nCachedBranchId must be set after all consensus rules have been validated.");
3416 if (IsActivationHeightForAnyUpgrade(pindex->GetHeight(), Params().GetConsensus())) {
3417 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
3418 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->GetHeight(), chainparams.GetConsensus());
3419 } else if (pindex->pprev) {
3420 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
3423 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
3424 setDirtyBlockIndex.insert(pindex);
3427 ConnectNotarisations(block, pindex->GetHeight());
3430 if (!pblocktree->WriteTxIndex(vPos))
3431 return AbortNode(state, "Failed to write transaction index");
3432 if (fAddressIndex) {
3433 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3434 return AbortNode(state, "Failed to write address index");
3437 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3438 return AbortNode(state, "Failed to write address unspent index");
3443 if (!pblocktree->UpdateSpentIndex(spentIndex))
3444 return AbortNode(state, "Failed to write transaction index");
3446 if (fTimestampIndex) {
3447 unsigned int logicalTS = pindex->nTime;
3448 unsigned int prevLogicalTS = 0;
3450 // retrieve logical timestamp of the previous block
3452 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3453 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3455 if (logicalTS <= prevLogicalTS) {
3456 logicalTS = prevLogicalTS + 1;
3457 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3460 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3461 return AbortNode(state, "Failed to write timestamp index");
3463 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3464 return AbortNode(state, "Failed to write blockhash index");
3467 // add this block to the view's block chain
3468 view.SetBestBlock(pindex->GetBlockHash());
3470 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3471 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
3473 // Watch for changes to the previous coinbase transaction.
3474 static uint256 hashPrevBestCoinBase;
3475 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
3476 hashPrevBestCoinBase = block.vtx[0].GetHash();
3478 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3479 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
3481 //FlushStateToDisk();
3482 komodo_connectblock(pindex,*(CBlock *)&block);
3486 enum FlushStateMode {
3488 FLUSH_STATE_IF_NEEDED,
3489 FLUSH_STATE_PERIODIC,
3494 * Update the on-disk chain state.
3495 * The caches and indexes are flushed depending on the mode we're called with
3496 * if they're too large, if it's been a while since the last write,
3497 * or always and in all cases if we're in prune mode and are deleting files.
3499 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
3500 LOCK2(cs_main, cs_LastBlockFile);
3501 static int64_t nLastWrite = 0;
3502 static int64_t nLastFlush = 0;
3503 static int64_t nLastSetChain = 0;
3504 std::set<int> setFilesToPrune;
3505 bool fFlushForPrune = false;
3507 if (fPruneMode && fCheckForPruning && !fReindex) {
3508 FindFilesToPrune(setFilesToPrune);
3509 fCheckForPruning = false;
3510 if (!setFilesToPrune.empty()) {
3511 fFlushForPrune = true;
3513 pblocktree->WriteFlag("prunedblockfiles", true);
3518 int64_t nNow = GetTimeMicros();
3519 // Avoid writing/flushing immediately after startup.
3520 if (nLastWrite == 0) {
3523 if (nLastFlush == 0) {
3526 if (nLastSetChain == 0) {
3527 nLastSetChain = nNow;
3529 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3530 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3531 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3532 // The cache is over the limit, we have to write now.
3533 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3534 // 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.
3535 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3536 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3537 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3538 // Combine all conditions that result in a full cache flush.
3539 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3540 // Write blocks and block index to disk.
3541 if (fDoFullFlush || fPeriodicWrite) {
3542 // Depend on nMinDiskSpace to ensure we can write block index
3543 if (!CheckDiskSpace(0))
3544 return state.Error("out of disk space");
3545 // First make sure all block and undo data is flushed to disk.
3547 // Then update all block file information (which may refer to block and undo files).
3549 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3550 vFiles.reserve(setDirtyFileInfo.size());
3551 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3552 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3553 setDirtyFileInfo.erase(it++);
3555 std::vector<const CBlockIndex*> vBlocks;
3556 vBlocks.reserve(setDirtyBlockIndex.size());
3557 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3558 vBlocks.push_back(*it);
3559 setDirtyBlockIndex.erase(it++);
3561 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3562 return AbortNode(state, "Files to write to block index database");
3565 // Finally remove any pruned files
3567 UnlinkPrunedFiles(setFilesToPrune);
3570 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3572 // Typical CCoins structures on disk are around 128 bytes in size.
3573 // Pushing a new one to the database can cause it to be written
3574 // twice (once in the log, and once in the tables). This is already
3575 // an overestimation, as most will delete an existing entry or
3576 // overwrite one. Still, use a conservative safety factor of 2.
3577 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3578 return state.Error("out of disk space");
3579 // Flush the chainstate (which may refer to block index entries).
3580 if (!pcoinsTip->Flush())
3581 return AbortNode(state, "Failed to write to coin database");
3584 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3585 // Update best block in wallet (so we can detect restored wallets).
3586 GetMainSignals().SetBestChain(chainActive.GetLocator());
3587 nLastSetChain = nNow;
3589 } catch (const std::runtime_error& e) {
3590 return AbortNode(state, std::string("System error while flushing: ") + e.what());
3595 void FlushStateToDisk() {
3596 CValidationState state;
3597 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3600 void PruneAndFlush() {
3601 CValidationState state;
3602 fCheckForPruning = true;
3603 FlushStateToDisk(state, FLUSH_STATE_NONE);
3606 /** Update chainActive and related internal data structures. */
3607 void static UpdateTip(CBlockIndex *pindexNew) {
3608 const CChainParams& chainParams = Params();
3609 chainActive.SetTip(pindexNew);
3612 nTimeBestReceived = GetTime();
3613 mempool.AddTransactionsUpdated(1);
3616 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
3617 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
3619 int32_t longestchain = komodo_longestchain();
3620 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
3623 LogPrintf("%s: new best=%s height=%d log2_work=%.8g log2_stake=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
3624 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3625 log(chainActive.Tip()->chainPower.chainWork.getdouble())/log(2.0),
3626 log(chainActive.Tip()->chainPower.chainStake.getdouble())/log(2.0),
3627 (unsigned long)chainActive.LastTip()->nChainTx,
3628 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
3629 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3631 cvBlockChange.notify_all();
3633 // Check the version of the last 100 blocks to see if we need to upgrade:
3634 static bool fWarned = false;
3635 if (!IsInitialBlockDownload() && !fWarned)
3638 const CBlockIndex* pindex = chainActive.Tip();
3639 for (int i = 0; i < 100 && pindex != NULL; i++)
3641 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3643 pindex = pindex->pprev;
3646 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3647 if (nUpgraded > 100/2)
3649 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3650 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3651 CAlert::Notify(strMiscWarning, true);
3658 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3659 * mempool.removeWithoutBranchId after this, with cs_main held.
3661 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3662 CBlockIndex *pindexDelete = chainActive.Tip();
3663 assert(pindexDelete);
3664 // Read block from disk.
3666 if (!ReadBlockFromDisk(block, pindexDelete,1))
3667 return AbortNode(state, "Failed to read block");
3668 // Apply the block atomically to the chain state.
3669 uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3670 uint256 saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3671 int64_t nStart = GetTimeMicros();
3673 CCoinsViewCache view(pcoinsTip);
3674 if (!DisconnectBlock(block, state, pindexDelete, view))
3675 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3676 assert(view.Flush());
3677 DisconnectNotarisations(block);
3679 pindexDelete->segid = -2;
3680 pindexDelete->newcoins = 0;
3681 pindexDelete->zfunds = 0;
3683 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3684 uint256 sproutAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3685 uint256 saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3686 // Write the chain state to disk, if necessary.
3687 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3691 // resurrect mempool transactions from the disconnected block.
3692 for (int i = 0; i < block.vtx.size(); i++)
3694 // ignore validation errors in resurrected transactions
3695 CTransaction &tx = block.vtx[i];
3696 list<CTransaction> removed;
3697 CValidationState stateDummy;
3698 // don't keep staking or invalid transactions
3699 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (komodo_isPoS((CBlock *)&block) != 0))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3701 mempool.remove(tx, removed, true);
3704 if (sproutAnchorBeforeDisconnect != sproutAnchorAfterDisconnect) {
3705 // The anchor may not change between block disconnects,
3706 // in which case we don't want to evict from the mempool yet!
3707 mempool.removeWithAnchor(sproutAnchorBeforeDisconnect, SPROUT);
3709 if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) {
3710 // The anchor may not change between block disconnects,
3711 // in which case we don't want to evict from the mempool yet!
3712 mempool.removeWithAnchor(saplingAnchorBeforeDisconnect, SAPLING);
3716 // Update chainActive and related variables.
3717 UpdateTip(pindexDelete->pprev);
3719 // Get the current commitment tree
3720 SproutMerkleTree newSproutTree;
3721 SaplingMerkleTree newSaplingTree;
3722 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
3723 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
3724 // Let wallets know transactions went from 1-confirmed to
3725 // 0-confirmed or conflicted:
3726 for (int i = 0; i < block.vtx.size(); i++)
3728 CTransaction &tx = block.vtx[i];
3729 if ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
3731 EraseFromWallets(tx.GetHash());
3735 SyncWithWallets(tx, NULL);
3738 // Update cached incremental witnesses
3739 GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
3743 static int64_t nTimeReadFromDisk = 0;
3744 static int64_t nTimeConnectTotal = 0;
3745 static int64_t nTimeFlush = 0;
3746 static int64_t nTimeChainState = 0;
3747 static int64_t nTimePostConnect = 0;
3750 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3751 * corresponding to pindexNew, to bypass loading it again from disk.
3752 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3754 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3756 assert(pindexNew->pprev == chainActive.Tip());
3757 // Read block from disk.
3758 int64_t nTime1 = GetTimeMicros();
3761 if (!ReadBlockFromDisk(block, pindexNew,1))
3762 return AbortNode(state, "Failed to read block");
3765 KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight();
3766 // Get the current commitment tree
3767 SproutMerkleTree oldSproutTree;
3768 SaplingMerkleTree oldSaplingTree;
3769 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
3770 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
3771 // Apply the block atomically to the chain state.
3772 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3774 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3776 CCoinsViewCache view(pcoinsTip);
3777 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3778 KOMODO_CONNECTING = -1;
3779 GetMainSignals().BlockChecked(*pblock, state);
3781 if (state.IsInvalid())
3782 InvalidBlockFound(pindexNew, state);
3783 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3785 mapBlockSource.erase(pindexNew->GetBlockHash());
3786 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3787 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3788 assert(view.Flush());
3790 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3791 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3792 // Write the chain state to disk, if necessary.
3793 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3795 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3796 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3797 // Remove conflicting transactions from the mempool.
3798 list<CTransaction> txConflicted;
3799 mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload());
3801 // Remove transactions that expire at new block height from mempool
3802 mempool.removeExpired(pindexNew->GetHeight());
3804 // Update chainActive & related variables.
3805 UpdateTip(pindexNew);
3806 // Tell wallet about transactions that went from mempool
3808 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3809 SyncWithWallets(tx, NULL);
3811 // ... and about transactions that got confirmed:
3812 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3813 SyncWithWallets(tx, pblock);
3815 // Update cached incremental witnesses
3816 GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
3818 EnforceNodeDeprecation(pindexNew->GetHeight());
3820 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3821 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3822 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3823 if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->GetHeight() >= KOMODO_LONGESTCHAIN )
3825 else KOMODO_INSYNC = 0;
3826 //fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->GetHeight(),KOMODO_INSYNC);
3827 if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
3828 komodo_broadcast(pblock,8);
3833 * Return the tip of the chain with the most work in it, that isn't
3834 * known to be invalid (it's however far from certain to be valid).
3836 static CBlockIndex* FindMostWorkChain() {
3838 CBlockIndex *pindexNew = NULL;
3840 // Find the best candidate header.
3842 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3843 if (it == setBlockIndexCandidates.rend())
3848 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3849 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3850 CBlockIndex *pindexTest = pindexNew;
3851 bool fInvalidAncestor = false;
3852 while (pindexTest && !chainActive.Contains(pindexTest)) {
3853 assert(pindexTest->nChainTx || pindexTest->GetHeight() == 0);
3855 // Pruned nodes may have entries in setBlockIndexCandidates for
3856 // which block files have been deleted. Remove those as candidates
3857 // for the most work chain if we come across them; we can't switch
3858 // to a chain unless we have all the non-active-chain parent blocks.
3859 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3860 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3861 if (fFailedChain || fMissingData) {
3862 // Candidate chain is not usable (either invalid or missing data)
3863 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->chainPower > pindexBestInvalid->chainPower))
3864 pindexBestInvalid = pindexNew;
3865 CBlockIndex *pindexFailed = pindexNew;
3866 // Remove the entire chain from the set.
3867 while (pindexTest != pindexFailed) {
3869 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3870 } else if (fMissingData) {
3871 // If we're missing data, then add back to mapBlocksUnlinked,
3872 // so that if the block arrives in the future we can try adding
3873 // to setBlockIndexCandidates again.
3874 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3876 setBlockIndexCandidates.erase(pindexFailed);
3877 pindexFailed = pindexFailed->pprev;
3879 setBlockIndexCandidates.erase(pindexTest);
3880 fInvalidAncestor = true;
3883 pindexTest = pindexTest->pprev;
3885 if (!fInvalidAncestor)
3890 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3891 static void PruneBlockIndexCandidates() {
3892 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3893 // reorganization to a better block fails.
3894 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3895 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
3896 setBlockIndexCandidates.erase(it++);
3898 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3899 assert(!setBlockIndexCandidates.empty());
3903 * Try to make some progress towards making pindexMostWork the active block.
3904 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3906 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3907 AssertLockHeld(cs_main);
3908 bool fInvalidFound = false;
3909 const CBlockIndex *pindexOldTip = chainActive.Tip();
3910 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3912 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3913 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3914 // then pindexFork will be null, and we would need to remove the entire chain including
3915 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3916 auto reorgLength = pindexOldTip ? pindexOldTip->GetHeight() - (pindexFork ? pindexFork->GetHeight() : -1) : 0;
3917 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3918 if (reorgLength > MAX_REORG_LENGTH) {
3919 auto msg = strprintf(_(
3920 "A block chain reorganization has been detected that would roll back %d blocks! "
3921 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3922 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3923 _("Reorganization details") + ":\n" +
3924 "- " + strprintf(_("Current tip: %s, height %d, work %s\nstake %s"),
3925 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex(),
3926 pindexOldTip->chainPower.chainStake.GetHex()) + "\n" +
3927 "- " + strprintf(_("New tip: %s, height %d, work %s\nstake %s"),
3928 pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex(),
3929 pindexMostWork->chainPower.chainStake.GetHex()) + "\n" +
3930 "- " + strprintf(_("Fork point: %s %s, height %d"),
3931 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n\n" +
3932 _("Please help, human!");
3933 LogPrintf("*** %s\n", msg);
3934 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3939 // Disconnect active blocks which are no longer in the best chain.
3940 bool fBlocksDisconnected = false;
3941 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3942 if (!DisconnectTip(state))
3944 fBlocksDisconnected = true;
3946 if ( KOMODO_REWIND != 0 )
3948 CBlockIndex *tipindex;
3949 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->GetHeight(),KOMODO_REWIND);
3950 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->GetHeight() > KOMODO_REWIND )
3952 fBlocksDisconnected = true;
3953 fprintf(stderr,"%d ",(int32_t)tipindex->GetHeight());
3954 InvalidateBlock(state,tipindex);
3955 if ( !DisconnectTip(state) )
3958 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3960 fprintf(stderr,"resuming normal operations\n");
3964 // Build list of new blocks to connect.
3965 std::vector<CBlockIndex*> vpindexToConnect;
3966 bool fContinue = true;
3967 int nHeight = pindexFork ? pindexFork->GetHeight() : -1;
3968 while (fContinue && nHeight != pindexMostWork->GetHeight()) {
3969 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3970 // a few blocks along the way.
3971 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->GetHeight());
3972 vpindexToConnect.clear();
3973 vpindexToConnect.reserve(nTargetHeight - nHeight);
3974 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3975 while (pindexIter && pindexIter->GetHeight() != nHeight) {
3976 vpindexToConnect.push_back(pindexIter);
3977 pindexIter = pindexIter->pprev;
3979 nHeight = nTargetHeight;
3981 // Connect new blocks.
3982 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
3983 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
3984 if (state.IsInvalid()) {
3985 // The block violates a consensus rule.
3986 if (!state.CorruptionPossible())
3987 InvalidChainFound(vpindexToConnect.back());
3988 state = CValidationState();
3989 fInvalidFound = true;
3993 // A system error occurred (disk space, database error, ...).
3997 PruneBlockIndexCandidates();
3998 if (!pindexOldTip || chainActive.Tip()->chainPower > pindexOldTip->chainPower) {
3999 // We're in a better position than we were. Return temporarily to release the lock.
4007 if (fBlocksDisconnected) {
4008 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4010 mempool.removeWithoutBranchId(
4011 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4012 mempool.check(pcoinsTip);
4014 // Callbacks/notifications for a new best chain.
4016 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
4018 CheckForkWarningConditions();
4024 * Make the best chain active, in multiple steps. The result is either failure
4025 * or an activated best chain. pblock is either NULL or a pointer to a block
4026 * that is already loaded (to avoid loading it again from disk).
4028 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
4029 CBlockIndex *pindexNewTip = NULL;
4030 CBlockIndex *pindexMostWork = NULL;
4031 const CChainParams& chainParams = Params();
4033 boost::this_thread::interruption_point();
4035 bool fInitialDownload;
4038 pindexMostWork = FindMostWorkChain();
4040 // Whether we have anything to do at all.
4041 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
4044 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
4046 pindexNewTip = chainActive.Tip();
4047 fInitialDownload = IsInitialBlockDownload();
4049 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
4051 // Notifications/callbacks that can run without cs_main
4052 if (!fInitialDownload) {
4053 uint256 hashNewTip = pindexNewTip->GetBlockHash();
4054 // Relay inventory, but don't relay old inventory during initial block download.
4055 int nBlockEstimate = 0;
4056 if (fCheckpointsEnabled)
4057 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
4058 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
4059 // in a stalled download if the block file is pruned before the request.
4060 if (nLocalServices & NODE_NETWORK) {
4062 BOOST_FOREACH(CNode* pnode, vNodes)
4063 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
4064 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
4066 // Notify external listeners about the new tip.
4067 GetMainSignals().UpdatedBlockTip(pindexNewTip);
4068 uiInterface.NotifyBlockTip(hashNewTip);
4069 } //else fprintf(stderr,"initial download skips propagation\n");
4070 } while(pindexMostWork != chainActive.Tip());
4073 // Write changes periodically to disk, after relay.
4074 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
4081 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
4082 AssertLockHeld(cs_main);
4084 // Mark the block itself as invalid.
4085 pindex->nStatus |= BLOCK_FAILED_VALID;
4086 setDirtyBlockIndex.insert(pindex);
4087 setBlockIndexCandidates.erase(pindex);
4089 while (chainActive.Contains(pindex)) {
4090 CBlockIndex *pindexWalk = chainActive.Tip();
4091 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
4092 setDirtyBlockIndex.insert(pindexWalk);
4093 setBlockIndexCandidates.erase(pindexWalk);
4094 // ActivateBestChain considers blocks already in chainActive
4095 // unconditionally valid already, so force disconnect away from it.
4096 if (!DisconnectTip(state)) {
4097 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4098 mempool.removeWithoutBranchId(
4099 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4103 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
4105 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
4107 BlockMap::iterator it = mapBlockIndex.begin();
4108 while (it != mapBlockIndex.end() && it->second != 0 ) {
4109 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
4110 setBlockIndexCandidates.insert(it->second);
4115 InvalidChainFound(pindex);
4116 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4117 mempool.removeWithoutBranchId(
4118 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4122 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
4123 AssertLockHeld(cs_main);
4125 int nHeight = pindex->GetHeight();
4127 // Remove the invalidity flag from this block and all its descendants.
4128 BlockMap::iterator it = mapBlockIndex.begin();
4129 while (it != mapBlockIndex.end()) {
4130 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
4131 it->second->nStatus &= ~BLOCK_FAILED_MASK;
4132 setDirtyBlockIndex.insert(it->second);
4133 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
4134 setBlockIndexCandidates.insert(it->second);
4136 if (it->second == pindexBestInvalid) {
4137 // Reset invalid block marker if it was pointing to one of those.
4138 pindexBestInvalid = NULL;
4144 // Remove the invalidity flag from all ancestors too.
4145 while (pindex != NULL) {
4146 if (pindex->nStatus & BLOCK_FAILED_MASK) {
4147 pindex->nStatus &= ~BLOCK_FAILED_MASK;
4148 setDirtyBlockIndex.insert(pindex);
4150 pindex = pindex->pprev;
4155 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
4157 // Check for duplicate
4158 uint256 hash = block.GetHash();
4159 BlockMap::iterator it = mapBlockIndex.find(hash);
4160 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
4161 if (it != mapBlockIndex.end())
4163 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
4165 // 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
4166 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
4169 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
4171 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
4172 return(0); // return here to avoid the state of pindex->GetHeight() not set and pprev NULL
4175 // Construct new block index object
4176 CBlockIndex* pindexNew = new CBlockIndex(block);
4178 // We assign the sequence id to blocks only when the full data is available,
4179 // to avoid miners withholding blocks but broadcasting headers, to get a
4180 // competitive advantage.
4181 pindexNew->nSequenceId = 0;
4182 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4183 pindexNew->phashBlock = &((*mi).first);
4184 if (miPrev != mapBlockIndex.end())
4186 if ( (pindexNew->pprev= (*miPrev).second) != 0 )
4187 pindexNew->SetHeight(pindexNew->pprev->GetHeight() + 1);
4188 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
4189 pindexNew->BuildSkip();
4191 pindexNew->chainPower = (pindexNew->pprev ? CChainPower(pindexNew) + pindexNew->pprev->chainPower : CChainPower(pindexNew)) + GetBlockProof(*pindexNew);
4192 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
4193 if (pindexBestHeader == NULL || pindexBestHeader->chainPower < pindexNew->chainPower)
4194 pindexBestHeader = pindexNew;
4196 setDirtyBlockIndex.insert(pindexNew);
4197 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
4198 mi->second = pindexNew;
4202 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
4203 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
4205 pindexNew->nTx = block.vtx.size();
4206 pindexNew->nChainTx = 0;
4207 CAmount sproutValue = 0;
4208 CAmount saplingValue = 0;
4209 for (auto tx : block.vtx) {
4210 // Negative valueBalance "takes" money from the transparent value pool
4211 // and adds it to the Sapling value pool. Positive valueBalance "gives"
4212 // money to the transparent value pool, removing from the Sapling value
4213 // pool. So we invert the sign here.
4214 saplingValue += -tx.valueBalance;
4216 for (auto js : tx.vjoinsplit) {
4217 sproutValue += js.vpub_old;
4218 sproutValue -= js.vpub_new;
4221 pindexNew->nSproutValue = sproutValue;
4222 pindexNew->nChainSproutValue = boost::none;
4223 pindexNew->nSaplingValue = saplingValue;
4224 pindexNew->nChainSaplingValue = boost::none;
4225 pindexNew->nFile = pos.nFile;
4226 pindexNew->nDataPos = pos.nPos;
4227 pindexNew->nUndoPos = 0;
4228 pindexNew->nStatus |= BLOCK_HAVE_DATA;
4229 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
4230 setDirtyBlockIndex.insert(pindexNew);
4232 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
4233 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
4234 deque<CBlockIndex*> queue;
4235 queue.push_back(pindexNew);
4237 // Recursively process any descendant blocks that now may be eligible to be connected.
4238 while (!queue.empty()) {
4239 CBlockIndex *pindex = queue.front();
4241 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
4242 if (pindex->pprev) {
4243 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4244 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4246 pindex->nChainSproutValue = boost::none;
4248 if (pindex->pprev->nChainSaplingValue) {
4249 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
4251 pindex->nChainSaplingValue = boost::none;
4254 pindex->nChainSproutValue = pindex->nSproutValue;
4255 pindex->nChainSaplingValue = pindex->nSaplingValue;
4258 LOCK(cs_nBlockSequenceId);
4259 pindex->nSequenceId = nBlockSequenceId++;
4261 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
4262 setBlockIndexCandidates.insert(pindex);
4264 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
4265 while (range.first != range.second) {
4266 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
4267 queue.push_back(it->second);
4269 mapBlocksUnlinked.erase(it);
4273 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
4274 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
4281 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
4283 LOCK(cs_LastBlockFile);
4285 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
4286 if (vinfoBlockFile.size() <= nFile) {
4287 vinfoBlockFile.resize(nFile + 1);
4291 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
4293 if (vinfoBlockFile.size() <= nFile) {
4294 vinfoBlockFile.resize(nFile + 1);
4298 pos.nPos = vinfoBlockFile[nFile].nSize;
4301 if (nFile != nLastBlockFile) {
4303 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
4305 FlushBlockFile(!fKnown);
4306 nLastBlockFile = nFile;
4309 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
4311 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
4313 vinfoBlockFile[nFile].nSize += nAddSize;
4316 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4317 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4318 if (nNewChunks > nOldChunks) {
4320 fCheckForPruning = true;
4321 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
4322 FILE *file = OpenBlockFile(pos);
4324 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
4325 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
4330 return state.Error("out of disk space");
4334 setDirtyFileInfo.insert(nFile);
4338 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
4342 LOCK(cs_LastBlockFile);
4344 unsigned int nNewSize;
4345 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
4346 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
4347 setDirtyFileInfo.insert(nFile);
4349 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4350 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4351 if (nNewChunks > nOldChunks) {
4353 fCheckForPruning = true;
4354 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
4355 FILE *file = OpenUndoFile(pos);
4357 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
4358 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
4363 return state.Error("out of disk space");
4369 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
4374 uint256 hash; int32_t i;
4375 hash = blockhdr.GetHash();
4376 for (i=31; i>=0; i--)
4377 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4378 fprintf(stderr," <- CheckBlockHeader\n");
4379 if ( chainActive.LastTip() != 0 )
4381 hash = chainActive.LastTip()->GetBlockHash();
4382 for (i=31; i>=0; i--)
4383 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4384 fprintf(stderr," <- chainTip\n");
4388 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
4390 CBlockIndex *tipindex;
4391 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
4392 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
4394 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
4395 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4397 //fprintf(stderr,"now its valid\n");
4401 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4403 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
4404 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4407 // Check block version
4408 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
4409 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
4411 // Check Equihash solution is valid
4414 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4415 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4417 // Check proof of work matches claimed amount
4418 /*komodo_index2pubkey33(pubkey33,pindex,height);
4419 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
4420 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
4424 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
4425 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
4427 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
4428 libzcash::ProofVerifier& verifier,
4429 bool fCheckPOW, bool fCheckMerkleRoot)
4431 uint8_t pubkey33[33]; uint256 hash;
4432 // These are checks that are independent of context.
4433 hash = block.GetHash();
4434 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
4435 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
4437 if ( *futureblockp == 0 )
4439 LogPrintf("CheckBlock header error");
4445 //if ( !CheckEquihashSolution(&block, Params()) )
4446 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4447 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
4448 if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
4450 int32_t z; for (z=31; z>=0; z--)
4451 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
4452 fprintf(stderr," failed hash ht.%d\n",height);
4453 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
4455 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
4456 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4458 // Check the merkle root.
4459 if (fCheckMerkleRoot) {
4461 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4462 if (block.hashMerkleRoot != hashMerkleRoot2)
4463 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
4464 REJECT_INVALID, "bad-txnmrklroot", true);
4466 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4467 // of transactions in a block without affecting the merkle root of a block,
4468 // while still invalidating it.
4470 return state.DoS(100, error("CheckBlock: duplicate transaction"),
4471 REJECT_INVALID, "bad-txns-duplicate", true);
4474 // All potential-corruption validation must be done before we do any
4475 // transaction validation, as otherwise we may mark the header as invalid
4476 // because we receive the wrong transactions for it.
4479 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
4480 return state.DoS(100, error("CheckBlock: size limits failed"),
4481 REJECT_INVALID, "bad-blk-length");
4483 // First transaction must be coinbase, the rest must not be
4484 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
4485 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
4486 REJECT_INVALID, "bad-cb-missing");
4488 for (unsigned int i = 1; i < block.vtx.size(); i++)
4489 if (block.vtx[i].IsCoinBase())
4490 return state.DoS(100, error("CheckBlock: more than one coinbase"),
4491 REJECT_INVALID, "bad-cb-multiple");
4493 // Check transactions
4494 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
4496 CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
4497 //fprintf(stderr,"put block's tx into mempool\n");
4500 for (i=0; i<block.vtx.size(); i++)
4502 CTransaction Tx; const CTransaction &tx = (CTransaction)block.vtx[i];
4503 if ( tx.IsCoinBase() != 0 )
4505 else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || komodo_isPoS((CBlock *)&block) != 0) )
4508 if ( myAddtomempool(Tx) == false ) // happens with out of order tx in block on resync
4511 if ( rejects == 0 || rejects == lastrejects )
4513 if ( 0 && lastrejects != 0 )
4514 fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
4517 //fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
4518 lastrejects = rejects;
4521 //fprintf(stderr,"done putting block's tx into mempool\n");
4523 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4525 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
4526 return error("CheckBlock: komodo_validate_interest failed");
4527 if (!CheckTransaction(tx, state, verifier))
4528 return error("CheckBlock: CheckTransaction failed");
4530 unsigned int nSigOps = 0;
4531 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4533 nSigOps += GetLegacySigOpCount(tx);
4535 if (nSigOps > MAX_BLOCK_SIGOPS)
4536 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
4537 REJECT_INVALID, "bad-blk-sigops", true);
4538 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
4540 //static uint32_t counter;
4541 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
4542 // fprintf(stderr,"check deposit rejection\n");
4543 LogPrintf("CheckBlockHeader komodo_check_deposit error");
4549 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4551 const CChainParams& chainParams = Params();
4552 const Consensus::Params& consensusParams = chainParams.GetConsensus();
4553 uint256 hash = block.GetHash();
4554 if (hash == consensusParams.hashGenesisBlock)
4559 int nHeight = pindexPrev->GetHeight()+1;
4561 // Check proof of work
4562 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
4564 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) <<
4565 " for block #" << nHeight << endl;
4566 return state.DoS(100, error("%s: incorrect proof of work", __func__),
4567 REJECT_INVALID, "bad-diffbits");
4570 // Check timestamp against prev
4571 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
4573 return state.Invalid(error("%s: block's timestamp is too early", __func__),
4574 REJECT_INVALID, "time-too-old");
4577 // Check that timestamp is not too far in the future
4578 if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
4580 return state.Invalid(error("%s: block timestamp too far in the future", __func__),
4581 REJECT_INVALID, "time-too-new");
4584 if (fCheckpointsEnabled)
4586 // Check that the block chain matches the known block chain up to a checkpoint
4587 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
4589 /*CBlockIndex *heightblock = chainActive[nHeight];
4590 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4592 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4595 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
4597 // Don't accept any forks from the main chain prior to last checkpoint
4598 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
4599 int32_t notarized_height;
4600 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() > 1 )
4602 CBlockIndex *heightblock = chainActive[nHeight];
4603 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4605 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
4609 if ( pcheckpoint != 0 && nHeight < pcheckpoint->GetHeight() )
4610 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->GetHeight()));
4611 if ( komodo_checkpoint(¬arized_height,nHeight,hash) < 0 )
4613 CBlockIndex *heightblock = chainActive[nHeight];
4614 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4616 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4618 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4622 // Reject block.nVersion < 4 blocks
4623 if (block.nVersion < 4)
4624 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4625 REJECT_OBSOLETE, "bad-version");
4630 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4632 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->GetHeight() + 1;
4633 const Consensus::Params& consensusParams = Params().GetConsensus();
4635 // Check that all transactions are finalized
4636 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
4638 // Check transaction contextually against consensus rules at block height
4639 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4640 return false; // Failure reason has been set in validation state object
4643 int nLockTimeFlags = 0;
4644 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4645 ? pindexPrev->GetMedianTimePast()
4646 : block.GetBlockTime();
4647 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4648 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4652 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4653 // In Zcash this has been enforced since launch, except that the genesis
4654 // block didn't include the height in the coinbase (see Zcash protocol spec
4655 // section '6.8 Bitcoin Improvement Proposals').
4658 CScript expect = CScript() << nHeight;
4659 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4660 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4661 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4667 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4669 static uint256 zero;
4670 const CChainParams& chainparams = Params();
4671 AssertLockHeld(cs_main);
4673 // Check for duplicate
4674 uint256 hash = block.GetHash();
4675 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4676 CBlockIndex *pindex = NULL;
4677 if (miSelf != mapBlockIndex.end())
4679 // Block header is already known.
4680 if ( (pindex= miSelf->second) == 0 )
4681 miSelf->second = pindex = AddToBlockIndex(block);
4684 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4685 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4686 /*if ( pindex != 0 && hash == komodo_requestedhash )
4688 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4689 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4690 komodo_requestedcount = 0;
4693 //if ( pindex == 0 )
4694 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4697 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state,0))
4699 if ( *futureblockp == 0 )
4701 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4705 // Get prev block index
4706 CBlockIndex* pindexPrev = NULL;
4707 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4709 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4710 if (mi == mapBlockIndex.end())
4712 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4714 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4716 pindexPrev = (*mi).second;
4717 if (pindexPrev == 0 )
4719 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4722 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4723 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4725 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4727 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4728 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4733 if ( (pindex= AddToBlockIndex(block)) != 0 )
4735 miSelf = mapBlockIndex.find(hash);
4736 if (miSelf != mapBlockIndex.end())
4737 miSelf->second = pindex;
4738 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4743 /*if ( pindex != 0 && hash == komodo_requestedhash )
4745 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4746 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4747 komodo_requestedcount = 0;
4752 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4754 const CChainParams& chainparams = Params();
4755 AssertLockHeld(cs_main);
4757 CBlockIndex *&pindex = *ppindex;
4758 if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
4760 if ( *futureblockp == 0 )
4762 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4768 LogPrintf("AcceptBlock null pindex error\n");
4771 //fprintf(stderr,"acceptblockheader passed\n");
4772 // Try to process all requested blocks that we don't have, but only
4773 // process an unrequested block if it's new and has enough work to
4774 // advance our tip, and isn't too many blocks ahead.
4775 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4776 bool fHasMoreWork = (chainActive.Tip() ? pindex->chainPower > chainActive.Tip()->chainPower : true);
4777 // Blocks that are too out-of-order needlessly limit the effectiveness of
4778 // pruning, because pruning will not delete block files that contain any
4779 // blocks which are too close in height to the tip. Apply this test
4780 // regardless of whether pruning is enabled; it should generally be safe to
4781 // not process unrequested blocks.
4782 bool fTooFarAhead = (pindex->GetHeight() > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4784 // TODO: deal better with return value and error conditions for duplicate
4785 // and unrequested blocks.
4786 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4787 if (fAlreadyHave) return true;
4788 if (!fRequested) { // If we didn't ask for it:
4789 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4790 if (!fHasMoreWork) return true; // Don't process less-work chains
4791 if (fTooFarAhead) return true; // Block height is too high
4794 // See method docstring for why this is always disabled
4795 auto verifier = libzcash::ProofVerifier::Disabled();
4796 if ((!CheckBlock(futureblockp,pindex->GetHeight(),pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4798 if ( *futureblockp == 0 )
4800 if (state.IsInvalid() && !state.CorruptionPossible()) {
4801 pindex->nStatus |= BLOCK_FAILED_VALID;
4802 setDirtyBlockIndex.insert(pindex);
4804 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4809 int nHeight = pindex->GetHeight();
4810 // Write block to history file
4812 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4813 CDiskBlockPos blockPos;
4816 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4817 return error("AcceptBlock(): FindBlockPos failed");
4819 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4820 AbortNode(state, "Failed to write block");
4821 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4822 return error("AcceptBlock(): ReceivedBlockTransactions failed");
4823 } catch (const std::runtime_error& e) {
4824 return AbortNode(state, std::string("System error: ") + e.what());
4827 if (fCheckForPruning)
4828 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4829 if ( *futureblockp == 0 )
4831 LogPrintf("AcceptBlock block from future error\n");
4835 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4837 unsigned int nFound = 0;
4838 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4840 if (pstart->nVersion >= minVersion)
4842 pstart = pstart->pprev;
4844 return (nFound >= nRequired);
4847 void komodo_currentheight_set(int32_t height);
4849 CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4851 CBlockIndex *pindex = 0;
4852 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4853 if ( miSelf != mapBlockIndex.end() )
4855 if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4857 miSelf->second = AddToBlockIndex(*pblock);
4858 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4860 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4862 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4863 if ( miSelf != mapBlockIndex.end() )
4865 if ( miSelf->second == 0 )
4867 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4868 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4876 CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
4878 CBlockIndex *pindex=0,*previndex=0;
4879 if ( (pindex= mapBlockIndex[hash]) == 0 )
4881 pindex = new CBlockIndex();
4883 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4884 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4885 pindex->phashBlock = &((*mi).first);
4887 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4888 if ( miSelf == mapBlockIndex.end() )
4890 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4893 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4897 pindex = AddToBlockIndex(*pblock);
4898 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4902 miSelf->second = pindex;
4903 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4904 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4906 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4908 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4909 if ( miSelf == mapBlockIndex.end() )
4910 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4911 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4913 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4915 if ( previndex == 0 )
4916 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4917 if ( previndex != 0 )
4919 miSelf->second = previndex;
4920 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4921 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4923 } else LogPrintf("komodo_ensure unexpected null miprev\n");
4929 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
4931 // Preliminary checks
4932 bool checked; uint256 hash; int32_t futureblock=0;
4933 auto verifier = libzcash::ProofVerifier::Disabled();
4934 hash = pblock->GetHash();
4935 //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
4938 if ( chainActive.LastTip() != 0 )
4939 komodo_currentheight_set(chainActive.LastTip()->GetHeight());
4940 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
4941 bool fRequested = MarkBlockAsReceived(hash);
4942 fRequested |= fForceProcessing;
4943 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
4946 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
4948 if (!checked && futureblock == 0)
4952 Misbehaving(pfrom->GetId(), 1);
4954 return error("%s: CheckBlock FAILED", __func__);
4957 CBlockIndex *pindex = NULL;
4960 // 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
4961 komodo_ensure(pblock, hash);
4963 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
4964 if (pindex && pfrom) {
4965 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
4968 if (!ret && futureblock == 0)
4969 return error("%s: AcceptBlock FAILED", __func__);
4970 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
4973 if (futureblock == 0 && !ActivateBestChain(state, pblock))
4974 return error("%s: ActivateBestChain failed", __func__);
4975 //fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
4980 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4982 AssertLockHeld(cs_main);
4983 assert(pindexPrev == chainActive.Tip());
4985 CCoinsViewCache viewNew(pcoinsTip);
4986 CBlockIndex indexDummy(block);
4987 indexDummy.pprev = pindexPrev;
4988 indexDummy.SetHeight(pindexPrev->GetHeight() + 1);
4989 // JoinSplit proofs are verified in ConnectBlock
4990 auto verifier = libzcash::ProofVerifier::Disabled();
4991 // NOTE: CheckBlockHeader is called by CheckBlock
4992 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4994 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
4997 int32_t futureblock;
4998 if (!CheckBlock(&futureblock,indexDummy.GetHeight(),0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
5000 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
5003 if (!ContextualCheckBlock(block, state, pindexPrev))
5005 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
5008 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
5010 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
5013 assert(state.IsValid());
5014 if ( futureblock != 0 )
5020 * BLOCK PRUNING CODE
5023 /* Calculate the amount of disk space the block & undo files currently use */
5024 uint64_t CalculateCurrentUsage()
5026 uint64_t retval = 0;
5027 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
5028 retval += file.nSize + file.nUndoSize;
5033 /* Prune a block file (modify associated database entries)*/
5034 void PruneOneBlockFile(const int fileNumber)
5036 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
5037 CBlockIndex* pindex = it->second;
5038 if (pindex->nFile == fileNumber) {
5039 pindex->nStatus &= ~BLOCK_HAVE_DATA;
5040 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
5042 pindex->nDataPos = 0;
5043 pindex->nUndoPos = 0;
5044 setDirtyBlockIndex.insert(pindex);
5046 // Prune from mapBlocksUnlinked -- any block we prune would have
5047 // to be downloaded again in order to consider its chain, at which
5048 // point it would be considered as a candidate for
5049 // mapBlocksUnlinked or setBlockIndexCandidates.
5050 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
5051 while (range.first != range.second) {
5052 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
5054 if (it->second == pindex) {
5055 mapBlocksUnlinked.erase(it);
5061 vinfoBlockFile[fileNumber].SetNull();
5062 setDirtyFileInfo.insert(fileNumber);
5066 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
5068 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
5069 CDiskBlockPos pos(*it, 0);
5070 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
5071 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
5072 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
5076 /* Calculate the block/rev files that should be deleted to remain under target*/
5077 void FindFilesToPrune(std::set<int>& setFilesToPrune)
5079 LOCK2(cs_main, cs_LastBlockFile);
5080 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
5083 if (chainActive.Tip()->GetHeight() <= Params().PruneAfterHeight()) {
5086 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->GetHeight() - MIN_BLOCKS_TO_KEEP;
5087 uint64_t nCurrentUsage = CalculateCurrentUsage();
5088 // We don't check to prune until after we've allocated new space for files
5089 // So we should leave a buffer under our target to account for another allocation
5090 // before the next pruning.
5091 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
5092 uint64_t nBytesToPrune;
5095 if (nCurrentUsage + nBuffer >= nPruneTarget) {
5096 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
5097 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
5099 if (vinfoBlockFile[fileNumber].nSize == 0)
5102 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
5105 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
5106 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
5109 PruneOneBlockFile(fileNumber);
5110 // Queue up the files for removal
5111 setFilesToPrune.insert(fileNumber);
5112 nCurrentUsage -= nBytesToPrune;
5117 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
5118 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
5119 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
5120 nLastBlockWeCanPrune, count);
5123 bool CheckDiskSpace(uint64_t nAdditionalBytes)
5125 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
5127 // Check for nMinDiskSpace bytes (currently 50MB)
5128 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
5129 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
5134 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
5136 static int32_t didinit[64];
5139 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5140 boost::filesystem::create_directories(path.parent_path());
5141 FILE* file = fopen(path.string().c_str(), "rb+");
5142 if (!file && !fReadOnly)
5143 file = fopen(path.string().c_str(), "wb+");
5145 LogPrintf("Unable to open file %s\n", path.string());
5148 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
5150 komodo_prefetch(file);
5151 didinit[pos.nFile] = 1;
5154 if (fseek(file, pos.nPos, SEEK_SET)) {
5155 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5163 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
5164 return OpenDiskFile(pos, "blk", fReadOnly);
5167 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5168 return OpenDiskFile(pos, "rev", fReadOnly);
5171 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
5173 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
5176 CBlockIndex * InsertBlockIndex(uint256 hash)
5182 BlockMap::iterator mi = mapBlockIndex.find(hash);
5183 if (mi != mapBlockIndex.end())
5184 return (*mi).second;
5187 CBlockIndex* pindexNew = new CBlockIndex();
5189 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
5190 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
5191 pindexNew->phashBlock = &((*mi).first);
5192 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
5197 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
5199 bool static LoadBlockIndexDB()
5201 const CChainParams& chainparams = Params();
5202 LogPrintf("%s: start loading guts\n", __func__);
5203 if (!pblocktree->LoadBlockIndexGuts())
5205 LogPrintf("%s: loaded guts\n", __func__);
5206 boost::this_thread::interruption_point();
5208 // Calculate chainPower
5209 vector<pair<int, CBlockIndex*> > vSortedByHeight;
5210 vSortedByHeight.reserve(mapBlockIndex.size());
5211 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5213 CBlockIndex* pindex = item.second;
5214 vSortedByHeight.push_back(make_pair(pindex->GetHeight(), pindex));
5215 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5217 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
5218 sort(vSortedByHeight.begin(), vSortedByHeight.end());
5219 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
5220 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
5222 CBlockIndex* pindex = item.second;
5223 pindex->chainPower = (pindex->pprev ? CChainPower(pindex) + pindex->pprev->chainPower : CChainPower(pindex)) + GetBlockProof(*pindex);
5224 // We can link the chain of blocks for which we've received transactions at some point.
5225 // Pruned nodes may have deleted the block.
5226 if (pindex->nTx > 0) {
5227 if (pindex->pprev) {
5228 if (pindex->pprev->nChainTx) {
5229 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
5230 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
5231 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
5233 pindex->nChainSproutValue = boost::none;
5235 if (pindex->pprev->nChainSaplingValue) {
5236 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
5238 pindex->nChainSaplingValue = boost::none;
5241 pindex->nChainTx = 0;
5242 pindex->nChainSproutValue = boost::none;
5243 pindex->nChainSaplingValue = boost::none;
5244 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
5247 pindex->nChainTx = pindex->nTx;
5248 pindex->nChainSproutValue = pindex->nSproutValue;
5249 pindex->nChainSaplingValue = pindex->nSaplingValue;
5252 // Construct in-memory chain of branch IDs.
5253 // Relies on invariant: a block that does not activate a network upgrade
5254 // will always be valid under the same consensus rules as its parent.
5255 // Genesis block has a branch ID of zero by definition, but has no
5256 // validity status because it is side-loaded into a fresh chain.
5257 // Activation blocks will have branch IDs set (read from disk).
5258 if (pindex->pprev) {
5259 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
5260 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
5263 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
5265 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
5266 setBlockIndexCandidates.insert(pindex);
5267 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->chainPower > pindexBestInvalid->chainPower))
5268 pindexBestInvalid = pindex;
5270 pindex->BuildSkip();
5271 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
5272 pindexBestHeader = pindex;
5273 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5275 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
5277 // Load block file info
5278 pblocktree->ReadLastBlockFile(nLastBlockFile);
5279 vinfoBlockFile.resize(nLastBlockFile + 1);
5280 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
5281 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
5282 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
5284 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
5285 for (int nFile = nLastBlockFile + 1; true; nFile++) {
5286 CBlockFileInfo info;
5287 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
5288 vinfoBlockFile.push_back(info);
5294 // Check presence of blk files
5295 LogPrintf("Checking all blk files are present...\n");
5296 set<int> setBlkDataFiles;
5297 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5299 CBlockIndex* pindex = item.second;
5300 if (pindex->nStatus & BLOCK_HAVE_DATA) {
5301 setBlkDataFiles.insert(pindex->nFile);
5303 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5305 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
5306 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
5308 CDiskBlockPos pos(*it, 0);
5309 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
5314 // Check whether we have ever pruned block & undo files
5315 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
5317 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
5319 // Check whether we need to continue reindexing
5320 bool fReindexing = false;
5321 pblocktree->ReadReindexing(fReindexing);
5322 fReindex |= fReindexing;
5324 // Check whether we have a transaction index
5325 pblocktree->ReadFlag("txindex", fTxIndex);
5326 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
5327 // Check whether we have an address index
5328 pblocktree->ReadFlag("addressindex", fAddressIndex);
5329 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
5331 // Check whether we have a timestamp index
5332 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
5333 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
5335 // Check whether we have a spent index
5336 pblocktree->ReadFlag("spentindex", fSpentIndex);
5337 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
5339 // Fill in-memory data
5340 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5342 CBlockIndex* pindex = item.second;
5343 // - This relationship will always be true even if pprev has multiple
5344 // children, because hashSproutAnchor is technically a property of pprev,
5345 // not its children.
5346 // - This will miss chain tips; we handle the best tip below, and other
5347 // tips will be handled by ConnectTip during a re-org.
5348 if (pindex->pprev) {
5349 pindex->pprev->hashFinalSproutRoot = pindex->hashSproutAnchor;
5351 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5354 // Load pointer to end of best chain
5355 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
5356 if (it == mapBlockIndex.end())
5359 chainActive.SetTip(it->second);
5361 // Set hashFinalSproutRoot for the end of best chain
5362 it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT);
5364 PruneBlockIndexCandidates();
5367 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
5368 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
5370 int32_t longestchain = komodo_longestchain();
5371 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
5372 // runs, which makes it return 0, so we guess 50% for now
5373 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
5376 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
5377 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
5378 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
5381 EnforceNodeDeprecation(chainActive.Height(), true);
5386 CVerifyDB::CVerifyDB()
5388 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
5391 CVerifyDB::~CVerifyDB()
5393 uiInterface.ShowProgress("", 100);
5396 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
5399 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
5402 // Verify blocks in the best chain
5403 if (nCheckDepth <= 0)
5404 nCheckDepth = 1000000000; // suffices until the year 19000
5405 if (nCheckDepth > chainActive.Height())
5406 nCheckDepth = chainActive.Height();
5407 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
5408 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
5409 CCoinsViewCache coins(coinsview);
5410 CBlockIndex* pindexState = chainActive.Tip();
5411 CBlockIndex* pindexFailure = NULL;
5412 int nGoodTransactions = 0;
5413 CValidationState state;
5414 // No need to verify JoinSplits twice
5415 auto verifier = libzcash::ProofVerifier::Disabled();
5416 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
5417 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
5419 boost::this_thread::interruption_point();
5420 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
5421 if (pindex->GetHeight() < chainActive.Height()-nCheckDepth)
5424 // check level 0: read from disk
5425 if (!ReadBlockFromDisk(block, pindex,0))
5426 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5427 // check level 1: verify block validity
5428 int32_t futureblock;
5429 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, verifier,0) )
5430 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5431 // check level 2: verify undo validity
5432 if (nCheckLevel >= 2 && pindex) {
5434 CDiskBlockPos pos = pindex->GetUndoPos();
5435 if (!pos.IsNull()) {
5436 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5437 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5440 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
5441 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
5443 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5444 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5445 pindexState = pindex->pprev;
5447 nGoodTransactions = 0;
5448 pindexFailure = pindex;
5450 nGoodTransactions += block.vtx.size();
5452 if (ShutdownRequested())
5455 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
5457 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->GetHeight() + 1, nGoodTransactions);
5459 // check level 4: try reconnecting blocks
5460 if (nCheckLevel >= 4) {
5461 CBlockIndex *pindex = pindexState;
5462 while (pindex != chainActive.Tip()) {
5463 boost::this_thread::interruption_point();
5464 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * 50))));
5465 pindex = chainActive.Next(pindex);
5467 if (!ReadBlockFromDisk(block, pindex,0))
5468 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5469 if (!ConnectBlock(block, state, pindex, coins,false, true))
5470 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5474 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions);
5479 bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches)
5483 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
5484 // index will have nCachedBranchId set based on the values previously persisted
5485 // to disk. By definition, a set nCachedBranchId means that the block was
5486 // fully-validated under the corresponding consensus rules. Thus we can quickly
5487 // identify whether the current active chain matches our expected sequence of
5488 // consensus rule changes, with two checks:
5490 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
5491 // - nCachedBranchId for each block matches what we expect.
5492 auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) {
5493 auto consensus = params.GetConsensus();
5494 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5495 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->GetHeight(), consensus);
5496 return fFlagSet == fFlagExpected &&
5497 pindex->nCachedBranchId &&
5498 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->GetHeight(), consensus);
5502 while (nHeight <= chainActive.Height()) {
5503 if (!sufficientlyValidated(chainActive[nHeight])) {
5509 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
5510 auto rewindLength = chainActive.Height() - nHeight;
5511 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH)
5513 auto pindexOldTip = chainActive.Tip();
5514 auto pindexRewind = chainActive[nHeight - 1];
5515 auto msg = strprintf(_(
5516 "A block chain rewind has been detected that would roll back %d blocks! "
5517 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5518 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5519 _("Rewind details") + ":\n" +
5520 "- " + strprintf(_("Current tip: %s, height %d"),
5521 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight()) + "\n" +
5522 "- " + strprintf(_("Rewinding to: %s, height %d"),
5523 pindexRewind->phashBlock->GetHex(), pindexRewind->GetHeight()) + "\n\n" +
5524 _("Please help, human!");
5525 LogPrintf("*** %s\n", msg);
5526 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5531 CValidationState state;
5532 CBlockIndex* pindex = chainActive.Tip();
5533 while (chainActive.Height() >= nHeight) {
5534 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5535 // If pruning, don't try rewinding past the HAVE_DATA point;
5536 // since older blocks can't be served anyway, there's
5537 // no need to walk further, and trying to DisconnectTip()
5538 // will fail (and require a needless reindex/redownload
5539 // of the blockchain).
5542 if (!DisconnectTip(state, true)) {
5543 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->GetHeight());
5545 // Occasionally flush state to disk.
5546 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5550 // Reduce validity flag and have-data flags.
5552 // Collect blocks to be removed (blocks in mapBlockIndex must be at least BLOCK_VALID_TREE).
5553 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5554 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5555 std::vector<const CBlockIndex*> vBlocks;
5556 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5557 CBlockIndex* pindexIter = it->second;
5559 // Note: If we encounter an insufficiently validated block that
5560 // is on chainActive, it must be because we are a pruning node, and
5561 // this block or some successor doesn't HAVE_DATA, so we were unable to
5562 // rewind all the way. Blocks remaining on chainActive at this point
5563 // must not have their validity reduced.
5564 if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
5566 pindexIter->nStatus =
5567 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5568 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
5569 // Remove have-data flags
5570 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
5572 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
5573 pindexIter->nCachedBranchId = boost::none;
5574 // Remove storage location
5575 pindexIter->nFile = 0;
5576 pindexIter->nDataPos = 0;
5577 pindexIter->nUndoPos = 0;
5578 // Remove various other things
5579 pindexIter->nTx = 0;
5580 pindexIter->nChainTx = 0;
5581 pindexIter->nSproutValue = boost::none;
5582 pindexIter->nChainSproutValue = boost::none;
5583 pindexIter->nSaplingValue = 0;
5584 pindexIter->nChainSaplingValue = boost::none;
5585 pindexIter->nSequenceId = 0;
5587 // Make sure it gets written
5588 /* corresponds to commented out block below as an alternative to setDirtyBlockIndex
5589 vBlocks.push_back(pindexIter);
5591 setDirtyBlockIndex.insert(pindexIter);
5592 if (pindexIter == pindexBestInvalid)
5594 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
5595 pindexBestInvalid = NULL;
5599 setBlockIndexCandidates.erase(pindexIter);
5600 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
5601 while (ret.first != ret.second) {
5602 if (ret.first->second == pindexIter) {
5603 mapBlocksUnlinked.erase(ret.first++);
5608 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5609 setBlockIndexCandidates.insert(pindexIter);
5614 // Set pindexBestHeader to the current chain tip
5615 // (since we are about to delete the block it is pointing to)
5616 pindexBestHeader = chainActive.Tip();
5618 // Erase block indices on-disk
5619 if (!pblocktree->EraseBatchSync(vBlocks)) {
5620 return AbortNode(state, "Failed to erase from block index database");
5623 // Erase block indices in-memory
5624 for (auto pindex : vBlocks) {
5625 auto ret = mapBlockIndex.find(*pindex->phashBlock);
5626 if (ret != mapBlockIndex.end()) {
5627 mapBlockIndex.erase(ret);
5633 PruneBlockIndexCandidates();
5637 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5644 void UnloadBlockIndex()
5647 setBlockIndexCandidates.clear();
5648 chainActive.SetTip(NULL);
5649 pindexBestInvalid = NULL;
5650 pindexBestHeader = NULL;
5652 mapOrphanTransactions.clear();
5653 mapOrphanTransactionsByPrev.clear();
5655 mapBlocksUnlinked.clear();
5656 vinfoBlockFile.clear();
5658 nBlockSequenceId = 1;
5659 mapBlockSource.clear();
5660 mapBlocksInFlight.clear();
5661 nQueuedValidatedHeaders = 0;
5662 nPreferredDownload = 0;
5663 setDirtyBlockIndex.clear();
5664 setDirtyFileInfo.clear();
5665 mapNodeState.clear();
5666 recentRejects.reset(NULL);
5668 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5669 delete entry.second;
5671 mapBlockIndex.clear();
5672 fHavePruned = false;
5675 bool LoadBlockIndex()
5677 // Load block index from databases
5678 KOMODO_LOADINGBLOCKS = 1;
5679 if (!fReindex && !LoadBlockIndexDB())
5681 KOMODO_LOADINGBLOCKS = 0;
5684 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5689 bool InitBlockIndex() {
5690 const CChainParams& chainparams = Params();
5693 // Initialize global variables that cannot be constructed at startup.
5694 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5695 // Check whether we're already initialized
5696 if (chainActive.Genesis() != NULL)
5700 // Use the provided setting for -txindex in the new database
5701 fTxIndex = GetBoolArg("-txindex", true);
5702 pblocktree->WriteFlag("txindex", fTxIndex);
5703 // Use the provided setting for -addressindex in the new database
5704 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5705 pblocktree->WriteFlag("addressindex", fAddressIndex);
5707 // Use the provided setting for -timestampindex in the new database
5708 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5709 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5711 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5712 pblocktree->WriteFlag("spentindex", fSpentIndex);
5713 fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
5714 LogPrintf("Initializing databases...\n");
5716 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5719 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5720 // Start new block file
5721 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5722 CDiskBlockPos blockPos;
5723 CValidationState state;
5724 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5725 return error("LoadBlockIndex(): FindBlockPos failed");
5726 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5727 return error("LoadBlockIndex(): writing genesis block to disk failed");
5728 CBlockIndex *pindex = AddToBlockIndex(block);
5730 return error("LoadBlockIndex(): couldnt add to block index");
5731 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5732 return error("LoadBlockIndex(): genesis block not accepted");
5733 if (!ActivateBestChain(state, &block))
5734 return error("LoadBlockIndex(): genesis block cannot be activated");
5735 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5736 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5737 } catch (const std::runtime_error& e) {
5738 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5747 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5749 const CChainParams& chainparams = Params();
5750 // Map of disk positions for blocks with unknown parent (only used for reindex)
5751 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5752 int64_t nStart = GetTimeMillis();
5756 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5757 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5758 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5759 uint64_t nRewind = blkdat.GetPos();
5760 while (!blkdat.eof()) {
5761 boost::this_thread::interruption_point();
5763 blkdat.SetPos(nRewind);
5764 nRewind++; // start one byte further next time, in case of failure
5765 blkdat.SetLimit(); // remove former limit
5766 unsigned int nSize = 0;
5769 unsigned char buf[MESSAGE_START_SIZE];
5770 blkdat.FindByte(Params().MessageStart()[0]);
5771 nRewind = blkdat.GetPos()+1;
5772 blkdat >> FLATDATA(buf);
5773 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5777 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5779 } catch (const std::exception&) {
5780 // no valid block header found; don't complain
5785 uint64_t nBlockPos = blkdat.GetPos();
5787 dbp->nPos = nBlockPos;
5788 blkdat.SetLimit(nBlockPos + nSize);
5789 blkdat.SetPos(nBlockPos);
5792 nRewind = blkdat.GetPos();
5794 // detect out of order blocks, and store them for later
5795 uint256 hash = block.GetHash();
5796 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5797 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5798 block.hashPrevBlock.ToString());
5800 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5804 // process in case the block isn't known yet
5805 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5806 CValidationState state;
5807 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5809 if (state.IsError())
5811 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->GetHeight() % 1000 == 0) {
5812 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->GetHeight());
5815 // Recursively process earlier encountered successors of this block
5816 deque<uint256> queue;
5817 queue.push_back(hash);
5818 while (!queue.empty()) {
5819 uint256 head = queue.front();
5821 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5822 while (range.first != range.second) {
5823 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5824 if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->GetHeight():0,block, it->second,1))
5826 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5828 CValidationState dummy;
5829 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5832 queue.push_back(block.GetHash());
5836 mapBlocksUnknownParent.erase(it);
5839 } catch (const std::exception& e) {
5840 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5843 } catch (const std::runtime_error& e) {
5844 AbortNode(std::string("System error: ") + e.what());
5847 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5851 void static CheckBlockIndex()
5853 const Consensus::Params& consensusParams = Params().GetConsensus();
5854 if (!fCheckBlockIndex) {
5860 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5861 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5862 // iterating the block tree require that chainActive has been initialized.)
5863 if (chainActive.Height() < 0) {
5864 assert(mapBlockIndex.size() <= 1);
5868 // Build forward-pointing map of the entire block tree.
5869 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5870 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5871 if ( it->second != 0 )
5872 forward.insert(std::make_pair(it->second->pprev, it->second));
5874 if ( Params().NetworkIDString() != "regtest" )
5875 assert(forward.size() == mapBlockIndex.size());
5877 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5878 CBlockIndex *pindex = rangeGenesis.first->second;
5879 rangeGenesis.first++;
5880 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5882 // Iterate over the entire block tree, using depth-first search.
5883 // Along the way, remember whether there are blocks on the path from genesis
5884 // block being explored which are the first to have certain properties.
5887 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5888 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5889 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5890 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5891 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5892 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5893 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5894 while (pindex != NULL) {
5896 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5897 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5898 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5899 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5900 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5901 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5902 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5904 // Begin: actual consistency checks.
5905 if (pindex->pprev == NULL) {
5906 // Genesis block checks.
5907 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5908 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5910 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
5911 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5912 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5914 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5915 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5916 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5918 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5919 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5921 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5922 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5923 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5924 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5925 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5926 assert(pindex->GetHeight() == nHeight); // nHeight must be consistent.
5927 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.
5928 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->GetHeight() < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5929 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5930 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5931 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5932 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5933 if (pindexFirstInvalid == NULL) {
5934 // Checks for not-invalid blocks.
5935 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5937 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5938 if (pindexFirstInvalid == NULL) {
5939 // If this block sorts at least as good as the current tip and
5940 // is valid and we have all data for its parents, it must be in
5941 // setBlockIndexCandidates. chainActive.Tip() must also be there
5942 // even if some data has been pruned.
5943 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5944 assert(setBlockIndexCandidates.count(pindex));
5946 // If some parent is missing, then it could be that this block was in
5947 // setBlockIndexCandidates but had to be removed because of the missing data.
5948 // In this case it must be in mapBlocksUnlinked -- see test below.
5950 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
5951 assert(setBlockIndexCandidates.count(pindex) == 0);
5953 // Check whether this block is in mapBlocksUnlinked.
5954 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5955 bool foundInUnlinked = false;
5956 while (rangeUnlinked.first != rangeUnlinked.second) {
5957 assert(rangeUnlinked.first->first == pindex->pprev);
5958 if (rangeUnlinked.first->second == pindex) {
5959 foundInUnlinked = true;
5962 rangeUnlinked.first++;
5964 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5965 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5966 assert(foundInUnlinked);
5968 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5969 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5970 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5971 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5972 assert(fHavePruned); // We must have pruned.
5973 // This block may have entered mapBlocksUnlinked if:
5974 // - it has a descendant that at some point had more work than the
5976 // - we tried switching to that descendant but were missing
5977 // data for some intermediate block between chainActive and the
5979 // So if this block is itself better than chainActive.Tip() and it wasn't in
5980 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5981 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5982 if (pindexFirstInvalid == NULL) {
5983 assert(foundInUnlinked);
5987 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5988 // End: actual consistency checks.
5990 // Try descending into the first subnode.
5991 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5992 if (range.first != range.second) {
5993 // A subnode was found.
5994 pindex = range.first->second;
5998 // This is a leaf node.
5999 // Move upwards until we reach a node of which we have not yet visited the last child.
6001 // We are going to either move to a parent or a sibling of pindex.
6002 // If pindex was the first with a certain property, unset the corresponding variable.
6003 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
6004 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
6005 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
6006 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
6007 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
6008 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
6009 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
6011 CBlockIndex* pindexPar = pindex->pprev;
6012 // Find which child we just visited.
6013 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
6014 while (rangePar.first->second != pindex) {
6015 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
6018 // Proceed to the next one.
6020 if (rangePar.first != rangePar.second) {
6021 // Move to the sibling.
6022 pindex = rangePar.first->second;
6033 // Check that we actually traversed the entire map.
6034 assert(nNodes == forward.size());
6037 //////////////////////////////////////////////////////////////////////////////
6042 std::string GetWarnings(const std::string& strFor)
6045 string strStatusBar;
6048 if (!CLIENT_VERSION_IS_RELEASE)
6049 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
6051 if (GetBoolArg("-testsafemode", false))
6052 strStatusBar = strRPC = "testsafemode enabled";
6054 // Misc warnings like out of disk space and clock is wrong
6055 if (strMiscWarning != "")
6058 strStatusBar = strMiscWarning;
6061 if (fLargeWorkForkFound)
6064 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
6066 else if (fLargeWorkInvalidChainFound)
6069 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.");
6075 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6077 const CAlert& alert = item.second;
6078 if (alert.AppliesToMe() && alert.nPriority > nPriority)
6080 nPriority = alert.nPriority;
6081 strStatusBar = alert.strStatusBar;
6082 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
6083 strRPC = alert.strRPCError;
6089 if (strFor == "statusbar")
6090 return strStatusBar;
6091 else if (strFor == "rpc")
6093 assert(!"GetWarnings(): invalid parameter");
6104 //////////////////////////////////////////////////////////////////////////////
6110 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
6116 assert(recentRejects);
6117 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
6119 // If the chain tip has changed previously rejected transactions
6120 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
6121 // or a double-spend. Reset the rejects filter and give those
6122 // txs a second chance.
6123 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
6124 recentRejects->reset();
6127 return recentRejects->contains(inv.hash) ||
6128 mempool.exists(inv.hash) ||
6129 mapOrphanTransactions.count(inv.hash) ||
6130 pcoinsTip->HaveCoins(inv.hash);
6133 return mapBlockIndex.count(inv.hash);
6135 // Don't know what it is, just say we already got one
6139 void static ProcessGetData(CNode* pfrom)
6141 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
6143 vector<CInv> vNotFound;
6147 while (it != pfrom->vRecvGetData.end()) {
6148 // Don't bother if send buffer is too full to respond anyway
6149 if (pfrom->nSendSize >= SendBufferSize())
6152 const CInv &inv = *it;
6154 boost::this_thread::interruption_point();
6157 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6160 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
6161 if (mi != mapBlockIndex.end())
6163 if (chainActive.Contains(mi->second)) {
6166 static const int nOneMonth = 30 * 24 * 60 * 60;
6167 // To prevent fingerprinting attacks, only send blocks outside of the active
6168 // chain if they are valid, and no more than a month older (both in time, and in
6169 // best equivalent proof of work) than the best header chain we know about.
6170 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
6171 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
6172 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
6174 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
6178 // Pruned nodes may have deleted the block, so check whether
6179 // it's available before trying to send.
6180 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
6182 // Send block from disk
6184 if (!ReadBlockFromDisk(block, (*mi).second,1))
6186 assert(!"cannot load block from disk");
6190 if (inv.type == MSG_BLOCK)
6192 //uint256 hash; int32_t z;
6193 //hash = block.GetHash();
6194 //for (z=31; z>=0; z--)
6195 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
6196 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
6197 pfrom->PushMessage("block", block);
6199 else // MSG_FILTERED_BLOCK)
6201 LOCK(pfrom->cs_filter);
6204 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
6205 pfrom->PushMessage("merkleblock", merkleBlock);
6206 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
6207 // This avoids hurting performance by pointlessly requiring a round-trip
6208 // Note that there is currently no way for a node to request any single transactions we didn't send here -
6209 // they must either disconnect and retry or request the full block.
6210 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
6211 // however we MUST always provide at least what the remote peer needs
6212 typedef std::pair<unsigned int, uint256> PairType;
6213 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
6214 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
6215 pfrom->PushMessage("tx", block.vtx[pair.first]);
6221 // Trigger the peer node to send a getblocks request for the next batch of inventory
6222 if (inv.hash == pfrom->hashContinue)
6224 // Bypass PushInventory, this must send even if redundant,
6225 // and we want it right after the last block so they don't
6226 // wait for other stuff first.
6228 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
6229 pfrom->PushMessage("inv", vInv);
6230 pfrom->hashContinue.SetNull();
6234 else if (inv.IsKnownType())
6236 // Send stream from relay memory
6237 bool pushed = false;
6240 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
6241 if (mi != mapRelay.end()) {
6242 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
6246 if (!pushed && inv.type == MSG_TX) {
6248 if (mempool.lookup(inv.hash, tx)) {
6249 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
6252 pfrom->PushMessage("tx", ss);
6257 vNotFound.push_back(inv);
6261 // Track requests for our stuff.
6262 GetMainSignals().Inventory(inv.hash);
6264 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6269 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
6271 if (!vNotFound.empty()) {
6272 // Let the peer know that we didn't find what it asked for, so it doesn't
6273 // have to wait around forever. Currently only SPV clients actually care
6274 // about this message: it's needed when they are recursively walking the
6275 // dependencies of relevant unconfirmed transactions. SPV clients want to
6276 // do that because they want to know about (and store and rebroadcast and
6277 // risk analyze) the dependencies of transactions relevant to them, without
6278 // having to download the entire memory pool.
6279 pfrom->PushMessage("notfound", vNotFound);
6283 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
6285 const CChainParams& chainparams = Params();
6286 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
6287 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
6288 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
6290 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
6294 if (strCommand == "version")
6296 // Each connection can only send one version message
6297 if (pfrom->nVersion != 0)
6299 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
6300 Misbehaving(pfrom->GetId(), 1);
6307 uint64_t nNonce = 1;
6308 int nVersion; // use temporary for version, don't set version number until validated as connected
6309 vRecv >> nVersion >> pfrom->nServices >> nTime >> addrMe;
6310 if (nVersion == 10300)
6313 if (nVersion < MIN_PEER_PROTO_VERSION)
6315 // disconnect from peers older than this proto version
6316 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6317 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6318 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
6319 pfrom->fDisconnect = true;
6323 // Reject incoming connections from nodes that don't know about the current epoch
6324 const Consensus::Params& params = Params().GetConsensus();
6325 auto currentEpoch = CurrentEpoch(GetHeight(), params);
6326 if (nVersion < params.vUpgrades[currentEpoch].nProtocolVersion)
6328 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion);
6329 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6330 strprintf("Version must be %d or greater",
6331 params.vUpgrades[currentEpoch].nProtocolVersion));
6332 pfrom->fDisconnect = true;
6337 vRecv >> addrFrom >> nNonce;
6338 if (!vRecv.empty()) {
6339 vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
6340 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
6343 vRecv >> pfrom->nStartingHeight;
6345 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
6347 pfrom->fRelayTxes = true;
6349 // Disconnect if we connected to ourself
6350 if (nNonce == nLocalHostNonce && nNonce > 1)
6352 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
6353 pfrom->fDisconnect = true;
6357 pfrom->nVersion = nVersion;
6359 pfrom->addrLocal = addrMe;
6360 if (pfrom->fInbound && addrMe.IsRoutable())
6365 // Be shy and don't send version until we hear
6366 if (pfrom->fInbound)
6367 pfrom->PushVersion();
6369 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
6371 // Potentially mark this peer as a preferred download peer.
6372 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
6375 pfrom->PushMessage("verack");
6376 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6378 if (!pfrom->fInbound)
6380 // Advertise our address
6381 if (fListen && !IsInitialBlockDownload())
6383 CAddress addr = GetLocalAddress(&pfrom->addr);
6384 if (addr.IsRoutable())
6386 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6387 pfrom->PushAddress(addr);
6388 } else if (IsPeerAddrLocalGood(pfrom)) {
6389 addr.SetIP(pfrom->addrLocal);
6390 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6391 pfrom->PushAddress(addr);
6395 // Get recent addresses
6396 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
6398 pfrom->PushMessage("getaddr");
6399 pfrom->fGetAddr = true;
6401 addrman.Good(pfrom->addr);
6403 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
6405 addrman.Add(addrFrom, addrFrom);
6406 addrman.Good(addrFrom);
6413 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6414 item.second.RelayTo(pfrom);
6417 pfrom->fSuccessfullyConnected = true;
6421 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
6423 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
6424 pfrom->cleanSubVer, pfrom->nVersion,
6425 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
6428 int64_t nTimeOffset = nTime - GetTime();
6429 pfrom->nTimeOffset = nTimeOffset;
6430 AddTimeData(pfrom->addr, nTimeOffset);
6434 else if (pfrom->nVersion == 0)
6436 // Must have a version message before anything else
6437 Misbehaving(pfrom->GetId(), 1);
6442 else if (strCommand == "verack")
6444 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6446 // Mark this node as currently connected, so we update its timestamp later.
6447 if (pfrom->fNetworkNode) {
6449 State(pfrom->GetId())->fCurrentlyConnected = true;
6454 // Disconnect existing peer connection when:
6455 // 1. The version message has been received
6456 // 2. Peer version is below the minimum version for the current epoch
6457 else if (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[
6458 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion)
6460 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6461 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6462 strprintf("Version must be %d or greater",
6463 chainparams.GetConsensus().vUpgrades[
6464 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion));
6465 pfrom->fDisconnect = true;
6470 else if (strCommand == "addr")
6472 vector<CAddress> vAddr;
6475 // Don't want addr from older versions unless seeding
6476 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
6478 if (vAddr.size() > 1000)
6480 Misbehaving(pfrom->GetId(), 20);
6481 return error("message addr size() = %u", vAddr.size());
6484 // Store the new addresses
6485 vector<CAddress> vAddrOk;
6486 int64_t nNow = GetAdjustedTime();
6487 int64_t nSince = nNow - 10 * 60;
6488 BOOST_FOREACH(CAddress& addr, vAddr)
6490 boost::this_thread::interruption_point();
6492 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6493 addr.nTime = nNow - 5 * 24 * 60 * 60;
6494 pfrom->AddAddressKnown(addr);
6495 bool fReachable = IsReachable(addr);
6496 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
6498 // Relay to a limited number of other nodes
6501 // Use deterministic randomness to send to the same nodes for 24 hours
6502 // at a time so the addrKnowns of the chosen nodes prevent repeats
6503 static uint256 hashSalt;
6504 if (hashSalt.IsNull())
6505 hashSalt = GetRandHash();
6506 uint64_t hashAddr = addr.GetHash();
6507 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
6508 hashRand = Hash(BEGIN(hashRand), END(hashRand));
6509 multimap<uint256, CNode*> mapMix;
6510 BOOST_FOREACH(CNode* pnode, vNodes)
6512 if (pnode->nVersion < CADDR_TIME_VERSION)
6514 unsigned int nPointer;
6515 memcpy(&nPointer, &pnode, sizeof(nPointer));
6516 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
6517 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6518 mapMix.insert(make_pair(hashKey, pnode));
6520 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
6521 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6522 ((*mi).second)->PushAddress(addr);
6525 // Do not store addresses outside our network
6527 vAddrOk.push_back(addr);
6529 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
6530 if (vAddr.size() < 1000)
6531 pfrom->fGetAddr = false;
6532 if (pfrom->fOneShot)
6533 pfrom->fDisconnect = true;
6537 else if (strCommand == "inv")
6541 if (vInv.size() > MAX_INV_SZ)
6543 Misbehaving(pfrom->GetId(), 20);
6544 return error("message inv size() = %u", vInv.size());
6549 std::vector<CInv> vToFetch;
6551 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
6553 const CInv &inv = vInv[nInv];
6555 boost::this_thread::interruption_point();
6556 pfrom->AddInventoryKnown(inv);
6558 bool fAlreadyHave = AlreadyHave(inv);
6559 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
6561 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6564 if (inv.type == MSG_BLOCK) {
6565 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
6566 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
6567 // First request the headers preceding the announced block. In the normal fully-synced
6568 // case where a new block is announced that succeeds the current tip (no reorganization),
6569 // there are no such headers.
6570 // Secondly, and only when we are close to being synced, we request the announced block directly,
6571 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6572 // time the block arrives, the header chain leading up to it is already validated. Not
6573 // doing this will result in the received block being rejected as an orphan in case it is
6574 // not a direct successor.
6575 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
6576 CNodeState *nodestate = State(pfrom->GetId());
6577 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
6578 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6579 vToFetch.push_back(inv);
6580 // Mark block as in flight already, even though the actual "getdata" message only goes out
6581 // later (within the same cs_main lock, though).
6582 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
6584 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->GetHeight(), inv.hash.ToString(), pfrom->id);
6588 // Track requests for our stuff
6589 GetMainSignals().Inventory(inv.hash);
6591 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6592 Misbehaving(pfrom->GetId(), 50);
6593 return error("send buffer size() = %u", pfrom->nSendSize);
6597 if (!vToFetch.empty())
6598 pfrom->PushMessage("getdata", vToFetch);
6602 else if (strCommand == "getdata")
6606 if (vInv.size() > MAX_INV_SZ)
6608 Misbehaving(pfrom->GetId(), 20);
6609 return error("message getdata size() = %u", vInv.size());
6612 if (fDebug || (vInv.size() != 1))
6613 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
6615 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
6616 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
6618 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6619 ProcessGetData(pfrom);
6623 else if (strCommand == "getblocks")
6625 CBlockLocator locator;
6627 vRecv >> locator >> hashStop;
6631 // Find the last block the caller has in the main chain
6632 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
6634 // Send the rest of the chain
6636 pindex = chainActive.Next(pindex);
6638 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
6639 for (; pindex; pindex = chainActive.Next(pindex))
6641 if (pindex->GetBlockHash() == hashStop)
6643 LogPrint("net", " getblocks stopping at %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6646 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6649 // When this block is requested, we'll send an inv that'll
6650 // trigger the peer to getblocks the next batch of inventory.
6651 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6652 pfrom->hashContinue = pindex->GetBlockHash();
6659 else if (strCommand == "getheaders")
6661 CBlockLocator locator;
6663 vRecv >> locator >> hashStop;
6667 if (IsInitialBlockDownload())
6670 CBlockIndex* pindex = NULL;
6671 if (locator.IsNull())
6673 // If locator is null, return the hashStop block
6674 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6675 if (mi == mapBlockIndex.end())
6677 pindex = (*mi).second;
6681 // Find the last block the caller has in the main chain
6682 pindex = FindForkInGlobalIndex(chainActive, locator);
6684 pindex = chainActive.Next(pindex);
6687 // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6688 vector<CNetworkBlockHeader> vHeaders;
6689 int nLimit = MAX_HEADERS_RESULTS;
6690 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.ToString(), pfrom->id);
6691 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->GetHeight() : -1) )// no need to ever suppress this
6693 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->GetHeight() : -1);
6694 for (; pindex; pindex = chainActive.Next(pindex))
6696 CBlockHeader h = pindex->GetBlockHeader();
6697 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6698 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
6699 vHeaders.push_back(pindex->GetBlockHeader());
6700 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6703 pfrom->PushMessage("headers", vHeaders);
6705 /*else if ( IS_KOMODO_NOTARY != 0 )
6707 static uint32_t counter;
6708 if ( counter++ < 3 )
6709 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);
6714 else if (strCommand == "tx")
6716 vector<uint256> vWorkQueue;
6717 vector<uint256> vEraseQueue;
6721 CInv inv(MSG_TX, tx.GetHash());
6722 pfrom->AddInventoryKnown(inv);
6726 bool fMissingInputs = false;
6727 CValidationState state;
6729 pfrom->setAskFor.erase(inv.hash);
6730 mapAlreadyAskedFor.erase(inv);
6732 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6734 mempool.check(pcoinsTip);
6735 RelayTransaction(tx);
6736 vWorkQueue.push_back(inv.hash);
6738 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6739 pfrom->id, pfrom->cleanSubVer,
6740 tx.GetHash().ToString(),
6741 mempool.mapTx.size());
6743 // Recursively process any orphan transactions that depended on this one
6744 set<NodeId> setMisbehaving;
6745 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6747 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6748 if (itByPrev == mapOrphanTransactionsByPrev.end())
6750 for (set<uint256>::iterator mi = itByPrev->second.begin();
6751 mi != itByPrev->second.end();
6754 const uint256& orphanHash = *mi;
6755 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6756 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6757 bool fMissingInputs2 = false;
6758 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6759 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6760 // anyone relaying LegitTxX banned)
6761 CValidationState stateDummy;
6764 if (setMisbehaving.count(fromPeer))
6766 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6768 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
6769 RelayTransaction(orphanTx);
6770 vWorkQueue.push_back(orphanHash);
6771 vEraseQueue.push_back(orphanHash);
6773 else if (!fMissingInputs2)
6776 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6778 // Punish peer that gave us an invalid orphan tx
6779 Misbehaving(fromPeer, nDos);
6780 setMisbehaving.insert(fromPeer);
6781 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6783 // Has inputs but not accepted to mempool
6784 // Probably non-standard or insufficient fee/priority
6785 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
6786 vEraseQueue.push_back(orphanHash);
6787 assert(recentRejects);
6788 recentRejects->insert(orphanHash);
6790 mempool.check(pcoinsTip);
6794 BOOST_FOREACH(uint256 hash, vEraseQueue)
6795 EraseOrphanTx(hash);
6797 // TODO: currently, prohibit joinsplits from entering mapOrphans
6798 else if (fMissingInputs && tx.vjoinsplit.size() == 0)
6800 AddOrphanTx(tx, pfrom->GetId());
6802 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6803 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6804 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6806 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6808 assert(recentRejects);
6809 recentRejects->insert(tx.GetHash());
6811 if (pfrom->fWhitelisted) {
6812 // Always relay transactions received from whitelisted peers, even
6813 // if they were already in the mempool or rejected from it due
6814 // to policy, allowing the node to function as a gateway for
6815 // nodes hidden behind it.
6817 // Never relay transactions that we would assign a non-zero DoS
6818 // score for, as we expect peers to do the same with us in that
6821 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6822 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6823 RelayTransaction(tx);
6825 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6826 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6831 if (state.IsInvalid(nDoS))
6833 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6834 pfrom->id, pfrom->cleanSubVer,
6835 state.GetRejectReason());
6836 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6837 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6839 Misbehaving(pfrom->GetId(), nDoS);
6843 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6845 std::vector<CBlockHeader> headers;
6847 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6848 unsigned int nCount = ReadCompactSize(vRecv);
6849 if (nCount > MAX_HEADERS_RESULTS) {
6850 Misbehaving(pfrom->GetId(), 20);
6851 return error("headers message size = %u", nCount);
6853 headers.resize(nCount);
6854 for (unsigned int n = 0; n < nCount; n++) {
6855 vRecv >> headers[n];
6856 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6862 // Nothing interesting. Stop asking this peers for more headers.
6866 CBlockIndex *pindexLast = NULL;
6867 BOOST_FOREACH(const CBlockHeader& header, headers) {
6868 //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6869 //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
6871 CValidationState state;
6872 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6873 Misbehaving(pfrom->GetId(), 20);
6874 return error("non-continuous headers sequence");
6876 int32_t futureblock;
6877 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6879 if (state.IsInvalid(nDoS) && futureblock == 0)
6881 if (nDoS > 0 && futureblock == 0)
6882 Misbehaving(pfrom->GetId(), nDoS/nDoS);
6883 return error("invalid header received");
6889 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6891 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6892 // Headers message had its maximum size; the peer may have more headers.
6893 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6894 // from there instead.
6895 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->GetHeight() != pfrom->sendhdrsreq )
6897 pfrom->sendhdrsreq = (int32_t)pindexLast->GetHeight();
6898 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->GetHeight(), pfrom->id, pfrom->nStartingHeight);
6899 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6906 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6911 CInv inv(MSG_BLOCK, block.GetHash());
6912 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6914 pfrom->AddInventoryKnown(inv);
6916 CValidationState state;
6917 // Process all blocks from whitelisted peers, even if not requested,
6918 // unless we're still syncing with the network.
6919 // Such an unrequested block may still be processed, subject to the
6920 // conditions in AcceptBlock().
6921 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6922 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
6924 if (state.IsInvalid(nDoS)) {
6925 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6926 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6929 Misbehaving(pfrom->GetId(), nDoS);
6936 // This asymmetric behavior for inbound and outbound connections was introduced
6937 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
6938 // to users' AddrMan and later request them by sending getaddr messages.
6939 // Making nodes which are behind NAT and can only make outgoing connections ignore
6940 // the getaddr message mitigates the attack.
6941 else if ((strCommand == "getaddr") && (pfrom->fInbound))
6943 // Only send one GetAddr response per connection to reduce resource waste
6944 // and discourage addr stamping of INV announcements.
6945 if (pfrom->fSentAddr) {
6946 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6949 pfrom->fSentAddr = true;
6951 pfrom->vAddrToSend.clear();
6952 vector<CAddress> vAddr = addrman.GetAddr();
6953 BOOST_FOREACH(const CAddress &addr, vAddr)
6954 pfrom->PushAddress(addr);
6958 else if (strCommand == "mempool")
6960 LOCK2(cs_main, pfrom->cs_filter);
6962 std::vector<uint256> vtxid;
6963 mempool.queryHashes(vtxid);
6965 BOOST_FOREACH(uint256& hash, vtxid) {
6966 CInv inv(MSG_TX, hash);
6967 if (pfrom->pfilter) {
6969 bool fInMemPool = mempool.lookup(hash, tx);
6970 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
6971 if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
6973 vInv.push_back(inv);
6974 if (vInv.size() == MAX_INV_SZ) {
6975 pfrom->PushMessage("inv", vInv);
6979 if (vInv.size() > 0)
6980 pfrom->PushMessage("inv", vInv);
6984 else if (strCommand == "ping")
6986 if (pfrom->nVersion > BIP0031_VERSION)
6990 // Echo the message back with the nonce. This allows for two useful features:
6992 // 1) A remote node can quickly check if the connection is operational
6993 // 2) Remote nodes can measure the latency of the network thread. If this node
6994 // is overloaded it won't respond to pings quickly and the remote node can
6995 // avoid sending us more work, like chain download requests.
6997 // The nonce stops the remote getting confused between different pings: without
6998 // it, if the remote node sends a ping once per second and this node takes 5
6999 // seconds to respond to each, the 5th ping the remote sends would appear to
7000 // return very quickly.
7001 pfrom->PushMessage("pong", nonce);
7006 else if (strCommand == "pong")
7008 int64_t pingUsecEnd = nTimeReceived;
7010 size_t nAvail = vRecv.in_avail();
7011 bool bPingFinished = false;
7012 std::string sProblem;
7014 if (nAvail >= sizeof(nonce)) {
7017 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
7018 if (pfrom->nPingNonceSent != 0) {
7019 if (nonce == pfrom->nPingNonceSent) {
7020 // Matching pong received, this ping is no longer outstanding
7021 bPingFinished = true;
7022 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
7023 if (pingUsecTime > 0) {
7024 // Successful ping time measurement, replace previous
7025 pfrom->nPingUsecTime = pingUsecTime;
7026 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
7028 // This should never happen
7029 sProblem = "Timing mishap";
7032 // Nonce mismatches are normal when pings are overlapping
7033 sProblem = "Nonce mismatch";
7035 // This is most likely a bug in another implementation somewhere; cancel this ping
7036 bPingFinished = true;
7037 sProblem = "Nonce zero";
7041 sProblem = "Unsolicited pong without ping";
7044 // This is most likely a bug in another implementation somewhere; cancel this ping
7045 bPingFinished = true;
7046 sProblem = "Short payload";
7049 if (!(sProblem.empty())) {
7050 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
7054 pfrom->nPingNonceSent,
7058 if (bPingFinished) {
7059 pfrom->nPingNonceSent = 0;
7064 else if (fAlerts && strCommand == "alert")
7069 uint256 alertHash = alert.GetHash();
7070 if (pfrom->setKnown.count(alertHash) == 0)
7072 if (alert.ProcessAlert(Params().AlertKey()))
7075 pfrom->setKnown.insert(alertHash);
7078 BOOST_FOREACH(CNode* pnode, vNodes)
7079 alert.RelayTo(pnode);
7083 // Small DoS penalty so peers that send us lots of
7084 // duplicate/expired/invalid-signature/whatever alerts
7085 // eventually get banned.
7086 // This isn't a Misbehaving(100) (immediate ban) because the
7087 // peer might be an older or different implementation with
7088 // a different signature key, etc.
7089 Misbehaving(pfrom->GetId(), 10);
7094 else if (!(nLocalServices & NODE_BLOOM) &&
7095 (strCommand == "filterload" ||
7096 strCommand == "filteradd"))
7098 if (pfrom->nVersion >= NO_BLOOM_VERSION) {
7099 Misbehaving(pfrom->GetId(), 100);
7101 } else if (GetBoolArg("-enforcenodebloom", false)) {
7102 pfrom->fDisconnect = true;
7108 else if (strCommand == "filterload")
7110 CBloomFilter filter;
7113 if (!filter.IsWithinSizeConstraints())
7114 // There is no excuse for sending a too-large filter
7115 Misbehaving(pfrom->GetId(), 100);
7118 LOCK(pfrom->cs_filter);
7119 delete pfrom->pfilter;
7120 pfrom->pfilter = new CBloomFilter(filter);
7121 pfrom->pfilter->UpdateEmptyFull();
7123 pfrom->fRelayTxes = true;
7127 else if (strCommand == "filteradd")
7129 vector<unsigned char> vData;
7132 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
7133 // and thus, the maximum size any matched object can have) in a filteradd message
7134 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
7136 Misbehaving(pfrom->GetId(), 100);
7138 LOCK(pfrom->cs_filter);
7140 pfrom->pfilter->insert(vData);
7142 Misbehaving(pfrom->GetId(), 100);
7147 else if (strCommand == "filterclear")
7149 LOCK(pfrom->cs_filter);
7150 if (nLocalServices & NODE_BLOOM) {
7151 delete pfrom->pfilter;
7152 pfrom->pfilter = new CBloomFilter();
7154 pfrom->fRelayTxes = true;
7158 else if (strCommand == "reject")
7162 string strMsg; unsigned char ccode; string strReason;
7163 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
7166 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
7168 if (strMsg == "block" || strMsg == "tx")
7172 ss << ": hash " << hash.ToString();
7174 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
7175 } catch (const std::ios_base::failure&) {
7176 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
7177 LogPrint("net", "Unparseable reject message received\n");
7181 else if (strCommand == "notfound") {
7182 // We do not care about the NOTFOUND message, but logging an Unknown Command
7183 // message would be undesirable as we transmit it ourselves.
7187 // Ignore unknown commands for extensibility
7188 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
7196 // requires LOCK(cs_vRecvMsg)
7197 bool ProcessMessages(CNode* pfrom)
7200 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
7204 // (4) message start
7212 if (!pfrom->vRecvGetData.empty())
7213 ProcessGetData(pfrom);
7215 // this maintains the order of responses
7216 if (!pfrom->vRecvGetData.empty()) return fOk;
7218 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
7219 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
7220 // Don't bother if send buffer is too full to respond anyway
7221 if (pfrom->nSendSize >= SendBufferSize())
7225 CNetMessage& msg = *it;
7228 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
7229 // msg.hdr.nMessageSize, msg.vRecv.size(),
7230 // msg.complete() ? "Y" : "N");
7232 // end, if an incomplete message is found
7233 if (!msg.complete())
7236 // at this point, any failure means we can delete the current message
7239 // Scan for message start
7240 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
7241 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
7247 CMessageHeader& hdr = msg.hdr;
7248 if (!hdr.IsValid(Params().MessageStart()))
7250 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
7253 string strCommand = hdr.GetCommand();
7256 unsigned int nMessageSize = hdr.nMessageSize;
7259 CDataStream& vRecv = msg.vRecv;
7260 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
7261 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
7262 if (nChecksum != hdr.nChecksum)
7264 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
7265 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
7273 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
7274 boost::this_thread::interruption_point();
7276 catch (const std::ios_base::failure& e)
7278 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
7279 if (strstr(e.what(), "end of data"))
7281 // Allow exceptions from under-length message on vRecv
7282 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());
7284 else if (strstr(e.what(), "size too large"))
7286 // Allow exceptions from over-long size
7287 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
7291 //PrintExceptionContinue(&e, "ProcessMessages()");
7294 catch (const boost::thread_interrupted&) {
7297 catch (const std::exception& e) {
7298 PrintExceptionContinue(&e, "ProcessMessages()");
7300 PrintExceptionContinue(NULL, "ProcessMessages()");
7304 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
7309 // In case the connection got shut down, its receive buffer was wiped
7310 if (!pfrom->fDisconnect)
7311 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
7317 bool SendMessages(CNode* pto, bool fSendTrickle)
7319 const Consensus::Params& consensusParams = Params().GetConsensus();
7321 // Don't send anything until we get its version message
7322 if (pto->nVersion == 0)
7328 bool pingSend = false;
7329 if (pto->fPingQueued) {
7330 // RPC ping request by user
7333 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
7334 // Ping automatically sent as a latency probe & keepalive.
7339 while (nonce == 0) {
7340 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
7342 pto->fPingQueued = false;
7343 pto->nPingUsecStart = GetTimeMicros();
7344 if (pto->nVersion > BIP0031_VERSION) {
7345 pto->nPingNonceSent = nonce;
7346 pto->PushMessage("ping", nonce);
7348 // Peer is too old to support ping command with nonce, pong will never arrive.
7349 pto->nPingNonceSent = 0;
7350 pto->PushMessage("ping");
7354 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
7358 // Address refresh broadcast
7359 static int64_t nLastRebroadcast;
7360 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
7363 BOOST_FOREACH(CNode* pnode, vNodes)
7365 // Periodically clear addrKnown to allow refresh broadcasts
7366 if (nLastRebroadcast)
7367 pnode->addrKnown.reset();
7369 // Rebroadcast our address
7370 AdvertizeLocal(pnode);
7372 if (!vNodes.empty())
7373 nLastRebroadcast = GetTime();
7381 vector<CAddress> vAddr;
7382 vAddr.reserve(pto->vAddrToSend.size());
7383 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
7385 if (!pto->addrKnown.contains(addr.GetKey()))
7387 pto->addrKnown.insert(addr.GetKey());
7388 vAddr.push_back(addr);
7389 // receiver rejects addr messages larger than 1000
7390 if (vAddr.size() >= 1000)
7392 pto->PushMessage("addr", vAddr);
7397 pto->vAddrToSend.clear();
7399 pto->PushMessage("addr", vAddr);
7402 CNodeState &state = *State(pto->GetId());
7403 if (state.fShouldBan) {
7404 if (pto->fWhitelisted)
7405 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
7407 pto->fDisconnect = true;
7408 if (pto->addr.IsLocal())
7409 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
7412 CNode::Ban(pto->addr);
7415 state.fShouldBan = false;
7418 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
7419 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
7420 state.rejects.clear();
7423 if (pindexBestHeader == NULL)
7424 pindexBestHeader = chainActive.Tip();
7425 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.
7426 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
7427 // Only actively request headers from a single peer, unless we're close to today.
7428 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
7429 state.fSyncStarted = true;
7431 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
7432 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->GetHeight(), pto->id, pto->nStartingHeight);
7433 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
7437 // Resend wallet transactions that haven't gotten in a block yet
7438 // Except during reindex, importing and IBD, when old wallet
7439 // transactions become unconfirmed and spams other nodes.
7440 if (!fReindex && !fImporting && !IsInitialBlockDownload())
7442 GetMainSignals().Broadcast(nTimeBestReceived);
7446 // Message: inventory
7449 vector<CInv> vInvWait;
7451 LOCK(pto->cs_inventory);
7452 vInv.reserve(pto->vInventoryToSend.size());
7453 vInvWait.reserve(pto->vInventoryToSend.size());
7454 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
7456 if (pto->setInventoryKnown.count(inv))
7459 // trickle out tx inv to protect privacy
7460 if (inv.type == MSG_TX && !fSendTrickle)
7462 // 1/4 of tx invs blast to all immediately
7463 static uint256 hashSalt;
7464 if (hashSalt.IsNull())
7465 hashSalt = GetRandHash();
7466 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
7467 hashRand = Hash(BEGIN(hashRand), END(hashRand));
7468 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
7472 vInvWait.push_back(inv);
7477 // returns true if wasn't already contained in the set
7478 if (pto->setInventoryKnown.insert(inv).second)
7480 vInv.push_back(inv);
7481 if (vInv.size() >= 1000)
7483 pto->PushMessage("inv", vInv);
7488 pto->vInventoryToSend = vInvWait;
7491 pto->PushMessage("inv", vInv);
7493 // Detect whether we're stalling
7494 int64_t nNow = GetTimeMicros();
7495 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7496 // Stalling only triggers when the block download window cannot move. During normal steady state,
7497 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7498 // should only happen during initial block download.
7499 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
7500 pto->fDisconnect = true;
7502 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
7503 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7504 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7505 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
7506 // to unreasonably increase our timeout.
7507 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7508 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7509 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7510 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7511 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7512 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7513 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
7514 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
7515 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7516 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7517 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7519 if (queuedBlock.nTimeDisconnect < nNow) {
7520 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7521 pto->fDisconnect = true;
7526 // Message: getdata (blocks)
7528 static uint256 zero;
7529 vector<CInv> vGetData;
7530 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
7531 vector<CBlockIndex*> vToDownload;
7532 NodeId staller = -1;
7533 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7534 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7535 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
7536 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
7537 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
7538 pindex->GetHeight(), pto->id);
7540 if (state.nBlocksInFlight == 0 && staller != -1) {
7541 if (State(staller)->nStallingSince == 0) {
7542 State(staller)->nStallingSince = nNow;
7543 LogPrint("net", "Stall started peer=%d\n", staller);
7547 /*CBlockIndex *pindex;
7548 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
7550 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7551 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7552 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7553 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
7554 komodo_requestedcount++;
7555 if ( komodo_requestedcount > 16 )
7557 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7558 komodo_requestedcount = 0;
7563 // Message: getdata (non-blocks)
7565 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
7567 const CInv& inv = (*pto->mapAskFor.begin()).second;
7568 if (!AlreadyHave(inv))
7571 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
7572 vGetData.push_back(inv);
7573 if (vGetData.size() >= 1000)
7575 pto->PushMessage("getdata", vGetData);
7579 //If we're not going to ask, don't expect a response.
7580 pto->setAskFor.erase(inv.hash);
7582 pto->mapAskFor.erase(pto->mapAskFor.begin());
7584 if (!vGetData.empty())
7585 pto->PushMessage("getdata", vGetData);
7591 std::string CBlockFileInfo::ToString() const {
7592 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));
7597 static class CMainCleanup
7603 BlockMap::iterator it1 = mapBlockIndex.begin();
7604 for (; it1 != mapBlockIndex.end(); it1++)
7605 delete (*it1).second;
7606 mapBlockIndex.clear();
7608 // orphan transactions
7609 mapOrphanTransactions.clear();
7610 mapOrphanTransactionsByPrev.clear();
7612 } instance_of_cmaincleanup;
7614 extern "C" const char* getDataDir()
7616 return GetDataDir().string().c_str();
7620 // Set default values of new CMutableTransaction based on consensus rules at given height.
7621 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7623 CMutableTransaction mtx;
7625 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7626 if (isOverwintered) {
7627 mtx.fOverwintered = true;
7628 mtx.nExpiryHeight = nHeight + expiryDelta;
7630 if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) {
7631 mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
7632 mtx.nVersion = SAPLING_TX_VERSION;
7634 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7635 mtx.nVersion = OVERWINTER_TX_VERSION;
7636 mtx.nExpiryHeight = std::min(
7638 static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));