1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
12 #include "arith_uint256.h"
13 #include "importcoin.h"
14 #include "chainparams.h"
15 #include "checkpoints.h"
16 #include "checkqueue.h"
17 #include "consensus/upgrades.h"
18 #include "consensus/validation.h"
19 #include "deprecation.h"
21 #include "merkleblock.h"
23 #include "notarisationdb.h"
26 #include "script/interpreter.h"
28 #include "txmempool.h"
29 #include "ui_interface.h"
32 #include "utilmoneystr.h"
33 #include "validationinterface.h"
34 #include "wallet/asyncrpcoperation_sendmany.h"
35 #include "wallet/asyncrpcoperation_shieldcoinbase.h"
42 #include <unordered_map>
45 #include <boost/algorithm/string/replace.hpp>
46 #include <boost/filesystem.hpp>
47 #include <boost/filesystem/fstream.hpp>
48 #include <boost/math/distributions/poisson.hpp>
49 #include <boost/thread.hpp>
50 #include <boost/static_assert.hpp>
55 # error "Zcash cannot be compiled without assertions."
58 #include "librustzcash.h"
64 CCriticalSection cs_main;
65 extern uint8_t NOTARY_PUBKEY33[33];
66 extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING;
67 int32_t KOMODO_NEWBLOCKS;
68 int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
69 void komodo_broadcast(CBlock *pblock,int32_t limit);
71 BlockMap mapBlockIndex;
73 CBlockIndex *pindexBestHeader = NULL;
74 static int64_t nTimeBestReceived = 0;
75 CWaitableCriticalSection csBestBlock;
76 CConditionVariable cvBlockChange;
77 int nScriptCheckThreads = 0;
78 bool fExperimentalMode = false;
79 bool fImporting = false;
80 bool fReindex = false;
81 bool fTxIndex = false;
82 bool fAddressIndex = false;
83 bool fTimestampIndex = false;
84 bool fSpentIndex = false;
85 bool fHavePruned = false;
86 bool fPruneMode = false;
87 bool fIsBareMultisigStd = true;
88 bool fCheckBlockIndex = false;
89 bool fCheckpointsEnabled = true;
90 bool fCoinbaseEnforcedProtectionEnabled = true;
91 size_t nCoinCacheUsage = 5000 * 300;
92 uint64_t nPruneTarget = 0;
93 bool fAlerts = DEFAULT_ALERTS;
94 /* If the tip is older than this (in seconds), the node is considered to be in initial block download.
96 int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
98 unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
100 /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
101 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
103 CTxMemPool mempool(::minRelayTxFee);
109 map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
110 map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
111 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
114 * Returns true if there are nRequired or more blocks of minVersion or above
115 * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
117 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
118 static void CheckBlockIndex();
120 /** Constant stuff for coinbase transactions we create: */
121 CScript COINBASE_FLAGS;
123 const string strMessageMagic = "Komodo Signed Message:\n";
128 struct CBlockIndexWorkComparator
130 bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
131 // First sort by most total work, ...
132 if (pa->chainPower > pb->chainPower) return false;
133 if (pa->chainPower < pb->chainPower) return true;
135 // ... then by earliest time received, ...
136 if (pa->nSequenceId < pb->nSequenceId) return false;
137 if (pa->nSequenceId > pb->nSequenceId) return true;
139 // Use pointer address as tie breaker (should only happen with blocks
140 // loaded from disk, as those all have id 0).
141 if (pa < pb) return false;
142 if (pa > pb) return true;
149 CBlockIndex *pindexBestInvalid;
152 * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
153 * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
154 * missing the data for the block.
156 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
158 /** Number of nodes with fSyncStarted. */
159 int nSyncStarted = 0;
161 /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
162 * Pruned nodes may have entries where B is missing data.
164 multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
166 CCriticalSection cs_LastBlockFile;
167 std::vector<CBlockFileInfo> vinfoBlockFile;
168 int nLastBlockFile = 0;
169 /** Global flag to indicate we should check to see if there are
170 * block/undo files that should be deleted. Set on startup
171 * or if we allocate more file space when we're in prune mode
173 bool fCheckForPruning = false;
176 * Every received block is assigned a unique and increasing identifier, so we
177 * know which one to give priority in case of a fork.
179 CCriticalSection cs_nBlockSequenceId;
180 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
181 uint32_t nBlockSequenceId = 1;
184 * Sources of received blocks, saved to be able to send them reject
185 * messages or ban them when processing happens afterwards. Protected by
188 map<uint256, NodeId> mapBlockSource;
191 * Filter for transactions that were recently rejected by
192 * AcceptToMemoryPool. These are not rerequested until the chain tip
193 * changes, at which point the entire filter is reset. Protected by
196 * Without this filter we'd be re-requesting txs from each of our peers,
197 * increasing bandwidth consumption considerably. For instance, with 100
198 * peers, half of which relay a tx we don't accept, that might be a 50x
199 * bandwidth increase. A flooding attacker attempting to roll-over the
200 * filter using minimum-sized, 60byte, transactions might manage to send
201 * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
202 * two minute window to send invs to us.
204 * Decreasing the false positive rate is fairly cheap, so we pick one in a
205 * million to make it highly unlikely for users to have issues with this
210 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
211 uint256 hashRecentRejectsChainTip;
213 /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
216 CBlockIndex *pindex; //! Optional.
217 int64_t nTime; //! Time of "getdata" request in microseconds.
218 bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
219 int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
221 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
223 /** Number of blocks in flight with validated headers. */
224 int nQueuedValidatedHeaders = 0;
226 /** Number of preferable block download peers. */
227 int nPreferredDownload = 0;
229 /** Dirty block index entries. */
230 set<CBlockIndex*> setDirtyBlockIndex;
232 /** Dirty block file entries. */
233 set<int> setDirtyFileInfo;
236 //////////////////////////////////////////////////////////////////////////////
238 // Registration of network node signals.
243 struct CBlockReject {
244 unsigned char chRejectCode;
245 string strRejectReason;
250 * Maintain validation-specific state about nodes, protected by cs_main, instead
251 * by CNode's own locks. This simplifies asynchronous operation, where
252 * processing of incoming data is done after the ProcessMessage call returns,
253 * and we're no longer holding the node's locks.
256 //! The peer's address
258 //! Whether we have a fully established connection.
259 bool fCurrentlyConnected;
260 //! Accumulated misbehaviour score for this peer.
262 //! Whether this peer should be disconnected and banned (unless whitelisted).
264 //! String name of this peer (debugging/logging purposes).
266 //! List of asynchronously-determined block rejections to notify this peer about.
267 std::vector<CBlockReject> rejects;
268 //! The best known block we know this peer has announced.
269 CBlockIndex *pindexBestKnownBlock;
270 //! The hash of the last unknown block this peer has announced.
271 uint256 hashLastUnknownBlock;
272 //! The last full block we both have.
273 CBlockIndex *pindexLastCommonBlock;
274 //! Whether we've started headers synchronization with this peer.
276 //! Since when we're stalling block download progress (in microseconds), or 0.
277 int64_t nStallingSince;
278 list<QueuedBlock> vBlocksInFlight;
280 int nBlocksInFlightValidHeaders;
281 //! Whether we consider this a preferred download peer.
282 bool fPreferredDownload;
285 fCurrentlyConnected = false;
288 pindexBestKnownBlock = NULL;
289 hashLastUnknownBlock.SetNull();
290 pindexLastCommonBlock = NULL;
291 fSyncStarted = false;
294 nBlocksInFlightValidHeaders = 0;
295 fPreferredDownload = false;
299 /** Map maintaining per-node state. Requires cs_main. */
300 map<NodeId, CNodeState> mapNodeState;
303 CNodeState *State(NodeId pnode) {
304 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
305 if (it == mapNodeState.end())
312 return chainActive.LastTip()->GetHeight();
315 void UpdatePreferredDownload(CNode* node, CNodeState* state)
317 nPreferredDownload -= state->fPreferredDownload;
319 // Whether this node should be marked as a preferred download node.
320 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
322 nPreferredDownload += state->fPreferredDownload;
325 // Returns time at which to timeout block request (nTime in microseconds)
326 int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
328 return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
331 void InitializeNode(NodeId nodeid, const CNode *pnode) {
333 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
334 state.name = pnode->addrName;
335 state.address = pnode->addr;
338 void FinalizeNode(NodeId nodeid) {
340 CNodeState *state = State(nodeid);
342 if (state->fSyncStarted)
345 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
346 AddressCurrentlyConnected(state->address);
349 BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
350 mapBlocksInFlight.erase(entry.hash);
351 EraseOrphansFor(nodeid);
352 nPreferredDownload -= state->fPreferredDownload;
354 mapNodeState.erase(nodeid);
357 void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
359 /* int expired = pool.Expire(GetTime() - age);
361 LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
363 std::vector<uint256> vNoSpendsRemaining;
364 pool.TrimToSize(limit, &vNoSpendsRemaining);
365 BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
366 pcoinsTip->Uncache(removed);*/
370 // Returns a bool indicating whether we requested this block.
371 bool MarkBlockAsReceived(const uint256& hash) {
372 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
373 if (itInFlight != mapBlocksInFlight.end()) {
374 CNodeState *state = State(itInFlight->second.first);
375 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
376 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
377 state->vBlocksInFlight.erase(itInFlight->second.second);
378 state->nBlocksInFlight--;
379 state->nStallingSince = 0;
380 mapBlocksInFlight.erase(itInFlight);
387 void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
388 CNodeState *state = State(nodeid);
389 assert(state != NULL);
391 // Make sure it's not listed somewhere already.
392 MarkBlockAsReceived(hash);
394 int64_t nNow = GetTimeMicros();
395 QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
396 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
397 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
398 state->nBlocksInFlight++;
399 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
400 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
403 /** Check whether the last unknown block a peer advertized is not yet known. */
404 void ProcessBlockAvailability(NodeId nodeid) {
405 CNodeState *state = State(nodeid);
406 assert(state != NULL);
408 if (!state->hashLastUnknownBlock.IsNull()) {
409 BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
410 if (itOld != mapBlockIndex.end() && itOld->second != 0 && (itOld->second->chainPower > CChainPower()))
412 if (state->pindexBestKnownBlock == NULL || itOld->second->chainPower >= state->pindexBestKnownBlock->chainPower)
413 state->pindexBestKnownBlock = itOld->second;
414 state->hashLastUnknownBlock.SetNull();
419 /** Update tracking information about which blocks a peer is assumed to have. */
420 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
421 CNodeState *state = State(nodeid);
422 assert(state != NULL);
424 /*ProcessBlockAvailability(nodeid);
426 BlockMap::iterator it = mapBlockIndex.find(hash);
427 if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
428 // An actually better block was announced.
429 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
430 state->pindexBestKnownBlock = it->second;
433 // An unknown block was announced; just assume that the latest one is the best one.
434 state->hashLastUnknownBlock = hash;
438 /** Find the last common ancestor two blocks have.
439 * Both pa and pb must be non-NULL. */
440 CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
441 if (pa->GetHeight() > pb->GetHeight()) {
442 pa = pa->GetAncestor(pb->GetHeight());
443 } else if (pb->GetHeight() > pa->GetHeight()) {
444 pb = pb->GetAncestor(pa->GetHeight());
447 while (pa != pb && pa && pb) {
452 // Eventually all chain branches meet at the genesis block.
457 /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
458 * at most count entries. */
459 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
463 vBlocks.reserve(vBlocks.size() + count);
464 CNodeState *state = State(nodeid);
465 assert(state != NULL);
467 // Make sure pindexBestKnownBlock is up to date, we'll need it.
468 ProcessBlockAvailability(nodeid);
470 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->chainPower < chainActive.Tip()->chainPower) {
471 // This peer has nothing interesting.
475 if (state->pindexLastCommonBlock == NULL) {
476 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
477 // Guessing wrong in either direction is not a problem.
478 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->GetHeight(), chainActive.Height())];
481 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
482 // of its current tip anymore. Go back enough to fix that.
483 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
484 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
487 std::vector<CBlockIndex*> vToFetch;
488 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
489 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
490 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
491 // download that next block if the window were 1 larger.
492 int nWindowEnd = state->pindexLastCommonBlock->GetHeight() + BLOCK_DOWNLOAD_WINDOW;
493 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->GetHeight(), nWindowEnd + 1);
494 NodeId waitingfor = -1;
495 while (pindexWalk->GetHeight() < nMaxHeight) {
496 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
497 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
498 // as iterating over ~100 CBlockIndex* entries anyway.
499 int nToFetch = std::min(nMaxHeight - pindexWalk->GetHeight(), std::max<int>(count - vBlocks.size(), 128));
500 vToFetch.resize(nToFetch);
501 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->GetHeight() + nToFetch);
502 vToFetch[nToFetch - 1] = pindexWalk;
503 for (unsigned int i = nToFetch - 1; i > 0; i--) {
504 vToFetch[i - 1] = vToFetch[i]->pprev;
507 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
508 // are not yet downloaded and not in flight to vBlocks. In the meantime, update
509 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
510 // already part of our chain (and therefore don't need it even if pruned).
511 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
512 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
513 // We consider the chain that this peer is on invalid.
516 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
517 if (pindex->nChainTx)
518 state->pindexLastCommonBlock = pindex;
519 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
520 // The block is not already downloaded, and not yet in flight.
521 if (pindex->GetHeight() > nWindowEnd) {
522 // We reached the end of the window.
523 if (vBlocks.size() == 0 && waitingfor != nodeid) {
524 // We aren't able to fetch anything, but we would be if the download window was one larger.
525 nodeStaller = waitingfor;
529 vBlocks.push_back(pindex);
530 if (vBlocks.size() == count) {
533 } else if (waitingfor == -1) {
534 // This is the first already-in-flight block.
535 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
543 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
545 CNodeState *state = State(nodeid);
548 stats.nMisbehavior = state->nMisbehavior;
549 stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->GetHeight() : -1;
550 stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->GetHeight() : -1;
551 BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
553 stats.vHeightInFlight.push_back(queue.pindex->GetHeight());
558 void RegisterNodeSignals(CNodeSignals& nodeSignals)
560 nodeSignals.GetHeight.connect(&GetHeight);
561 nodeSignals.ProcessMessages.connect(&ProcessMessages);
562 nodeSignals.SendMessages.connect(&SendMessages);
563 nodeSignals.InitializeNode.connect(&InitializeNode);
564 nodeSignals.FinalizeNode.connect(&FinalizeNode);
567 void UnregisterNodeSignals(CNodeSignals& nodeSignals)
569 nodeSignals.GetHeight.disconnect(&GetHeight);
570 nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
571 nodeSignals.SendMessages.disconnect(&SendMessages);
572 nodeSignals.InitializeNode.disconnect(&InitializeNode);
573 nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
576 CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
578 // Find the first block the caller has in the main chain
579 BOOST_FOREACH(const uint256& hash, locator.vHave) {
580 BlockMap::iterator mi = mapBlockIndex.find(hash);
581 if (mi != mapBlockIndex.end())
583 CBlockIndex* pindex = (*mi).second;
584 if (pindex != 0 && chain.Contains(pindex))
586 if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
591 return chain.Genesis();
594 CCoinsViewCache *pcoinsTip = NULL;
595 CBlockTreeDB *pblocktree = NULL;
602 UniValue komodo_snapshot(int top)
606 UniValue result(UniValue::VOBJ);
609 if ( pblocktree != 0 ) {
610 result = pblocktree->Snapshot(top);
612 fprintf(stderr,"null pblocktree start with -addressindex=1\n");
615 fprintf(stderr,"getsnapshot requires -addressindex=1\n");
620 //////////////////////////////////////////////////////////////////////////////
622 // mapOrphanTransactions
625 bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
627 uint256 hash = tx.GetHash();
628 if (mapOrphanTransactions.count(hash))
631 // Ignore big transactions, to avoid a
632 // send-big-orphans memory exhaustion attack. If a peer has a legitimate
633 // large transaction with a missing parent then we assume
634 // it will rebroadcast it later, after the parent transaction(s)
635 // have been mined or received.
636 // 10,000 orphans, each of which is at most 5,000 bytes big is
637 // at most 500 megabytes of orphans:
638 unsigned int sz = GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
641 LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
645 mapOrphanTransactions[hash].tx = tx;
646 mapOrphanTransactions[hash].fromPeer = peer;
647 BOOST_FOREACH(const CTxIn& txin, tx.vin)
648 mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
650 LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
651 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
655 void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
657 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
658 if (it == mapOrphanTransactions.end())
660 BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
662 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
663 if (itPrev == mapOrphanTransactionsByPrev.end())
665 itPrev->second.erase(hash);
666 if (itPrev->second.empty())
667 mapOrphanTransactionsByPrev.erase(itPrev);
669 mapOrphanTransactions.erase(it);
672 void EraseOrphansFor(NodeId peer)
675 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
676 while (iter != mapOrphanTransactions.end())
678 map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
679 if (maybeErase->second.fromPeer == peer)
681 EraseOrphanTx(maybeErase->second.tx.GetHash());
685 if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
689 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
691 unsigned int nEvicted = 0;
692 while (mapOrphanTransactions.size() > nMaxOrphans)
694 // Evict a random orphan:
695 uint256 randomhash = GetRandHash();
696 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
697 if (it == mapOrphanTransactions.end())
698 it = mapOrphanTransactions.begin();
699 EraseOrphanTx(it->first);
706 bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
708 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
709 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
712 // Sapling standard rules apply
713 if (tx.nVersion > CTransaction::SAPLING_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SAPLING_MIN_CURRENT_VERSION) {
714 reason = "sapling-version";
717 } else if (overwinterActive) {
718 // Overwinter standard rules apply
719 if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
720 reason = "overwinter-version";
724 // Sprout standard rules apply
725 if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
731 BOOST_FOREACH(const CTxIn& txin, tx.vin)
733 // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
734 // keys. (remember the 520 byte limit on redeemScript size) That works
735 // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
736 // bytes of scriptSig, which we round off to 1650 bytes for some minor
737 // future-proofing. That's also enough to spend a 20-of-20
738 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
739 // considered standard)
740 if (txin.scriptSig.size() > 1650) {
741 reason = "scriptsig-size";
744 if (!txin.scriptSig.IsPushOnly()) {
745 reason = "scriptsig-not-pushonly";
750 unsigned int v=0,nDataOut = 0;
751 txnouttype whichType;
752 BOOST_FOREACH(const CTxOut& txout, tx.vout)
754 if (!::IsStandard(txout.scriptPubKey, whichType))
756 reason = "scriptpubkey";
757 //fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
761 if (whichType == TX_NULL_DATA)
763 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
765 reason = "opreturn too big";
769 //fprintf(stderr,"is OP_RETURN\n");
771 else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
772 reason = "bare-multisig";
774 } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) {
781 // only one OP_RETURN txout is permitted
783 reason = "multi-op-return";
790 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
793 if (tx.nLockTime == 0)
795 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
797 BOOST_FOREACH(const CTxIn& txin, tx.vin)
799 if ( txin.nSequence == 0xfffffffe && (((int64_t)tx.nLockTime >= LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockTime) || ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD && (int64_t)tx.nLockTime > nBlockHeight)) )
803 else if (!txin.IsFinal())
805 //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
812 bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
814 if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
817 return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
820 bool CheckFinalTx(const CTransaction &tx, int flags)
822 AssertLockHeld(cs_main);
824 // By convention a negative value for flags indicates that the
825 // current network-enforced consensus rules should be used. In
826 // a future soft-fork scenario that would mean checking which
827 // rules would be enforced for the next block and setting the
828 // appropriate flags. At the present time no soft-forks are
829 // scheduled, so no flags are set.
830 flags = std::max(flags, 0);
832 // CheckFinalTx() uses chainActive.Height()+1 to evaluate
833 // nLockTime because when IsFinalTx() is called within
834 // CBlock::AcceptBlock(), the height of the block *being*
835 // evaluated is what is used. Thus if we want to know if a
836 // transaction can be part of the *next* block, we need to call
837 // IsFinalTx() with one more than chainActive.Height().
838 const int nBlockHeight = chainActive.Height() + 1;
840 // Timestamps on the other hand don't get any special treatment,
841 // because we can't know what timestamp the next block will have,
842 // and there aren't timestamp applications where it matters.
843 // However this changes once median past time-locks are enforced:
844 const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
845 ? chainActive.Tip()->GetMedianTimePast()
848 return IsFinalTx(tx, nBlockHeight, nBlockTime);
852 * Check transaction inputs to mitigate two
853 * potential denial-of-service attacks:
855 * 1. scriptSigs with extra data stuffed into them,
856 * not consumed by scriptPubKey (or P2SH script)
857 * 2. P2SH scripts with a crazy number of expensive
858 * CHECKSIG/CHECKMULTISIG operations
860 bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
863 return true; // Coinbases don't use vin normally
865 if (tx.IsCoinImport())
866 return tx.vin[0].scriptSig.IsCoinImport();
868 for (unsigned int i = 0; i < tx.vin.size(); i++)
870 const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
872 vector<vector<unsigned char> > vSolutions;
873 txnouttype whichType;
874 // get the scriptPubKey corresponding to this input:
875 const CScript& prevScript = prev.scriptPubKey;
876 //printf("Previous script: %s\n", prevScript.ToString().c_str());
878 if (!Solver(prevScript, whichType, vSolutions))
880 int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
881 if (nArgsExpected < 0)
884 // Transactions with extra stuff in their scriptSigs are
885 // non-standard. Note that this EvalScript() call will
886 // be quick, because if there are any operations
887 // beside "push data" in the scriptSig
888 // IsStandardTx() will have already returned false
889 // and this method isn't called.
890 vector<vector<unsigned char> > stack;
891 //printf("Checking script: %s\n", tx.vin[i].scriptSig.ToString().c_str());
892 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
895 if (whichType == TX_SCRIPTHASH)
899 CScript subscript(stack.back().begin(), stack.back().end());
900 vector<vector<unsigned char> > vSolutions2;
901 txnouttype whichType2;
902 if (Solver(subscript, whichType2, vSolutions2))
904 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
907 nArgsExpected += tmpExpected;
911 // Any other Script with less than 15 sigops OK:
912 unsigned int sigops = subscript.GetSigOpCount(true);
913 // ... extra data left on the stack after execution is OK, too:
914 return (sigops <= MAX_P2SH_SIGOPS);
918 if (stack.size() != (unsigned int)nArgsExpected)
925 unsigned int GetLegacySigOpCount(const CTransaction& tx)
927 unsigned int nSigOps = 0;
928 BOOST_FOREACH(const CTxIn& txin, tx.vin)
930 nSigOps += txin.scriptSig.GetSigOpCount(false);
932 BOOST_FOREACH(const CTxOut& txout, tx.vout)
934 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
939 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
941 if (tx.IsCoinBase() || tx.IsCoinImport())
944 unsigned int nSigOps = 0;
945 for (unsigned int i = 0; i < tx.vin.size(); i++)
947 const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
948 if (prevout.scriptPubKey.IsPayToScriptHash())
949 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
955 * Ensure that a coinbase transaction is structured according to the consensus rules of the
958 bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight)
960 // if time locks are on, ensure that this coin base is time locked exactly as it should be
961 if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) ||
962 (((nHeight >= 31680) || strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE))
964 CScriptID scriptHash;
966 // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that
967 // holds the full output script, which may include multisig, etc., but starts with
968 // the time lock verify of the correct time lock for this block height
969 if (tx.vout.size() == 2 &&
970 CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) &&
971 tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
972 tx.vout[1].scriptPubKey[0] == OP_RETURN)
975 std::vector<uint8_t> opretData = std::vector<uint8_t>();
976 CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
977 if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
979 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
982 CScriptExt opretScript = CScriptExt(&opretData[1], &opretData[opretData.size()]);
984 if (CScriptID(opretScript) == scriptHash &&
985 opretScript.IsCheckLockTimeVerify(&unlocktime) &&
986 komodo_block_unlocktime(nHeight) == unlocktime)
999 * Check a transaction contextually against a set of consensus rules valid at a given block height.
1002 * 1. AcceptToMemoryPool calls CheckTransaction and this function.
1003 * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
1004 * and ContextualCheckBlock (which calls this function).
1005 * 3. The isInitBlockDownload argument is only to assist with testing.
1007 bool ContextualCheckTransaction(
1008 const CTransaction& tx,
1009 CValidationState &state,
1012 bool (*isInitBlockDownload)())
1014 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
1015 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
1016 bool isSprout = !overwinterActive;
1018 // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
1019 if (isSprout && tx.fOverwintered) {
1020 return state.DoS(isInitBlockDownload() ? 0 : dosLevel,
1021 error("ContextualCheckTransaction(): ht.%d activates.%d dosLevel.%d overwinter is not active yet",
1022 nHeight, Params().GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight, dosLevel),
1023 REJECT_INVALID, "tx-overwinter-not-active");
1026 if (saplingActive) {
1027 // Reject transactions with valid version but missing overwintered flag
1028 if (tx.nVersion >= SAPLING_MIN_TX_VERSION && !tx.fOverwintered) {
1029 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwintered flag must be set"),
1030 REJECT_INVALID, "tx-overwintered-flag-not-set");
1033 // Reject transactions with non-Sapling version group ID
1034 if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1035 return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),
1036 REJECT_INVALID, "bad-sapling-tx-version-group-id");
1039 // Reject transactions with invalid version
1040 if (tx.fOverwintered && tx.nVersion < SAPLING_MIN_TX_VERSION ) {
1041 return state.DoS(100, error("CheckTransaction(): Sapling version too low"),
1042 REJECT_INVALID, "bad-tx-sapling-version-too-low");
1045 // Reject transactions with invalid version
1046 if (tx.fOverwintered && tx.nVersion > SAPLING_MAX_TX_VERSION ) {
1047 return state.DoS(100, error("CheckTransaction(): Sapling version too high"),
1048 REJECT_INVALID, "bad-tx-sapling-version-too-high");
1050 } else if (overwinterActive) {
1051 // Reject transactions with valid version but missing overwinter flag
1052 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
1053 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
1054 REJECT_INVALID, "tx-overwinter-flag-not-set");
1057 // Reject transactions with non-Overwinter version group ID
1058 if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1059 return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),
1060 REJECT_INVALID, "bad-overwinter-tx-version-group-id");
1063 // Reject transactions with invalid version
1064 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
1065 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
1066 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
1070 // Rules that apply to Overwinter or later:
1071 if (overwinterActive) {
1072 // Reject transactions intended for Sprout
1073 if (!tx.fOverwintered) {
1074 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
1075 REJECT_INVALID, "tx-overwinter-active");
1078 // Check that all transactions are unexpired
1079 if (IsExpiredTx(tx, nHeight)) {
1080 // Don't increase banscore if the transaction only just expired
1081 int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? (dosLevel > 10 ? dosLevel : 10) : 0;
1082 return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
1086 // Rules that apply before Sapling:
1087 if (!saplingActive) {
1089 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1090 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_BEFORE_SAPLING)
1091 return state.DoS(100, error("ContextualCheckTransaction(): size limits failed"),
1092 REJECT_INVALID, "bad-txns-oversize");
1095 uint256 dataToBeSigned;
1098 (!tx.vjoinsplit.empty() ||
1099 !tx.vShieldedSpend.empty() ||
1100 !tx.vShieldedOutput.empty()))
1102 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
1103 // Empty output script.
1106 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1107 } catch (std::logic_error ex) {
1108 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
1109 REJECT_INVALID, "error-computing-signature-hash");
1114 if (!(tx.IsMint() || tx.vjoinsplit.empty()))
1116 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
1118 // We rely on libsodium to check that the signature is canonical.
1119 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1120 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1121 dataToBeSigned.begin(), 32,
1122 tx.joinSplitPubKey.begin()
1124 return state.DoS(isInitBlockDownload() ? 0 : 100,
1125 error("CheckTransaction(): invalid joinsplit signature"),
1126 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1130 if (tx.IsCoinBase())
1132 if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1133 return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1134 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
1137 if (!tx.vShieldedSpend.empty() ||
1138 !tx.vShieldedOutput.empty())
1140 auto ctx = librustzcash_sapling_verification_ctx_init();
1142 for (const SpendDescription &spend : tx.vShieldedSpend) {
1143 if (!librustzcash_sapling_check_spend(
1146 spend.anchor.begin(),
1147 spend.nullifier.begin(),
1149 spend.zkproof.begin(),
1150 spend.spendAuthSig.begin(),
1151 dataToBeSigned.begin()
1154 librustzcash_sapling_verification_ctx_free(ctx);
1155 return state.DoS(100, error("ContextualCheckTransaction(): Sapling spend description invalid"),
1156 REJECT_INVALID, "bad-txns-sapling-spend-description-invalid");
1160 for (const OutputDescription &output : tx.vShieldedOutput) {
1161 if (!librustzcash_sapling_check_output(
1165 output.ephemeralKey.begin(),
1166 output.zkproof.begin()
1169 librustzcash_sapling_verification_ctx_free(ctx);
1170 return state.DoS(100, error("ContextualCheckTransaction(): Sapling output description invalid"),
1171 REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
1175 if (!librustzcash_sapling_final_check(
1178 tx.bindingSig.begin(),
1179 dataToBeSigned.begin()
1182 librustzcash_sapling_verification_ctx_free(ctx);
1183 return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
1184 REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
1187 librustzcash_sapling_verification_ctx_free(ctx);
1192 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1193 libzcash::ProofVerifier& verifier)
1195 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1196 if ( *(int32_t *)&array[0] == 0 )
1197 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1201 for (k=0; k<numbanned; k++)
1203 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1205 static uint32_t counter;
1206 if ( counter++ < 100 )
1207 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->GetHeight(),j);
1212 // Don't count coinbase transactions because mining skews the count
1213 if (!tx.IsCoinBase()) {
1214 transactionsValidated.increment();
1217 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1220 // Ensure that zk-SNARKs v|| y
1221 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1222 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1223 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1224 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1231 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1233 // Basic checks that don't depend on any context
1237 * 1. The consensus rule below was:
1238 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1239 * which checked if tx.nVersion fell within the range:
1240 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1241 * 2. The parser allowed tx.nVersion to be negative
1244 * 1. The consensus rule checks to see if tx.Version falls within the range:
1245 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1246 * 2. The previous consensus rule checked for negative values within the range:
1247 * INT32_MIN <= tx.nVersion < 0
1248 * This is unnecessary for Overwinter transactions since the parser now
1249 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1250 * and when Overwinter is not active ContextualCheckTransaction rejects
1251 * transactions with fOverwintered set. When fOverwintered is set,
1252 * this function and ContextualCheckTransaction will together check to
1253 * ensure tx.nVersion avoids the following ranges:
1254 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1255 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1257 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1258 return state.DoS(100, error("CheckTransaction(): version too low"),
1259 REJECT_INVALID, "bad-txns-version-too-low");
1261 else if (tx.fOverwintered) {
1262 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1263 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1264 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1266 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID &&
1267 tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1268 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1269 REJECT_INVALID, "bad-tx-version-group-id");
1271 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1272 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1273 REJECT_INVALID, "bad-tx-expiry-height-too-high");
1277 // Transactions containing empty `vin` must have either non-empty
1278 // `vjoinsplit` or non-empty `vShieldedSpend`.
1279 if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
1280 return state.DoS(10, error("CheckTransaction(): vin empty"),
1281 REJECT_INVALID, "bad-txns-vin-empty");
1282 // Transactions containing empty `vout` must have either non-empty
1283 // `vjoinsplit` or non-empty `vShieldedOutput`.
1284 if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
1285 return state.DoS(10, error("CheckTransaction(): vout empty"),
1286 REJECT_INVALID, "bad-txns-vout-empty");
1289 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE >= MAX_TX_SIZE_AFTER_SAPLING); // sanity
1290 BOOST_STATIC_ASSERT(MAX_TX_SIZE_AFTER_SAPLING > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1291 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_AFTER_SAPLING)
1292 return state.DoS(100, error("CheckTransaction(): size limits failed"),
1293 REJECT_INVALID, "bad-txns-oversize");
1295 // Check for negative or overflow output values
1296 CAmount nValueOut = 0;
1297 int32_t iscoinbase = tx.IsCoinBase();
1298 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1300 if (txout.nValue < 0)
1301 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1302 REJECT_INVALID, "bad-txns-vout-negative");
1303 if (txout.nValue > MAX_MONEY)
1305 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1306 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1308 if ( ASSETCHAINS_PRIVATE != 0 )
1310 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
1311 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetValueOut() > 0 )
1312 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
1314 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
1315 return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative");
1316 nValueOut += txout.nValue;
1317 if (!MoneyRange(nValueOut))
1318 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1319 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1322 // Check for non-zero valueBalance when there are no Sapling inputs or outputs
1323 if (tx.vShieldedSpend.empty() && tx.vShieldedOutput.empty() && tx.valueBalance != 0) {
1324 return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"),
1325 REJECT_INVALID, "bad-txns-valuebalance-nonzero");
1328 // Check for overflow valueBalance
1329 if (tx.valueBalance > MAX_MONEY || tx.valueBalance < -MAX_MONEY) {
1330 return state.DoS(100, error("CheckTransaction(): abs(tx.valueBalance) too large"),
1331 REJECT_INVALID, "bad-txns-valuebalance-toolarge");
1334 if (tx.valueBalance <= 0) {
1335 // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
1336 nValueOut += -tx.valueBalance;
1338 if (!MoneyRange(nValueOut)) {
1339 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1340 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1344 // Ensure that joinsplit values are well-formed
1345 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1347 if ( ASSETCHAINS_PUBLIC != 0 )
1349 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1350 REJECT_INVALID, "bad-txns-acprivacy-chain");
1352 if (joinsplit.vpub_old < 0) {
1353 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1354 REJECT_INVALID, "bad-txns-vpub_old-negative");
1357 if (joinsplit.vpub_new < 0) {
1358 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1359 REJECT_INVALID, "bad-txns-vpub_new-negative");
1362 if (joinsplit.vpub_old > MAX_MONEY) {
1363 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1364 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1367 if (joinsplit.vpub_new > MAX_MONEY) {
1368 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1369 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1372 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1373 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1374 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1377 nValueOut += joinsplit.vpub_old;
1378 if (!MoneyRange(nValueOut)) {
1379 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1380 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1384 // Ensure input values do not exceed MAX_MONEY
1385 // We have not resolved the txin values at this stage,
1386 // but we do know what the joinsplits claim to add
1387 // to the value pool.
1389 CAmount nValueIn = 0;
1390 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1392 nValueIn += it->vpub_new;
1394 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1395 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1396 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1400 // Also check for Sapling
1401 if (tx.valueBalance >= 0) {
1402 // NB: positive valueBalance "adds" money to the transparent value pool, just as inputs do
1403 nValueIn += tx.valueBalance;
1405 if (!MoneyRange(nValueIn)) {
1406 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1407 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1412 // Check for duplicate inputs
1413 set<COutPoint> vInOutPoints;
1414 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1416 if (vInOutPoints.count(txin.prevout))
1417 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1418 REJECT_INVALID, "bad-txns-inputs-duplicate");
1419 vInOutPoints.insert(txin.prevout);
1422 // Check for duplicate joinsplit nullifiers in this transaction
1424 set<uint256> vJoinSplitNullifiers;
1425 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1427 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1429 if (vJoinSplitNullifiers.count(nf))
1430 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1431 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1433 vJoinSplitNullifiers.insert(nf);
1438 // Check for duplicate sapling nullifiers in this transaction
1440 set<uint256> vSaplingNullifiers;
1441 BOOST_FOREACH(const SpendDescription& spend_desc, tx.vShieldedSpend)
1443 if (vSaplingNullifiers.count(spend_desc.nullifier))
1444 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1445 REJECT_INVALID, "bad-spend-description-nullifiers-duplicate");
1447 vSaplingNullifiers.insert(spend_desc.nullifier);
1453 // There should be no joinsplits in a coinbase transaction
1454 if (tx.vjoinsplit.size() > 0)
1455 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1456 REJECT_INVALID, "bad-cb-has-joinsplits");
1458 // A coinbase transaction cannot have spend descriptions or output descriptions
1459 if (tx.vShieldedSpend.size() > 0)
1460 return state.DoS(100, error("CheckTransaction(): coinbase has spend descriptions"),
1461 REJECT_INVALID, "bad-cb-has-spend-description");
1462 if (tx.vShieldedOutput.size() > 0)
1463 return state.DoS(100, error("CheckTransaction(): coinbase has output descriptions"),
1464 REJECT_INVALID, "bad-cb-has-output-description");
1466 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1467 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1468 REJECT_INVALID, "bad-cb-length");
1472 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1473 if (txin.prevout.IsNull())
1474 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1475 REJECT_INVALID, "bad-txns-prevout-null");
1481 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1483 extern int32_t KOMODO_ON_DEMAND;
1486 uint256 hash = tx.GetHash();
1487 double dPriorityDelta = 0;
1488 CAmount nFeeDelta = 0;
1489 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1490 if (dPriorityDelta > 0 || nFeeDelta > 0)
1494 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1498 // There is a free transaction area in blocks created by most miners,
1499 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1500 // to be considered to fall into this category. We don't want to encourage sending
1501 // multiple transactions instead of one big transaction to avoid fees.
1502 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1506 if (!MoneyRange(nMinFee))
1507 nMinFee = MAX_MONEY;
1512 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel)
1514 AssertLockHeld(cs_main);
1515 if (pfMissingInputs)
1516 *pfMissingInputs = false;
1518 int flag=0,nextBlockHeight = chainActive.Height() + 1;
1519 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1521 // Node operator can choose to reject tx by number of transparent inputs
1522 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1523 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1524 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
1528 size_t n = tx.vin.size();
1530 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1535 // if this is a valid stake transaction, don't put it in the mempool
1537 if (ValidateStakeTransaction(tx, p, false))
1539 return state.DoS(0, error("AcceptToMemoryPool: attempt to add staking transaction to the mempool"),
1540 REJECT_INVALID, "staking");
1543 auto verifier = libzcash::ProofVerifier::Strict();
1544 if ( komodo_validate_interest(tx,chainActive.LastTip()->GetHeight()+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
1546 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1547 return error("AcceptToMemoryPool: komodo_validate_interest failed");
1549 if (!CheckTransaction(tx, state, verifier))
1551 return error("AcceptToMemoryPool: CheckTransaction failed");
1553 // DoS level set to 10 to be more forgiving.
1554 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1555 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, (dosLevel == -1) ? 10 : dosLevel))
1557 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1559 // Coinbase is only valid in a block, not as a loose transaction
1560 if (tx.IsCoinBase())
1562 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1563 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1565 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1567 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1570 //fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\nscriptPubKey: %s\n",reason.c_str(),tx.vout[0].scriptPubKey.ToString().c_str());
1571 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1573 // Only accept nLockTime-using transactions that can be mined in the next
1574 // block; we don't want our mempool filled up with transactions that can't
1576 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1578 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1579 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1582 // is it already in the memory pool?
1583 uint256 hash = tx.GetHash();
1584 if (pool.exists(hash))
1586 //fprintf(stderr,"already in mempool\n");
1587 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
1590 // Check for conflicts with in-memory transactions
1592 LOCK(pool.cs); // protect pool.mapNextTx
1593 for (unsigned int i = 0; i < tx.vin.size(); i++)
1595 COutPoint outpoint = tx.vin[i].prevout;
1596 if (pool.mapNextTx.count(outpoint))
1598 // Disable replacement feature for now
1602 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1603 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
1604 if (pool.nullifierExists(nf, SPROUT)) {
1605 fprintf(stderr,"pool.mapNullifiers.count\n");
1610 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
1611 if (pool.nullifierExists(spendDescription.nullifier, SAPLING)) {
1619 CCoinsViewCache view(&dummy);
1621 CAmount nValueIn = 0;
1624 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1625 view.SetBackend(viewMemPool);
1627 // do we already have it?
1628 if (view.HaveCoins(hash))
1630 //fprintf(stderr,"view.HaveCoins(hash) error\n");
1631 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
1634 if (tx.IsCoinImport())
1636 // Inverse of normal case; if input exists, it's been spent
1637 if (ExistsImportTombstone(tx, view))
1638 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
1642 // do all inputs exist?
1643 // Note that this does not check for the presence of actual outputs (see the next check for that),
1644 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1645 BOOST_FOREACH(const CTxIn txin, tx.vin)
1647 if (!view.HaveCoins(txin.prevout.hash))
1649 if (pfMissingInputs)
1650 *pfMissingInputs = true;
1651 //fprintf(stderr,"missing inputs\n");
1652 return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing");
1656 // are the actual inputs available?
1657 if (!view.HaveInputs(tx))
1659 //fprintf(stderr,"accept failure.1\n");
1660 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1663 // are the joinsplit's requirements met?
1664 if (!view.HaveJoinSplitRequirements(tx))
1666 //fprintf(stderr,"accept failure.2\n");
1667 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1670 // Bring the best block into scope
1671 view.GetBestBlock();
1673 nValueIn = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime);
1674 if ( 0 && interest != 0 )
1675 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1676 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1677 view.SetBackend(dummy);
1680 // Check for non-standard pay-to-script-hash in inputs
1681 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1682 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1684 // Check that the transaction doesn't have an excessive number of
1685 // sigops, making it impossible to mine. Since the coinbase transaction
1686 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1687 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1688 // merely non-standard transaction.
1689 unsigned int nSigOps = GetLegacySigOpCount(tx);
1690 nSigOps += GetP2SHSigOpCount(tx, view);
1691 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1693 fprintf(stderr,"accept failure.4\n");
1694 return state.DoS(1, error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
1697 CAmount nValueOut = tx.GetValueOut();
1698 CAmount nFees = nValueIn-nValueOut;
1699 double dPriority = view.GetPriority(tx, chainActive.Height());
1701 // Keep track of transactions that spend a coinbase, which we re-scan
1702 // during reorgs to ensure COINBASE_MATURITY is still met.
1703 bool fSpendsCoinbase = false;
1704 if (!tx.IsCoinImport()) {
1705 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1706 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1707 if (coins->IsCoinBase()) {
1708 fSpendsCoinbase = true;
1714 // Grab the branch ID we expect this transaction to commit to. We don't
1715 // yet know if it does, but if the entry gets added to the mempool, then
1716 // it has passed ContextualCheckInputs and therefore this is correct.
1717 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1719 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1720 unsigned int nSize = entry.GetTxSize();
1722 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1723 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1724 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1726 // Don't accept it if it can't get into a block
1727 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1728 if (fLimitFree && nFees < txMinFee)
1730 //fprintf(stderr,"accept failure.5\n");
1731 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1735 // Require that free transactions have sufficient priority to be mined in the next block.
1736 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1737 fprintf(stderr,"accept failure.6\n");
1738 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1741 // Continuously rate-limit free (really, very-low-fee) transactions
1742 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1743 // be annoying or make others' transactions take longer to confirm.
1744 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1746 static CCriticalSection csFreeLimiter;
1747 static double dFreeCount;
1748 static int64_t nLastTime;
1749 int64_t nNow = GetTime();
1751 LOCK(csFreeLimiter);
1753 // Use an exponentially decaying ~10-minute window:
1754 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1756 // -limitfreerelay unit is thousand-bytes-per-minute
1757 // At default rate it would take over a month to fill 1GB
1758 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1760 fprintf(stderr,"accept failure.7\n");
1761 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1763 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1764 dFreeCount += nSize;
1767 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
1769 string errmsg = strprintf("absurdly high fees %s, %d > %d",
1771 nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1772 LogPrint("mempool", errmsg.c_str());
1773 return state.Error("AcceptToMemoryPool: " + errmsg);
1776 // Check against previous transactions
1777 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1778 PrecomputedTransactionData txdata(tx);
1779 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1781 //fprintf(stderr,"accept failure.9\n");
1782 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1785 // Check again against just the consensus-critical mandatory script
1786 // verification flags, in case of bugs in the standard flags that cause
1787 // transactions to pass as valid when they're actually invalid. For
1788 // instance the STRICTENC flag was incorrectly allowing certain
1789 // CHECKSIG NOT scripts to pass, even though they were invalid.
1791 // There is a similar check in CreateNewBlock() to prevent creating
1792 // invalid blocks, however allowing such transactions into the mempool
1793 // can be exploited as a DoS attack.
1794 // XXX: is this neccesary for CryptoConditions?
1795 if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 )
1798 KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->GetHeight() + 1;
1800 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1803 KOMODO_CONNECTING = -1;
1804 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1807 KOMODO_CONNECTING = -1;
1809 // Store transaction in memory
1810 if ( komodo_is_notarytx(tx) == 0 )
1812 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1814 if (!tx.IsCoinImport())
1816 // Add memory address index
1817 if (fAddressIndex) {
1818 pool.addAddressIndex(entry, view);
1821 // Add memory spent index
1823 pool.addSpentIndex(entry, view);
1828 SyncWithWallets(tx, NULL);
1833 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1835 if (!fTimestampIndex)
1836 return error("Timestamp index not enabled");
1838 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1839 return error("Unable to get hashes for timestamps");
1844 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1849 if (mempool.getSpentIndex(key, value))
1852 if (!pblocktree->ReadSpentIndex(key, value))
1858 bool GetAddressIndex(uint160 addressHash, int type,
1859 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1862 return error("address index not enabled");
1864 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1865 return error("unable to get txids for address");
1870 bool GetAddressUnspent(uint160 addressHash, int type,
1871 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1874 return error("address index not enabled");
1876 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1877 return error("unable to get txids for address");
1882 /*uint64_t myGettxout(uint256 hash,int32_t n)
1885 LOCK2(cs_main,mempool.cs);
1886 CCoinsViewMemPool view(pcoinsTip, mempool);
1887 if (!view.GetCoins(hash, coins))
1889 if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
1891 else return(coins.vout[n].nValue);
1894 bool myAddtomempool(CTransaction &tx)
1896 CValidationState state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
1897 if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
1898 return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
1902 bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1904 // need a GetTransaction without lock so the validation code for assets can run without deadlock
1906 //fprintf(stderr,"check mempool\n");
1907 if (mempool.lookup(hash, txOut))
1909 //fprintf(stderr,"found in mempool\n");
1913 //fprintf(stderr,"check disk\n");
1917 //fprintf(stderr,"ReadTxIndex\n");
1918 if (pblocktree->ReadTxIndex(hash, postx)) {
1919 //fprintf(stderr,"OpenBlockFile\n");
1920 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1922 return error("%s: OpenBlockFile failed", __func__);
1923 CBlockHeader header;
1924 //fprintf(stderr,"seek and read\n");
1927 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1929 } catch (const std::exception& e) {
1930 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1932 hashBlock = header.GetHash();
1933 if (txOut.GetHash() != hash)
1934 return error("%s: txid mismatch", __func__);
1935 //fprintf(stderr,"found on disk\n");
1939 //fprintf(stderr,"not found\n");
1943 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1944 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1946 CBlockIndex *pindexSlow = NULL;
1950 if (mempool.lookup(hash, txOut))
1957 if (pblocktree->ReadTxIndex(hash, postx)) {
1958 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1960 return error("%s: OpenBlockFile failed", __func__);
1961 CBlockHeader header;
1964 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1966 } catch (const std::exception& e) {
1967 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1969 hashBlock = header.GetHash();
1970 if (txOut.GetHash() != hash)
1971 return error("%s: txid mismatch", __func__);
1976 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1979 CCoinsViewCache &view = *pcoinsTip;
1980 const CCoins* coins = view.AccessCoins(hash);
1982 nHeight = coins->nHeight;
1985 pindexSlow = chainActive[nHeight];
1990 if (ReadBlockFromDisk(block, pindexSlow,1)) {
1991 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1992 if (tx.GetHash() == hash) {
1994 hashBlock = pindexSlow->GetBlockHash();
2004 /*char *komodo_getspendscript(uint256 hash,int32_t n)
2006 CTransaction tx; uint256 hashBlock;
2007 if ( !GetTransaction(hash,tx,hashBlock,true) )
2009 printf("null GetTransaction\n");
2012 if ( n >= 0 && n < tx.vout.size() )
2013 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
2014 else printf("getspendscript illegal n.%d\n",n);
2019 //////////////////////////////////////////////////////////////////////////////
2021 // CBlock and CBlockIndex
2024 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
2026 // Open history file to append
2027 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
2028 if (fileout.IsNull())
2029 return error("WriteBlockToDisk: OpenBlockFile failed");
2031 // Write index header
2032 unsigned int nSize = GetSerializeSize(fileout, block);
2033 fileout << FLATDATA(messageStart) << nSize;
2036 long fileOutPos = ftell(fileout.Get());
2038 return error("WriteBlockToDisk: ftell failed");
2039 pos.nPos = (unsigned int)fileOutPos;
2045 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
2047 uint8_t pubkey33[33];
2050 // Open history file to read
2051 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
2052 if (filein.IsNull())
2054 //fprintf(stderr,"readblockfromdisk err A\n");
2055 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
2062 catch (const std::exception& e) {
2063 fprintf(stderr,"readblockfromdisk err B\n");
2064 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
2067 if ( 0 && checkPOW != 0 )
2069 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
2070 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
2072 int32_t i; for (i=0; i<33; i++)
2073 fprintf(stderr,"%02x",pubkey33[i]);
2074 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
2076 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
2082 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
2086 if (!ReadBlockFromDisk(pindex->GetHeight(),block, pindex->GetBlockPos(),checkPOW))
2088 if (block.GetHash() != pindex->GetBlockHash())
2089 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
2090 pindex->ToString(), pindex->GetBlockPos().ToString());
2094 //uint64_t komodo_moneysupply(int32_t height);
2095 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
2096 extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
2097 extern uint32_t ASSETCHAINS_MAGIC;
2098 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
2099 extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
2101 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
2103 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
2104 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2107 return(100000000 * COIN); // ICO allocation
2108 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
2114 return(komodo_ac_block_subsidy(nHeight));
2117 // Mining slow start
2118 // The subsidy is ramped up linearly, skipping the middle payout of
2119 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
2120 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
2121 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2122 nSubsidy *= nHeight;
2124 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
2125 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2126 nSubsidy *= (nHeight+1);
2130 assert(nHeight > consensusParams.SubsidySlowStartShift());
2131 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
2132 // Force block reward to zero when right shift is undefined.
2133 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
2134 //if (halvings >= 64)
2137 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
2138 //nSubsidy >>= halvings;
2142 bool IsInitialBlockDownload()
2144 const CChainParams& chainParams = Params();
2146 // Once this function has returned false, it must remain false.
2147 static std::atomic<bool> latchToFalse{false};
2148 // Optimization: pre-test latch before taking the lock.
2149 if (latchToFalse.load(std::memory_order_relaxed))
2153 if (latchToFalse.load(std::memory_order_relaxed))
2156 if (fImporting || fReindex)
2158 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2162 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2164 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload - %d blocks\n", Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2169 arith_uint256 bigZero = arith_uint256();
2170 arith_uint256 minWork = UintToArith256(chainParams.GetConsensus().nMinimumChainWork);
2171 CBlockIndex *ptr = chainActive.Tip();
2175 if (ptr->chainPower < CChainPower(ptr, bigZero, minWork))
2178 state = ((chainActive.Height() < ptr->GetHeight() - 24*60) ||
2179 ptr->GetBlockTime() < (GetTime() - nMaxTipAge));
2181 //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()));
2184 LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
2185 latchToFalse.store(true, std::memory_order_relaxed);
2190 // determine if we are in sync with the best chain
2193 const CChainParams& chainParams = Params();
2196 if (fImporting || fReindex)
2198 //fprintf(stderr,"IsNotInSync: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2201 if (fCheckpointsEnabled)
2203 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2205 //fprintf(stderr,"IsNotInSync: checkpoint -> initialdownload chainActive.Height().%d GetTotalBlocksEstimate(chainParams.Checkpoints().%d\n", chainActive.Height(), Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2210 CBlockIndex *pbi = chainActive.Tip();
2211 int longestchain = komodo_longestchain();
2213 (pindexBestHeader == 0) ||
2214 ((pindexBestHeader->GetHeight() - 1) > pbi->GetHeight()) ||
2215 (longestchain != 0 && longestchain > pbi->GetHeight()) )
2217 return (pbi && pindexBestHeader && (pindexBestHeader->GetHeight() - 1) > pbi->GetHeight()) ?
2218 pindexBestHeader->GetHeight() - pbi->GetHeight() :
2225 static bool fLargeWorkForkFound = false;
2226 static bool fLargeWorkInvalidChainFound = false;
2227 static CBlockIndex *pindexBestForkTip = NULL;
2228 static CBlockIndex *pindexBestForkBase = NULL;
2230 void CheckForkWarningConditions()
2232 AssertLockHeld(cs_main);
2233 // Before we get past initial download, we cannot reliably alert about forks
2234 // (we assume we don't get stuck on a fork before finishing our initial sync)
2235 if (IsInitialBlockDownload())
2238 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
2239 // of our head, drop it
2240 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->GetHeight() >= 288)
2241 pindexBestForkTip = NULL;
2243 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->chainPower > (chainActive.LastTip()->chainPower + (GetBlockProof(*chainActive.LastTip()) * 6))))
2245 if (!fLargeWorkForkFound && pindexBestForkBase)
2247 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
2248 pindexBestForkBase->phashBlock->ToString() + std::string("'");
2249 CAlert::Notify(warning, true);
2251 if (pindexBestForkTip && pindexBestForkBase)
2253 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__,
2254 pindexBestForkBase->GetHeight(), pindexBestForkBase->phashBlock->ToString(),
2255 pindexBestForkTip->GetHeight(), pindexBestForkTip->phashBlock->ToString());
2256 fLargeWorkForkFound = true;
2260 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
2261 LogPrintf("%s: %s\n", warning.c_str(), __func__);
2262 CAlert::Notify(warning, true);
2263 fLargeWorkInvalidChainFound = true;
2268 fLargeWorkForkFound = false;
2269 fLargeWorkInvalidChainFound = false;
2273 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
2275 AssertLockHeld(cs_main);
2276 // If we are on a fork that is sufficiently large, set a warning flag
2277 CBlockIndex* pfork = pindexNewForkTip;
2278 CBlockIndex* plonger = chainActive.LastTip();
2279 while (pfork && pfork != plonger)
2281 while (plonger && plonger->GetHeight() > pfork->GetHeight())
2282 plonger = plonger->pprev;
2283 if (pfork == plonger)
2285 pfork = pfork->pprev;
2288 // We define a condition where we should warn the user about as a fork of at least 7 blocks
2289 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
2290 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
2291 // hash rate operating on the fork.
2292 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
2293 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
2294 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
2295 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->GetHeight() > pindexBestForkTip->GetHeight())) &&
2296 pindexNewForkTip->chainPower - pfork->chainPower > (GetBlockProof(*pfork) * 7) &&
2297 chainActive.Height() - pindexNewForkTip->GetHeight() < 72)
2299 pindexBestForkTip = pindexNewForkTip;
2300 pindexBestForkBase = pfork;
2303 CheckForkWarningConditions();
2306 // Requires cs_main.
2307 void Misbehaving(NodeId pnode, int howmuch)
2312 CNodeState *state = State(pnode);
2316 state->nMisbehavior += howmuch;
2317 int banscore = GetArg("-banscore", 101);
2318 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
2320 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2321 state->fShouldBan = true;
2323 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2326 void static InvalidChainFound(CBlockIndex* pindexNew)
2328 if (!pindexBestInvalid || pindexNew->chainPower > pindexBestInvalid->chainPower)
2329 pindexBestInvalid = pindexNew;
2331 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2332 pindexNew->GetBlockHash().ToString(), pindexNew->GetHeight(),
2333 log(pindexNew->chainPower.chainWork.getdouble())/log(2.0),
2334 log(pindexNew->chainPower.chainStake.getdouble())/log(2.0),
2335 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()));
2336 CBlockIndex *tip = chainActive.LastTip();
2338 LogPrintf("%s: current best=%s height=%d log2_work=%.8g log2_stake=%.8g date=%s\n", __func__,
2339 tip->GetBlockHash().ToString(), chainActive.Height(),
2340 log(tip->chainPower.chainWork.getdouble())/log(2.0),
2341 log(tip->chainPower.chainStake.getdouble())/log(2.0),
2342 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
2343 CheckForkWarningConditions();
2346 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2348 if (state.IsInvalid(nDoS)) {
2349 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2350 if (it != mapBlockSource.end() && State(it->second)) {
2351 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
2352 State(it->second)->rejects.push_back(reject);
2354 Misbehaving(it->second, nDoS);
2357 if (!state.CorruptionPossible()) {
2358 pindex->nStatus |= BLOCK_FAILED_VALID;
2359 setDirtyBlockIndex.insert(pindex);
2360 setBlockIndexCandidates.erase(pindex);
2361 InvalidChainFound(pindex);
2365 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
2367 if (!tx.IsMint()) // mark inputs spent
2369 txundo.vprevout.reserve(tx.vin.size());
2370 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
2371 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2372 unsigned nPos = txin.prevout.n;
2374 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2376 // mark an outpoint spent, and construct undo information
2377 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2379 if (coins->vout.size() == 0) {
2380 CTxInUndo& undo = txundo.vprevout.back();
2381 undo.nHeight = coins->nHeight;
2382 undo.fCoinBase = coins->fCoinBase;
2383 undo.nVersion = coins->nVersion;
2389 inputs.SetNullifiers(tx, true);
2391 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2394 if (tx.IsCoinImport()) {
2395 // add a tombstone for the burnTx
2396 AddImportTombstone(tx, inputs, nHeight);
2400 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2403 UpdateCoins(tx, inputs, txundo, nHeight);
2406 bool CScriptCheck::operator()() {
2407 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2408 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2409 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
2410 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2415 int GetSpendHeight(const CCoinsViewCache& inputs)
2418 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2419 return pindexPrev->GetHeight() + 1;
2422 namespace Consensus {
2423 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2425 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2426 // for an attacker to attempt to split the network.
2427 if (!inputs.HaveInputs(tx))
2428 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2430 // are the JoinSplit's requirements met?
2431 if (!inputs.HaveJoinSplitRequirements(tx))
2432 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2434 CAmount nValueIn = 0;
2436 for (unsigned int i = 0; i < tx.vin.size(); i++)
2438 const COutPoint &prevout = tx.vin[i].prevout;
2439 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2442 if (coins->IsCoinBase()) {
2443 // ensure that output of coinbases are not still time locked
2444 if (coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE)
2446 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2447 if (nSpendHeight < unlockTime) {
2448 return state.DoS(10,
2449 error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2450 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2454 // Ensure that coinbases are matured, no DoS as retry may work later
2455 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2457 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2458 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2461 // Ensure that coinbases cannot be spent to transparent outputs
2462 // Disabled on regtest
2463 if (fCoinbaseEnforcedProtectionEnabled &&
2464 consensusParams.fCoinbaseMustBeProtected &&
2465 !(tx.vout.size() == 0 || (tx.vout.size() == 1 && tx.vout[0].nValue == 0)) &&
2466 (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
2467 return state.DoS(100,
2468 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2469 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2473 // Check for negative or overflow input values
2474 nValueIn += coins->vout[prevout.n].nValue;
2475 #ifdef KOMODO_ENABLE_INTEREST
2476 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() >= 60000 )
2478 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2480 int64_t interest; int32_t txheight; uint32_t locktime;
2481 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2483 //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);
2484 nValueIn += interest;
2489 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2490 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2491 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2495 nValueIn += tx.GetShieldedValueIn();
2496 if (!MoneyRange(nValueIn))
2497 return state.DoS(100, error("CheckInputs(): shielded input to transparent value pool out of range"),
2498 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2500 if (nValueIn < tx.GetValueOut())
2502 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2503 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2504 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2506 // Tally transaction fees
2507 CAmount nTxFee = nValueIn - tx.GetValueOut();
2509 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2510 REJECT_INVALID, "bad-txns-fee-negative");
2512 if (!MoneyRange(nFees))
2513 return state.DoS(100, error("CheckInputs(): nFees out of range"),
2514 REJECT_INVALID, "bad-txns-fee-outofrange");
2517 }// namespace Consensus
2519 bool ContextualCheckInputs(
2520 const CTransaction& tx,
2521 CValidationState &state,
2522 const CCoinsViewCache &inputs,
2526 PrecomputedTransactionData& txdata,
2527 const Consensus::Params& consensusParams,
2528 uint32_t consensusBranchId,
2529 std::vector<CScriptCheck> *pvChecks)
2533 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2538 pvChecks->reserve(tx.vin.size());
2540 // The first loop above does all the inexpensive checks.
2541 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2542 // Helps prevent CPU exhaustion attacks.
2544 // Skip ECDSA signature verification when connecting blocks
2545 // before the last block chain checkpoint. This is safe because block merkle hashes are
2546 // still computed and checked, and any change will be caught at the next checkpoint.
2547 if (fScriptChecks) {
2548 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2549 const COutPoint &prevout = tx.vin[i].prevout;
2550 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2554 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2556 pvChecks->push_back(CScriptCheck());
2557 check.swap(pvChecks->back());
2558 } else if (!check()) {
2559 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2560 // Check whether the failure was caused by a
2561 // non-mandatory script verification check, such as
2562 // non-standard DER encodings or non-null dummy
2563 // arguments; if so, don't trigger DoS protection to
2564 // avoid splitting the network between upgraded and
2565 // non-upgraded nodes.
2566 CScriptCheck check2(*coins, tx, i,
2567 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2569 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2571 // Failures of other flags indicate a transaction that is
2572 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2573 // such nodes as they are not following the protocol. That
2574 // said during an upgrade careful thought should be taken
2575 // as to the correct behavior - we may want to continue
2576 // peering with non-upgraded nodes even after a soft-fork
2577 // super-majority vote has passed.
2578 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2584 if (tx.IsCoinImport())
2586 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2587 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2594 /*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)
2596 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2597 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2601 if (!tx.IsCoinBase())
2603 // While checking, GetBestBlock() refers to the parent block.
2604 // This is also true for mempool checks.
2605 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2606 int nSpendHeight = pindexPrev->GetHeight() + 1;
2607 for (unsigned int i = 0; i < tx.vin.size(); i++)
2609 const COutPoint &prevout = tx.vin[i].prevout;
2610 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2611 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2615 // If prev is coinbase, check that it's matured
2616 if (coins->IsCoinBase()) {
2617 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2618 COINBASE_MATURITY = _COINBASE_MATURITY;
2619 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2620 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2622 return state.Invalid(
2623 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2634 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2636 // Open history file to append
2637 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2638 if (fileout.IsNull())
2639 return error("%s: OpenUndoFile failed", __func__);
2641 // Write index header
2642 unsigned int nSize = GetSerializeSize(fileout, blockundo);
2643 fileout << FLATDATA(messageStart) << nSize;
2646 long fileOutPos = ftell(fileout.Get());
2648 return error("%s: ftell failed", __func__);
2649 pos.nPos = (unsigned int)fileOutPos;
2650 fileout << blockundo;
2652 // calculate & write checksum
2653 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2654 hasher << hashBlock;
2655 hasher << blockundo;
2656 fileout << hasher.GetHash();
2661 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2663 // Open history file to read
2664 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2665 if (filein.IsNull())
2666 return error("%s: OpenBlockFile failed", __func__);
2669 uint256 hashChecksum;
2671 filein >> blockundo;
2672 filein >> hashChecksum;
2674 catch (const std::exception& e) {
2675 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2678 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2679 hasher << hashBlock;
2680 hasher << blockundo;
2681 if (hashChecksum != hasher.GetHash())
2682 return error("%s: Checksum mismatch", __func__);
2687 /** Abort with a message */
2688 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2690 strMiscWarning = strMessage;
2691 LogPrintf("*** %s\n", strMessage);
2692 uiInterface.ThreadSafeMessageBox(
2693 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2694 "", CClientUIInterface::MSG_ERROR);
2699 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2701 AbortNode(strMessage, userMessage);
2702 return state.Error(strMessage);
2708 * Apply the undo operation of a CTxInUndo to the given chain state.
2709 * @param undo The undo object.
2710 * @param view The coins view to which to apply the changes.
2711 * @param out The out point that corresponds to the tx input.
2712 * @return True on success.
2714 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2718 CCoinsModifier coins = view.ModifyCoins(out.hash);
2719 if (undo.nHeight != 0) {
2720 // undo data contains height: this is the last output of the prevout tx being spent
2721 if (!coins->IsPruned())
2722 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2724 coins->fCoinBase = undo.fCoinBase;
2725 coins->nHeight = undo.nHeight;
2726 coins->nVersion = undo.nVersion;
2728 if (coins->IsPruned())
2729 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2731 if (coins->IsAvailable(out.n))
2732 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2733 if (coins->vout.size() < out.n+1)
2734 coins->vout.resize(out.n+1);
2735 coins->vout[out.n] = undo.txout;
2741 void ConnectNotarisations(const CBlock &block, int height)
2743 // Record Notarisations
2744 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2745 if (notarisations.size() > 0) {
2746 CDBBatch batch = CDBBatch(*pnotarisations);
2747 batch.Write(block.GetHash(), notarisations);
2748 WriteBackNotarisations(notarisations, batch);
2749 pnotarisations->WriteBatch(batch, true);
2750 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2751 notarisations.size(), block.GetHash().GetHex().data());
2756 void DisconnectNotarisations(const CBlock &block)
2758 // Delete from notarisations cache
2759 NotarisationsInBlock nibs;
2760 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2761 CDBBatch batch = CDBBatch(*pnotarisations);
2762 batch.Erase(block.GetHash());
2763 EraseBackNotarisations(nibs, batch);
2764 pnotarisations->WriteBatch(batch, true);
2765 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2766 nibs.size(), block.GetHash().GetHex().data());
2771 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2773 assert(pindex->GetBlockHash() == view.GetBestBlock());
2779 komodo_disconnect(pindex,block);
2780 CBlockUndo blockUndo;
2781 CDiskBlockPos pos = pindex->GetUndoPos();
2783 return error("DisconnectBlock(): no undo data available");
2784 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2785 return error("DisconnectBlock(): failure reading undo data");
2787 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2788 return error("DisconnectBlock(): block and undo data inconsistent");
2789 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2790 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2791 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2793 // undo transactions in reverse order
2794 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2795 const CTransaction &tx = block.vtx[i];
2796 uint256 hash = tx.GetHash();
2797 if (fAddressIndex) {
2799 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2800 const CTxOut &out = tx.vout[k];
2802 if (out.scriptPubKey.IsPayToScriptHash()) {
2803 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2805 // undo receiving activity
2806 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2808 // undo unspent index
2809 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2812 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2813 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2815 // undo receiving activity
2816 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2818 // undo unspent index
2819 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2822 else if (out.scriptPubKey.IsPayToPublicKey()) {
2823 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2825 // undo receiving activity
2826 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2828 // undo unspent index
2829 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2832 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2833 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2835 // undo receiving activity
2836 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, k, false), out.nValue));
2838 // undo unspent index
2839 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2850 // Check that all outputs are available and match the outputs in the block itself
2853 CCoinsModifier outs = view.ModifyCoins(hash);
2854 outs->ClearUnspendable();
2856 CCoins outsBlock(tx, pindex->GetHeight());
2857 // The CCoins serialization does not serialize negative numbers.
2858 // No network rules currently depend on the version here, so an inconsistency is harmless
2859 // but it must be corrected before txout nversion ever influences a network rule.
2860 if (outsBlock.nVersion < 0)
2861 outs->nVersion = outsBlock.nVersion;
2862 if (*outs != outsBlock)
2863 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2869 // unspend nullifiers
2870 view.SetNullifiers(tx, false);
2874 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2875 if (txundo.vprevout.size() != tx.vin.size())
2876 return error("DisconnectBlock(): transaction and undo data inconsistent");
2877 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2878 const COutPoint &out = tx.vin[j].prevout;
2879 const CTxInUndo &undo = txundo.vprevout[j];
2880 if (!ApplyTxInUndo(undo, view, out))
2883 const CTxIn input = tx.vin[j];
2886 // undo and delete the spent index
2887 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2890 if (fAddressIndex) {
2891 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2892 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2893 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2895 // undo spending activity
2896 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2898 // restore unspent index
2899 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2903 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2904 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2906 // undo spending activity
2907 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2909 // restore unspent index
2910 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2913 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2914 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2916 // undo spending activity
2917 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2919 // restore unspent index
2920 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2923 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2924 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2926 // undo spending activity
2927 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, hash, j, true), prevout.nValue * -1));
2929 // restore unspent index
2930 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2939 else if (tx.IsCoinImport())
2941 RemoveImportTombstone(tx, view);
2945 // set the old best Sprout anchor back
2946 view.PopAnchor(blockUndo.old_sprout_tree_root, SPROUT);
2948 // set the old best Sapling anchor back
2949 // We can get this from the `hashFinalSaplingRoot` of the last block
2950 // However, this is only reliable if the last block was on or after
2951 // the Sapling activation height. Otherwise, the last anchor was the
2953 if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2954 view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING);
2956 view.PopAnchor(SaplingMerkleTree::empty_root(), SAPLING);
2959 // move best block pointer to prevout block
2960 view.SetBestBlock(pindex->pprev->GetBlockHash());
2967 if (fAddressIndex) {
2968 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2969 return AbortNode(state, "Failed to delete address index");
2971 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2972 return AbortNode(state, "Failed to write address unspent index");
2979 void static FlushBlockFile(bool fFinalize = false)
2981 LOCK(cs_LastBlockFile);
2983 CDiskBlockPos posOld(nLastBlockFile, 0);
2985 FILE *fileOld = OpenBlockFile(posOld);
2988 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2989 FileCommit(fileOld);
2993 fileOld = OpenUndoFile(posOld);
2996 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2997 FileCommit(fileOld);
3002 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
3004 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
3006 void ThreadScriptCheck() {
3007 RenameThread("zcash-scriptch");
3008 scriptcheckqueue.Thread();
3012 // Called periodically asynchronously; alerts if it smells like
3013 // we're being fed a bad chain (blocks being generated much
3014 // too slowly or too quickly).
3016 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
3017 int64_t nPowTargetSpacing)
3019 if (bestHeader == NULL || initialDownloadCheck()) return;
3021 static int64_t lastAlertTime = 0;
3022 int64_t now = GetAdjustedTime();
3023 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
3025 const int SPAN_HOURS=4;
3026 const int SPAN_SECONDS=SPAN_HOURS*60*60;
3027 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
3029 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
3031 std::string strWarning;
3032 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
3035 const CBlockIndex* i = bestHeader;
3037 while (i->GetBlockTime() >= startTime) {
3040 if (i == NULL) return; // Ran out of chain, we must not be fully synced
3043 // How likely is it to find that many by chance?
3044 double p = boost::math::pdf(poisson, nBlocks);
3046 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
3047 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
3049 // Aim for one false-positive about every fifty years of normal running:
3050 const int FIFTY_YEARS = 50*365*24*60*60;
3051 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
3053 if (bestHeader->GetHeight() > BLOCKS_EXPECTED)
3055 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
3057 // Many fewer blocks than expected: alert!
3058 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
3059 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3061 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
3063 // Many more blocks than expected: alert!
3064 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
3065 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3068 if (!strWarning.empty())
3070 strMiscWarning = strWarning;
3071 CAlert::Notify(strWarning, true);
3072 lastAlertTime = now;
3077 static int64_t nTimeVerify = 0;
3078 static int64_t nTimeConnect = 0;
3079 static int64_t nTimeIndex = 0;
3080 static int64_t nTimeCallbacks = 0;
3081 static int64_t nTimeTotal = 0;
3083 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
3085 const CChainParams& chainparams = Params();
3086 if ( KOMODO_STOPAT != 0 && pindex->GetHeight() > KOMODO_STOPAT )
3088 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight());
3089 AssertLockHeld(cs_main);
3090 bool fExpensiveChecks = true;
3091 if (fCheckpointsEnabled) {
3092 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
3093 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->GetHeight()) == pindex) {
3094 // This block is an ancestor of a checkpoint: disable script checks
3095 fExpensiveChecks = false;
3098 auto verifier = libzcash::ProofVerifier::Strict();
3099 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
3100 int32_t futureblock;
3101 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
3102 if (!CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
3104 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
3108 // verify that the view's current state corresponds to the previous block
3109 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
3110 if ( hashPrevBlock != view.GetBestBlock() )
3112 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
3113 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
3114 REJECT_INVALID, "hashPrevBlock-not-bestblock");
3116 assert(hashPrevBlock == view.GetBestBlock());
3118 // Special case for the genesis block, skipping connection of its transactions
3119 // (its coinbase is unspendable)
3120 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
3122 view.SetBestBlock(pindex->GetBlockHash());
3123 // Before the genesis block, there was an empty tree
3124 SproutMerkleTree tree;
3125 pindex->hashSproutAnchor = tree.root();
3126 // The genesis block contained no JoinSplits
3127 pindex->hashFinalSproutRoot = pindex->hashSproutAnchor;
3132 bool fScriptChecks = (!fCheckpointsEnabled || pindex->GetHeight() >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
3133 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->GetHeight() > KOMODO_TESTNET_EXPIRATION ) // "testnet"
3135 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
3136 // unless those are already completely spent.
3137 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
3138 const CCoins* coins = view.AccessCoins(tx.GetHash());
3139 if (coins && !coins->IsPruned())
3140 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
3141 REJECT_INVALID, "bad-txns-BIP30");
3144 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
3146 // DERSIG (BIP66) is also always enforced, but does not have a flag.
3148 CBlockUndo blockundo;
3150 if ( ASSETCHAINS_CC != 0 )
3152 if ( scriptcheckqueue.IsIdle() == 0 )
3154 fprintf(stderr,"scriptcheckqueue isnt idle\n");
3158 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
3160 int64_t nTimeStart = GetTimeMicros();
3163 int64_t interest,sum = 0;
3164 unsigned int nSigOps = 0;
3165 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
3166 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
3167 vPos.reserve(block.vtx.size());
3168 blockundo.vtxundo.reserve(block.vtx.size() - 1);
3169 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
3170 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
3171 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
3172 // Construct the incremental merkle tree at the current
3174 auto old_sprout_tree_root = view.GetBestAnchor(SPROUT);
3175 // saving the top anchor in the block index as we go.
3177 pindex->hashSproutAnchor = old_sprout_tree_root;
3180 SproutMerkleTree sprout_tree;
3182 // This should never fail: we should always be able to get the root
3183 // that is on the tip of our chain
3184 assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
3187 // Consistency check: the root of the tree we're given should
3188 // match what we asked for.
3189 assert(sprout_tree.root() == old_sprout_tree_root);
3192 SaplingMerkleTree sapling_tree;
3193 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
3195 // Grab the consensus branch ID for the block's height
3196 auto consensusBranchId = CurrentEpochBranchId(pindex->GetHeight(), Params().GetConsensus());
3198 std::vector<PrecomputedTransactionData> txdata;
3199 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
3200 for (unsigned int i = 0; i < block.vtx.size(); i++)
3202 const CTransaction &tx = block.vtx[i];
3203 const uint256 txhash = tx.GetHash();
3204 nInputs += tx.vin.size();
3205 nSigOps += GetLegacySigOpCount(tx);
3206 if (nSigOps > MAX_BLOCK_SIGOPS)
3207 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3208 REJECT_INVALID, "bad-blk-sigops");
3209 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->GetHeight(),tx.nLockTime);
3212 if (!view.HaveInputs(tx))
3214 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
3215 REJECT_INVALID, "bad-txns-inputs-missingorspent");
3217 // are the JoinSplit's requirements met?
3218 if (!view.HaveJoinSplitRequirements(tx))
3219 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
3220 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
3221 if (fAddressIndex || fSpentIndex)
3223 for (size_t j = 0; j < tx.vin.size(); j++) {
3225 const CTxIn input = tx.vin[j];
3226 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
3230 if (prevout.scriptPubKey.IsPayToScriptHash()) {
3231 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
3234 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
3235 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
3238 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
3239 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
3242 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
3243 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
3247 hashBytes.SetNull();
3251 if (fAddressIndex && addressType > 0) {
3252 // record spending activity
3253 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->GetHeight(), i, txhash, j, true), prevout.nValue * -1));
3255 // remove address from unspent index
3256 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
3260 // add the spent index to determine the txid and input that spent an output
3261 // and to find the amount and address from an input
3262 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->GetHeight(), prevout.nValue, addressType, hashBytes)));
3267 // Add in sigops done by pay-to-script-hash inputs;
3268 // this is to prevent a "rogue miner" from creating
3269 // an incredibly-expensive-to-validate block.
3270 nSigOps += GetP2SHSigOpCount(tx, view);
3271 if (nSigOps > MAX_BLOCK_SIGOPS)
3272 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3273 REJECT_INVALID, "bad-blk-sigops");
3276 txdata.emplace_back(tx);
3278 if (!tx.IsCoinBase())
3280 nFees += view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
3283 std::vector<CScriptCheck> vChecks;
3284 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
3286 control.Add(vChecks);
3289 if (fAddressIndex) {
3290 for (unsigned int k = 0; k < tx.vout.size(); k++) {
3291 const CTxOut &out = tx.vout[k];
3292 //fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
3293 if (out.scriptPubKey.IsPayToScriptHash()) {
3294 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
3296 // record receiving activity
3297 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3299 // record unspent output
3300 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3303 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
3304 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
3306 // record receiving activity
3307 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3309 // record unspent output
3310 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3313 else if (out.scriptPubKey.IsPayToPublicKey()) {
3314 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
3316 // record receiving activity
3317 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3319 // record unspent output
3320 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3323 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
3324 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
3326 // record receiving activity
3327 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->GetHeight(), i, txhash, k, false), out.nValue));
3329 // record unspent output
3330 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->GetHeight())));
3340 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3341 // komodo_earned_interest(pindex->GetHeight(),sum);
3344 blockundo.vtxundo.push_back(CTxUndo());
3346 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight());
3348 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
3349 BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
3350 // Insert the note commitments into our temporary tree.
3352 sprout_tree.append(note_commitment);
3356 BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) {
3357 sapling_tree.append(outputDescription.cm);
3360 vPos.push_back(std::make_pair(tx.GetHash(), pos));
3361 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
3364 view.PushAnchor(sprout_tree);
3365 view.PushAnchor(sapling_tree);
3367 pindex->hashFinalSproutRoot = sprout_tree.root();
3369 blockundo.old_sprout_tree_root = old_sprout_tree_root;
3371 // If Sapling is active, block.hashFinalSaplingRoot must be the
3372 // same as the root of the Sapling tree
3373 if (NetworkUpgradeActive(pindex->GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3374 if (block.hashFinalSaplingRoot != sapling_tree.root()) {
3375 return state.DoS(100,
3376 error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"),
3377 REJECT_INVALID, "bad-sapling-root-in-block");
3380 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3381 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);
3383 CAmount blockReward = nFees + GetBlockSubsidy(pindex->GetHeight(), chainparams.GetConsensus()) + sum;
3384 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
3386 uint64_t checktoshis;
3387 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
3389 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
3390 blockReward += checktoshis;
3391 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
3394 if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->GetHeight() == 1 && block.vtx[0].GetValueOut() != blockReward)
3396 return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
3397 REJECT_INVALID, "bad-cb-amount");
3399 if ( block.vtx[0].GetValueOut() > blockReward+1 )
3401 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->GetHeight() >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
3403 return state.DoS(100,
3404 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3405 block.vtx[0].GetValueOut(), blockReward),
3406 REJECT_INVALID, "bad-cb-amount");
3407 } else if ( IS_KOMODO_NOTARY != 0 )
3408 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));
3410 if (!control.Wait())
3411 return state.DoS(100, false);
3412 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3413 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);
3418 // Write undo information to disk
3419 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
3421 if (pindex->GetUndoPos().IsNull()) {
3423 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
3424 return error("ConnectBlock(): FindUndoPos failed");
3425 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
3426 return AbortNode(state, "Failed to write undo data");
3428 // update nUndoPos in block index
3429 pindex->nUndoPos = pos.nPos;
3430 pindex->nStatus |= BLOCK_HAVE_UNDO;
3433 // Now that all consensus rules have been validated, set nCachedBranchId.
3434 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3435 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
3436 "nCachedBranchId must be set after all consensus rules have been validated.");
3437 if (IsActivationHeightForAnyUpgrade(pindex->GetHeight(), Params().GetConsensus())) {
3438 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
3439 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->GetHeight(), chainparams.GetConsensus());
3440 } else if (pindex->pprev) {
3441 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
3444 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
3445 setDirtyBlockIndex.insert(pindex);
3448 ConnectNotarisations(block, pindex->GetHeight());
3451 if (!pblocktree->WriteTxIndex(vPos))
3452 return AbortNode(state, "Failed to write transaction index");
3453 if (fAddressIndex) {
3454 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3455 return AbortNode(state, "Failed to write address index");
3458 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3459 return AbortNode(state, "Failed to write address unspent index");
3464 if (!pblocktree->UpdateSpentIndex(spentIndex))
3465 return AbortNode(state, "Failed to write transaction index");
3467 if (fTimestampIndex) {
3468 unsigned int logicalTS = pindex->nTime;
3469 unsigned int prevLogicalTS = 0;
3471 // retrieve logical timestamp of the previous block
3473 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3474 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3476 if (logicalTS <= prevLogicalTS) {
3477 logicalTS = prevLogicalTS + 1;
3478 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3481 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3482 return AbortNode(state, "Failed to write timestamp index");
3484 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3485 return AbortNode(state, "Failed to write blockhash index");
3488 // add this block to the view's block chain
3489 view.SetBestBlock(pindex->GetBlockHash());
3491 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3492 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
3494 // Watch for changes to the previous coinbase transaction.
3495 static uint256 hashPrevBestCoinBase;
3496 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
3497 hashPrevBestCoinBase = block.vtx[0].GetHash();
3499 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3500 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
3502 //FlushStateToDisk();
3503 komodo_connectblock(pindex,*(CBlock *)&block);
3507 enum FlushStateMode {
3509 FLUSH_STATE_IF_NEEDED,
3510 FLUSH_STATE_PERIODIC,
3515 * Update the on-disk chain state.
3516 * The caches and indexes are flushed depending on the mode we're called with
3517 * if they're too large, if it's been a while since the last write,
3518 * or always and in all cases if we're in prune mode and are deleting files.
3520 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
3521 LOCK2(cs_main, cs_LastBlockFile);
3522 static int64_t nLastWrite = 0;
3523 static int64_t nLastFlush = 0;
3524 static int64_t nLastSetChain = 0;
3525 std::set<int> setFilesToPrune;
3526 bool fFlushForPrune = false;
3528 if (fPruneMode && fCheckForPruning && !fReindex) {
3529 FindFilesToPrune(setFilesToPrune);
3530 fCheckForPruning = false;
3531 if (!setFilesToPrune.empty()) {
3532 fFlushForPrune = true;
3534 pblocktree->WriteFlag("prunedblockfiles", true);
3539 int64_t nNow = GetTimeMicros();
3540 // Avoid writing/flushing immediately after startup.
3541 if (nLastWrite == 0) {
3544 if (nLastFlush == 0) {
3547 if (nLastSetChain == 0) {
3548 nLastSetChain = nNow;
3550 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3551 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3552 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3553 // The cache is over the limit, we have to write now.
3554 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3555 // 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.
3556 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3557 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3558 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3559 // Combine all conditions that result in a full cache flush.
3560 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3561 // Write blocks and block index to disk.
3562 if (fDoFullFlush || fPeriodicWrite) {
3563 // Depend on nMinDiskSpace to ensure we can write block index
3564 if (!CheckDiskSpace(0))
3565 return state.Error("out of disk space");
3566 // First make sure all block and undo data is flushed to disk.
3568 // Then update all block file information (which may refer to block and undo files).
3570 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3571 vFiles.reserve(setDirtyFileInfo.size());
3572 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3573 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3574 setDirtyFileInfo.erase(it++);
3576 std::vector<const CBlockIndex*> vBlocks;
3577 vBlocks.reserve(setDirtyBlockIndex.size());
3578 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3579 vBlocks.push_back(*it);
3580 setDirtyBlockIndex.erase(it++);
3582 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3583 return AbortNode(state, "Files to write to block index database");
3586 // Finally remove any pruned files
3588 UnlinkPrunedFiles(setFilesToPrune);
3591 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3593 // Typical CCoins structures on disk are around 128 bytes in size.
3594 // Pushing a new one to the database can cause it to be written
3595 // twice (once in the log, and once in the tables). This is already
3596 // an overestimation, as most will delete an existing entry or
3597 // overwrite one. Still, use a conservative safety factor of 2.
3598 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3599 return state.Error("out of disk space");
3600 // Flush the chainstate (which may refer to block index entries).
3601 if (!pcoinsTip->Flush())
3602 return AbortNode(state, "Failed to write to coin database");
3605 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3606 // Update best block in wallet (so we can detect restored wallets).
3607 GetMainSignals().SetBestChain(chainActive.GetLocator());
3608 nLastSetChain = nNow;
3610 } catch (const std::runtime_error& e) {
3611 return AbortNode(state, std::string("System error while flushing: ") + e.what());
3616 void FlushStateToDisk() {
3617 CValidationState state;
3618 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3621 void PruneAndFlush() {
3622 CValidationState state;
3623 fCheckForPruning = true;
3624 FlushStateToDisk(state, FLUSH_STATE_NONE);
3627 /** Update chainActive and related internal data structures. */
3628 void static UpdateTip(CBlockIndex *pindexNew) {
3629 const CChainParams& chainParams = Params();
3630 chainActive.SetTip(pindexNew);
3633 nTimeBestReceived = GetTime();
3634 mempool.AddTransactionsUpdated(1);
3637 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
3638 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
3640 int32_t longestchain = komodo_longestchain();
3641 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
3644 LogPrintf("%s: new best=%s height=%d log2_work=%.8g log2_stake=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
3645 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3646 log(chainActive.Tip()->chainPower.chainWork.getdouble())/log(2.0),
3647 log(chainActive.Tip()->chainPower.chainStake.getdouble())/log(2.0),
3648 (unsigned long)chainActive.LastTip()->nChainTx,
3649 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
3650 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3652 cvBlockChange.notify_all();
3654 // Check the version of the last 100 blocks to see if we need to upgrade:
3655 static bool fWarned = false;
3656 if (!IsInitialBlockDownload() && !fWarned)
3659 const CBlockIndex* pindex = chainActive.Tip();
3660 for (int i = 0; i < 100 && pindex != NULL; i++)
3662 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3664 pindex = pindex->pprev;
3667 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3668 if (nUpgraded > 100/2)
3670 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3671 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3672 CAlert::Notify(strMiscWarning, true);
3679 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3680 * mempool.removeWithoutBranchId after this, with cs_main held.
3682 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3683 CBlockIndex *pindexDelete = chainActive.Tip();
3684 assert(pindexDelete);
3685 // Read block from disk.
3687 if (!ReadBlockFromDisk(block, pindexDelete,1))
3688 return AbortNode(state, "Failed to read block");
3689 // Apply the block atomically to the chain state.
3690 uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3691 uint256 saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3692 int64_t nStart = GetTimeMicros();
3694 CCoinsViewCache view(pcoinsTip);
3695 if (!DisconnectBlock(block, state, pindexDelete, view))
3696 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3697 assert(view.Flush());
3698 DisconnectNotarisations(block);
3700 pindexDelete->segid = -2;
3701 pindexDelete->newcoins = 0;
3702 pindexDelete->zfunds = 0;
3704 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3705 uint256 sproutAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3706 uint256 saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3707 // Write the chain state to disk, if necessary.
3708 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3712 // resurrect mempool transactions from the disconnected block.
3713 for (int i = 0; i < block.vtx.size(); i++)
3715 // ignore validation errors in resurrected transactions
3716 CTransaction &tx = block.vtx[i];
3717 list<CTransaction> removed;
3718 CValidationState stateDummy;
3720 // don't keep staking or invalid transactions
3721 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3723 mempool.remove(tx, removed, true);
3726 // if this is a staking tx, and we are on Verus Sapling with nothing at stake solution,
3727 // save staking tx as a possible cheat
3728 if (NetworkUpgradeActive(pindexDelete->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING) &&
3729 ASSETCHAINS_LWMAPOS && (i == (block.vtx.size() - 1)) &&
3730 (block.IsVerusPOSBlock()))
3732 CTxHolder txh = CTxHolder(block.vtx[i], pindexDelete->GetHeight());
3736 if (sproutAnchorBeforeDisconnect != sproutAnchorAfterDisconnect) {
3737 // The anchor may not change between block disconnects,
3738 // in which case we don't want to evict from the mempool yet!
3739 mempool.removeWithAnchor(sproutAnchorBeforeDisconnect, SPROUT);
3741 if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) {
3742 // The anchor may not change between block disconnects,
3743 // in which case we don't want to evict from the mempool yet!
3744 mempool.removeWithAnchor(saplingAnchorBeforeDisconnect, SAPLING);
3748 // Update chainActive and related variables.
3749 UpdateTip(pindexDelete->pprev);
3751 // Get the current commitment tree
3752 SproutMerkleTree newSproutTree;
3753 SaplingMerkleTree newSaplingTree;
3754 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
3755 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
3756 // Let wallets know transactions went from 1-confirmed to
3757 // 0-confirmed or conflicted:
3758 for (int i = 0; i < block.vtx.size(); i++)
3760 CTransaction &tx = block.vtx[i];
3761 if ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
3763 EraseFromWallets(tx.GetHash());
3767 SyncWithWallets(tx, NULL);
3770 // Update cached incremental witnesses
3771 GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
3775 static int64_t nTimeReadFromDisk = 0;
3776 static int64_t nTimeConnectTotal = 0;
3777 static int64_t nTimeFlush = 0;
3778 static int64_t nTimeChainState = 0;
3779 static int64_t nTimePostConnect = 0;
3782 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3783 * corresponding to pindexNew, to bypass loading it again from disk.
3784 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3786 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3788 assert(pindexNew->pprev == chainActive.Tip());
3789 // Read block from disk.
3790 int64_t nTime1 = GetTimeMicros();
3793 if (!ReadBlockFromDisk(block, pindexNew,1))
3794 return AbortNode(state, "Failed to read block");
3797 KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight();
3798 // Get the current commitment tree
3799 SproutMerkleTree oldSproutTree;
3800 SaplingMerkleTree oldSaplingTree;
3801 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
3802 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
3803 // Apply the block atomically to the chain state.
3804 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3806 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3808 CCoinsViewCache view(pcoinsTip);
3809 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3810 KOMODO_CONNECTING = -1;
3811 GetMainSignals().BlockChecked(*pblock, state);
3813 if (state.IsInvalid())
3814 InvalidBlockFound(pindexNew, state);
3815 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3817 mapBlockSource.erase(pindexNew->GetBlockHash());
3818 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3819 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3820 assert(view.Flush());
3822 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3823 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3824 // Write the chain state to disk, if necessary.
3825 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3827 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3828 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3829 // Remove conflicting transactions from the mempool.
3830 list<CTransaction> txConflicted;
3831 mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload());
3833 // Remove transactions that expire at new block height from mempool
3834 mempool.removeExpired(pindexNew->GetHeight());
3836 // Update chainActive & related variables.
3837 UpdateTip(pindexNew);
3838 // Tell wallet about transactions that went from mempool
3840 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3841 SyncWithWallets(tx, NULL);
3843 // ... and about transactions that got confirmed:
3844 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3845 SyncWithWallets(tx, pblock);
3847 // Update cached incremental witnesses
3848 GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
3850 EnforceNodeDeprecation(pindexNew->GetHeight());
3852 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3853 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3854 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3855 if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->GetHeight() >= KOMODO_LONGESTCHAIN )
3857 else KOMODO_INSYNC = 0;
3858 //fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->GetHeight(),KOMODO_INSYNC);
3859 if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
3860 komodo_broadcast(pblock,8);
3865 * Return the tip of the chain with the most work in it, that isn't
3866 * known to be invalid (it's however far from certain to be valid).
3868 static CBlockIndex* FindMostWorkChain() {
3870 CBlockIndex *pindexNew = NULL;
3872 // Find the best candidate header.
3874 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3875 if (it == setBlockIndexCandidates.rend())
3880 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3881 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3882 CBlockIndex *pindexTest = pindexNew;
3883 bool fInvalidAncestor = false;
3884 while (pindexTest && !chainActive.Contains(pindexTest)) {
3885 assert(pindexTest->nChainTx || pindexTest->GetHeight() == 0);
3887 // Pruned nodes may have entries in setBlockIndexCandidates for
3888 // which block files have been deleted. Remove those as candidates
3889 // for the most work chain if we come across them; we can't switch
3890 // to a chain unless we have all the non-active-chain parent blocks.
3891 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3892 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3893 if (fFailedChain || fMissingData) {
3894 // Candidate chain is not usable (either invalid or missing data)
3895 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->chainPower > pindexBestInvalid->chainPower))
3896 pindexBestInvalid = pindexNew;
3897 CBlockIndex *pindexFailed = pindexNew;
3898 // Remove the entire chain from the set.
3899 while (pindexTest != pindexFailed) {
3901 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3902 } else if (fMissingData) {
3903 // If we're missing data, then add back to mapBlocksUnlinked,
3904 // so that if the block arrives in the future we can try adding
3905 // to setBlockIndexCandidates again.
3906 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3908 setBlockIndexCandidates.erase(pindexFailed);
3909 pindexFailed = pindexFailed->pprev;
3911 setBlockIndexCandidates.erase(pindexTest);
3912 fInvalidAncestor = true;
3915 pindexTest = pindexTest->pprev;
3917 if (!fInvalidAncestor)
3922 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3923 static void PruneBlockIndexCandidates() {
3924 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3925 // reorganization to a better block fails.
3926 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3927 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
3928 setBlockIndexCandidates.erase(it++);
3930 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3931 assert(!setBlockIndexCandidates.empty());
3935 * Try to make some progress towards making pindexMostWork the active block.
3936 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3938 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3939 AssertLockHeld(cs_main);
3940 bool fInvalidFound = false;
3941 const CBlockIndex *pindexOldTip = chainActive.Tip();
3942 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3944 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3945 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3946 // then pindexFork will be null, and we would need to remove the entire chain including
3947 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3948 auto reorgLength = pindexOldTip ? pindexOldTip->GetHeight() - (pindexFork ? pindexFork->GetHeight() : -1) : 0;
3949 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3950 if (reorgLength > MAX_REORG_LENGTH) {
3951 auto msg = strprintf(_(
3952 "A block chain reorganization has been detected that would roll back %d blocks! "
3953 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3954 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3955 _("Reorganization details") + ":\n" +
3956 "- " + strprintf(_("Current tip: %s, height %d, work %s\nstake %s"),
3957 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight(), pindexOldTip->chainPower.chainWork.GetHex(),
3958 pindexOldTip->chainPower.chainStake.GetHex()) + "\n" +
3959 "- " + strprintf(_("New tip: %s, height %d, work %s\nstake %s"),
3960 pindexMostWork->phashBlock->GetHex(), pindexMostWork->GetHeight(), pindexMostWork->chainPower.chainWork.GetHex(),
3961 pindexMostWork->chainPower.chainStake.GetHex()) + "\n" +
3962 "- " + strprintf(_("Fork point: %s %s, height %d"),
3963 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->GetHeight()) + "\n\n" +
3964 _("Please help, human!");
3965 LogPrintf("*** %s\n", msg);
3966 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3971 // Disconnect active blocks which are no longer in the best chain.
3972 bool fBlocksDisconnected = false;
3974 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3975 if (!DisconnectTip(state))
3977 fBlocksDisconnected = true;
3979 if ( KOMODO_REWIND != 0 )
3981 CBlockIndex *tipindex;
3982 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->GetHeight(),KOMODO_REWIND);
3983 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->GetHeight() > KOMODO_REWIND )
3985 fBlocksDisconnected = true;
3986 fprintf(stderr,"%d ",(int32_t)tipindex->GetHeight());
3987 InvalidateBlock(state,tipindex);
3988 if ( !DisconnectTip(state) )
3991 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3993 fprintf(stderr,"resuming normal operations\n");
3997 // Build list of new blocks to connect.
3998 std::vector<CBlockIndex*> vpindexToConnect;
3999 bool fContinue = true;
4000 int nHeight = pindexFork ? pindexFork->GetHeight() : -1;
4001 while (fContinue && nHeight != pindexMostWork->GetHeight()) {
4002 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
4003 // a few blocks along the way.
4004 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->GetHeight());
4005 vpindexToConnect.clear();
4006 vpindexToConnect.reserve(nTargetHeight - nHeight);
4007 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
4008 while (pindexIter && pindexIter->GetHeight() != nHeight) {
4009 vpindexToConnect.push_back(pindexIter);
4010 pindexIter = pindexIter->pprev;
4012 nHeight = nTargetHeight;
4014 // Connect new blocks.
4015 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
4016 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
4017 if (state.IsInvalid()) {
4018 // The block violates a consensus rule.
4019 if (!state.CorruptionPossible())
4020 InvalidChainFound(vpindexToConnect.back());
4021 state = CValidationState();
4022 fInvalidFound = true;
4026 // A system error occurred (disk space, database error, ...).
4030 PruneBlockIndexCandidates();
4031 if (!pindexOldTip || chainActive.Tip()->chainPower > pindexOldTip->chainPower) {
4032 // We're in a better position than we were. Return temporarily to release the lock.
4040 if (fBlocksDisconnected) {
4041 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4043 mempool.removeWithoutBranchId(
4044 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4045 mempool.check(pcoinsTip);
4047 // Callbacks/notifications for a new best chain.
4049 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
4051 CheckForkWarningConditions();
4057 * Make the best chain active, in multiple steps. The result is either failure
4058 * or an activated best chain. pblock is either NULL or a pointer to a block
4059 * that is already loaded (to avoid loading it again from disk).
4061 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
4062 CBlockIndex *pindexNewTip = NULL;
4063 CBlockIndex *pindexMostWork = NULL;
4064 const CChainParams& chainParams = Params();
4066 boost::this_thread::interruption_point();
4068 bool fInitialDownload;
4071 pindexMostWork = FindMostWorkChain();
4073 // Whether we have anything to do at all.
4074 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
4077 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
4079 pindexNewTip = chainActive.Tip();
4080 fInitialDownload = IsInitialBlockDownload();
4082 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
4084 // Notifications/callbacks that can run without cs_main
4085 if (!fInitialDownload) {
4086 uint256 hashNewTip = pindexNewTip->GetBlockHash();
4087 // Relay inventory, but don't relay old inventory during initial block download.
4088 int nBlockEstimate = 0;
4089 if (fCheckpointsEnabled)
4090 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
4091 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
4092 // in a stalled download if the block file is pruned before the request.
4093 if (nLocalServices & NODE_NETWORK) {
4095 BOOST_FOREACH(CNode* pnode, vNodes)
4096 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
4097 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
4099 // Notify external listeners about the new tip.
4100 GetMainSignals().UpdatedBlockTip(pindexNewTip);
4101 uiInterface.NotifyBlockTip(hashNewTip);
4102 } //else fprintf(stderr,"initial download skips propagation\n");
4103 } while(pindexMostWork != chainActive.Tip());
4106 // Write changes periodically to disk, after relay.
4107 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
4114 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
4115 AssertLockHeld(cs_main);
4117 // Mark the block itself as invalid.
4118 pindex->nStatus |= BLOCK_FAILED_VALID;
4119 setDirtyBlockIndex.insert(pindex);
4120 setBlockIndexCandidates.erase(pindex);
4122 while (chainActive.Contains(pindex)) {
4123 CBlockIndex *pindexWalk = chainActive.Tip();
4124 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
4125 setDirtyBlockIndex.insert(pindexWalk);
4126 setBlockIndexCandidates.erase(pindexWalk);
4127 // ActivateBestChain considers blocks already in chainActive
4128 // unconditionally valid already, so force disconnect away from it.
4129 if (!DisconnectTip(state)) {
4130 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4131 mempool.removeWithoutBranchId(
4132 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4136 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
4138 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
4140 BlockMap::iterator it = mapBlockIndex.begin();
4141 while (it != mapBlockIndex.end()) {
4142 if ((it->second != 0) && it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
4143 setBlockIndexCandidates.insert(it->second);
4148 InvalidChainFound(pindex);
4149 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->GetHeight() + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4150 mempool.removeWithoutBranchId(
4151 CurrentEpochBranchId(chainActive.Tip()->GetHeight() + 1, Params().GetConsensus()));
4155 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
4156 AssertLockHeld(cs_main);
4158 int nHeight = pindex->GetHeight();
4160 // Remove the invalidity flag from this block and all its descendants.
4161 BlockMap::iterator it = mapBlockIndex.begin();
4162 while (it != mapBlockIndex.end()) {
4163 if ((it->second != 0) && !it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
4164 it->second->nStatus &= ~BLOCK_FAILED_MASK;
4165 setDirtyBlockIndex.insert(it->second);
4166 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
4167 setBlockIndexCandidates.insert(it->second);
4169 if (it->second == pindexBestInvalid) {
4170 // Reset invalid block marker if it was pointing to one of those.
4171 pindexBestInvalid = NULL;
4177 // Remove the invalidity flag from all ancestors too.
4178 while (pindex != NULL) {
4179 if (pindex->nStatus & BLOCK_FAILED_MASK) {
4180 pindex->nStatus &= ~BLOCK_FAILED_MASK;
4181 setDirtyBlockIndex.insert(pindex);
4183 pindex = pindex->pprev;
4188 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
4190 // Check for duplicate
4191 uint256 hash = block.GetHash();
4192 BlockMap::iterator it = mapBlockIndex.find(hash);
4193 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
4195 // the following block is for debugging, comment when not needed
4197 std::vector<BlockMap::iterator> vrit;
4198 for (BlockMap::iterator bit = mapBlockIndex.begin(); bit != mapBlockIndex.end(); bit++)
4200 if (bit->second == NULL)
4201 vrit.push_back(bit);
4205 printf("found %d NULL blocks in mapBlockIndex\n", vrit.size());
4209 if (it != mapBlockIndex.end())
4211 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
4213 // 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
4214 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
4217 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
4219 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
4220 return(0); // return here to avoid the state of pindex->GetHeight() not set and pprev NULL
4223 // Construct new block index object
4224 CBlockIndex* pindexNew = new CBlockIndex(block);
4226 // We assign the sequence id to blocks only when the full data is available,
4227 // to avoid miners withholding blocks but broadcasting headers, to get a
4228 // competitive advantage.
4229 pindexNew->nSequenceId = 0;
4230 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4231 pindexNew->phashBlock = &((*mi).first);
4232 if (miPrev != mapBlockIndex.end())
4234 if ( (pindexNew->pprev = (*miPrev).second) != 0 )
4235 pindexNew->SetHeight(pindexNew->pprev->GetHeight() + 1);
4236 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
4237 pindexNew->BuildSkip();
4239 pindexNew->chainPower = (pindexNew->pprev ? CChainPower(pindexNew) + pindexNew->pprev->chainPower : CChainPower(pindexNew)) + GetBlockProof(*pindexNew);
4240 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
4241 if (pindexBestHeader == NULL || pindexBestHeader->chainPower < pindexNew->chainPower)
4242 pindexBestHeader = pindexNew;
4244 setDirtyBlockIndex.insert(pindexNew);
4245 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
4246 mi->second = pindexNew;
4250 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
4251 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
4253 pindexNew->nTx = block.vtx.size();
4254 pindexNew->nChainTx = 0;
4255 CAmount sproutValue = 0;
4256 CAmount saplingValue = 0;
4257 for (auto tx : block.vtx) {
4258 // Negative valueBalance "takes" money from the transparent value pool
4259 // and adds it to the Sapling value pool. Positive valueBalance "gives"
4260 // money to the transparent value pool, removing from the Sapling value
4261 // pool. So we invert the sign here.
4262 saplingValue += -tx.valueBalance;
4264 for (auto js : tx.vjoinsplit) {
4265 sproutValue += js.vpub_old;
4266 sproutValue -= js.vpub_new;
4269 pindexNew->nSproutValue = sproutValue;
4270 pindexNew->nChainSproutValue = boost::none;
4271 pindexNew->nSaplingValue = saplingValue;
4272 pindexNew->nChainSaplingValue = boost::none;
4273 pindexNew->nFile = pos.nFile;
4274 pindexNew->nDataPos = pos.nPos;
4275 pindexNew->nUndoPos = 0;
4276 pindexNew->nStatus |= BLOCK_HAVE_DATA;
4277 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
4278 setDirtyBlockIndex.insert(pindexNew);
4280 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
4281 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
4282 deque<CBlockIndex*> queue;
4283 queue.push_back(pindexNew);
4285 // Recursively process any descendant blocks that now may be eligible to be connected.
4286 while (!queue.empty()) {
4287 CBlockIndex *pindex = queue.front();
4289 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
4290 if (pindex->pprev) {
4291 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4292 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4294 pindex->nChainSproutValue = boost::none;
4296 if (pindex->pprev->nChainSaplingValue) {
4297 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
4299 pindex->nChainSaplingValue = boost::none;
4302 pindex->nChainSproutValue = pindex->nSproutValue;
4303 pindex->nChainSaplingValue = pindex->nSaplingValue;
4306 LOCK(cs_nBlockSequenceId);
4307 pindex->nSequenceId = nBlockSequenceId++;
4309 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
4310 setBlockIndexCandidates.insert(pindex);
4312 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
4313 while (range.first != range.second) {
4314 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
4315 queue.push_back(it->second);
4317 mapBlocksUnlinked.erase(it);
4321 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
4322 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
4329 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
4331 LOCK(cs_LastBlockFile);
4333 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
4334 if (vinfoBlockFile.size() <= nFile) {
4335 vinfoBlockFile.resize(nFile + 1);
4339 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
4341 if (vinfoBlockFile.size() <= nFile) {
4342 vinfoBlockFile.resize(nFile + 1);
4346 pos.nPos = vinfoBlockFile[nFile].nSize;
4349 if (nFile != nLastBlockFile) {
4351 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
4353 FlushBlockFile(!fKnown);
4354 nLastBlockFile = nFile;
4357 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
4359 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
4361 vinfoBlockFile[nFile].nSize += nAddSize;
4364 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4365 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4366 if (nNewChunks > nOldChunks) {
4368 fCheckForPruning = true;
4369 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
4370 FILE *file = OpenBlockFile(pos);
4372 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
4373 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
4378 return state.Error("out of disk space");
4382 setDirtyFileInfo.insert(nFile);
4386 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
4390 LOCK(cs_LastBlockFile);
4392 unsigned int nNewSize;
4393 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
4394 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
4395 setDirtyFileInfo.insert(nFile);
4397 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4398 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4399 if (nNewChunks > nOldChunks) {
4401 fCheckForPruning = true;
4402 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
4403 FILE *file = OpenUndoFile(pos);
4405 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
4406 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
4411 return state.Error("out of disk space");
4417 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
4422 uint256 hash; int32_t i;
4423 hash = blockhdr.GetHash();
4424 for (i=31; i>=0; i--)
4425 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4426 fprintf(stderr," <- CheckBlockHeader\n");
4427 if ( chainActive.LastTip() != 0 )
4429 hash = chainActive.LastTip()->GetBlockHash();
4430 for (i=31; i>=0; i--)
4431 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4432 fprintf(stderr," <- chainTip\n");
4436 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
4438 CBlockIndex *tipindex;
4439 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
4440 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
4442 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
4443 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4445 //fprintf(stderr,"now its valid\n");
4449 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4451 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
4452 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4455 // Check block version
4456 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
4457 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
4459 // Check Equihash solution is valid
4462 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4463 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4465 // Check proof of work matches claimed amount
4466 /*komodo_index2pubkey33(pubkey33,pindex,height);
4467 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
4468 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
4472 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
4473 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
4475 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
4476 libzcash::ProofVerifier& verifier,
4477 bool fCheckPOW, bool fCheckMerkleRoot)
4479 uint8_t pubkey33[33]; uint256 hash;
4480 // These are checks that are independent of context.
4481 hash = block.GetHash();
4482 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
4483 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
4485 if ( *futureblockp == 0 )
4487 LogPrintf("CheckBlock header error");
4493 //if ( !CheckEquihashSolution(&block, Params()) )
4494 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4495 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
4496 if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
4498 int32_t z; for (z=31; z>=0; z--)
4499 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
4500 fprintf(stderr," failed hash ht.%d\n",height);
4501 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
4503 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
4504 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4506 // Check the merkle root.
4507 if (fCheckMerkleRoot) {
4509 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4510 if (block.hashMerkleRoot != hashMerkleRoot2)
4511 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
4512 REJECT_INVALID, "bad-txnmrklroot", true);
4514 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4515 // of transactions in a block without affecting the merkle root of a block,
4516 // while still invalidating it.
4518 return state.DoS(100, error("CheckBlock: duplicate transaction"),
4519 REJECT_INVALID, "bad-txns-duplicate", true);
4522 // All potential-corruption validation must be done before we do any
4523 // transaction validation, as otherwise we may mark the header as invalid
4524 // because we receive the wrong transactions for it.
4527 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
4528 return state.DoS(100, error("CheckBlock: size limits failed"),
4529 REJECT_INVALID, "bad-blk-length");
4531 // First transaction must be coinbase, the rest must not be
4532 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
4533 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
4534 REJECT_INVALID, "bad-cb-missing");
4536 for (unsigned int i = 1; i < block.vtx.size(); i++)
4537 if (block.vtx[i].IsCoinBase())
4538 return state.DoS(100, error("CheckBlock: more than one coinbase"),
4539 REJECT_INVALID, "bad-cb-multiple");
4541 // Check transactions
4542 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
4544 CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
4545 //fprintf(stderr,"put block's tx into mempool\n");
4548 for (i=0; i<block.vtx.size(); i++)
4550 CTransaction Tx; const CTransaction &tx = (CTransaction)block.vtx[i];
4551 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED && komodo_isPoS((CBlock *)&block) != 0))))
4554 if ( myAddtomempool(Tx) == false ) // happens with out of order tx in block on resync
4557 if ( rejects == 0 || rejects == lastrejects )
4559 if ( 0 && lastrejects != 0 )
4560 fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
4563 //fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
4564 lastrejects = rejects;
4567 //fprintf(stderr,"done putting block's tx into mempool\n");
4570 for (uint32_t i = 0; i < block.vtx.size(); i++)
4572 const CTransaction& tx = block.vtx[i];
4573 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
4574 return error("CheckBlock: komodo_validate_interest failed");
4575 if (!CheckTransaction(tx, state, verifier))
4576 return error("CheckBlock: CheckTransaction failed");
4578 unsigned int nSigOps = 0;
4579 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4581 nSigOps += GetLegacySigOpCount(tx);
4583 if (nSigOps > MAX_BLOCK_SIGOPS)
4584 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
4585 REJECT_INVALID, "bad-blk-sigops", true);
4586 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
4588 //static uint32_t counter;
4589 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
4590 // fprintf(stderr,"check deposit rejection\n");
4591 LogPrintf("CheckBlockHeader komodo_check_deposit error");
4597 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4599 const CChainParams& chainParams = Params();
4600 const Consensus::Params& consensusParams = chainParams.GetConsensus();
4601 uint256 hash = block.GetHash();
4602 if (hash == consensusParams.hashGenesisBlock)
4607 int nHeight = pindexPrev->GetHeight()+1;
4609 // Check proof of work
4610 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
4612 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) <<
4613 " for block #" << nHeight << endl;
4614 return state.DoS(100, error("%s: incorrect proof of work", __func__),
4615 REJECT_INVALID, "bad-diffbits");
4618 // Check timestamp against prev
4619 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
4621 return state.Invalid(error("%s: block's timestamp is too early", __func__),
4622 REJECT_INVALID, "time-too-old");
4625 // Check that timestamp is not too far in the future
4626 if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
4628 return state.Invalid(error("%s: block timestamp too far in the future", __func__),
4629 REJECT_INVALID, "time-too-new");
4632 if (fCheckpointsEnabled)
4634 // Check that the block chain matches the known block chain up to a checkpoint
4635 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
4637 /*CBlockIndex *heightblock = chainActive[nHeight];
4638 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4640 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4643 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
4645 // Don't accept any forks from the main chain prior to last checkpoint
4646 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
4647 int32_t notarized_height;
4648 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() > 1 )
4650 CBlockIndex *heightblock = chainActive[nHeight];
4651 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4653 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
4657 if ( pcheckpoint != 0 && nHeight < pcheckpoint->GetHeight() )
4658 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->GetHeight()));
4659 if ( komodo_checkpoint(¬arized_height,nHeight,hash) < 0 )
4661 CBlockIndex *heightblock = chainActive[nHeight];
4662 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4664 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4666 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4670 // Reject block.nVersion < 4 blocks
4671 if (block.nVersion < 4)
4672 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4673 REJECT_OBSOLETE, "bad-version");
4678 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4680 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->GetHeight() + 1;
4681 const Consensus::Params& consensusParams = Params().GetConsensus();
4682 bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
4684 // Check that all transactions are finalized
4685 for (uint32_t i = 0; i < block.vtx.size(); i++) {
4686 const CTransaction& tx = block.vtx[i];
4688 // Check transaction contextually against consensus rules at block height
4689 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4690 return false; // Failure reason has been set in validation state object
4693 // if this is a stake transaction with a stake opreturn, reject it if not staking a block. don't check coinbase or actual stake tx
4695 if (sapling && i > 0 && i < (block.vtx.size() - 1) && ValidateStakeTransaction(tx, p, false))
4697 return state.DoS(10, error("%s: attempt to submit block with staking transaction that is not staking", __func__), REJECT_INVALID, "bad-txns-staking");
4700 int nLockTimeFlags = 0;
4701 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4702 ? pindexPrev->GetMedianTimePast()
4703 : block.GetBlockTime();
4704 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4705 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4709 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4710 // In Zcash this has been enforced since launch, except that the genesis
4711 // block didn't include the height in the coinbase (see Zcash protocol spec
4712 // section '6.8 Bitcoin Improvement Proposals').
4715 CScript expect = CScript() << nHeight;
4716 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4717 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4718 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4724 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4726 static uint256 zero;
4727 const CChainParams& chainparams = Params();
4728 AssertLockHeld(cs_main);
4730 // Check for duplicate
4731 uint256 hash = block.GetHash();
4732 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4733 CBlockIndex *pindex = NULL;
4734 if (miSelf != mapBlockIndex.end())
4736 // Block header is already known.
4737 if ( (pindex = miSelf->second) == 0 )
4738 miSelf->second = pindex = AddToBlockIndex(block);
4741 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4742 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4743 /*if ( pindex != 0 && hash == komodo_requestedhash )
4745 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4746 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4747 komodo_requestedcount = 0;
4750 //if ( pindex == 0 )
4751 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4754 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state,0))
4756 if ( *futureblockp == 0 )
4758 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4762 // Get prev block index
4763 CBlockIndex* pindexPrev = NULL;
4764 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4766 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4767 if (mi == mapBlockIndex.end())
4769 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4771 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4773 pindexPrev = (*mi).second;
4774 if (pindexPrev == 0 )
4776 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4779 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4780 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4782 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4784 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4785 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4790 if ( (pindex= AddToBlockIndex(block)) != 0 )
4792 miSelf = mapBlockIndex.find(hash);
4793 if (miSelf != mapBlockIndex.end())
4794 miSelf->second = pindex;
4795 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4800 /*if ( pindex != 0 && hash == komodo_requestedhash )
4802 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4803 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4804 komodo_requestedcount = 0;
4809 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4811 const CChainParams& chainparams = Params();
4812 AssertLockHeld(cs_main);
4814 CBlockIndex *&pindex = *ppindex;
4815 if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
4817 if ( *futureblockp == 0 )
4819 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4825 LogPrintf("AcceptBlock null pindex\n");
4826 *futureblockp = true;
4829 //fprintf(stderr,"acceptblockheader passed\n");
4830 // Try to process all requested blocks that we don't have, but only
4831 // process an unrequested block if it's new and has enough work to
4832 // advance our tip, and isn't too many blocks ahead.
4833 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4834 bool fHasMoreWork = (chainActive.Tip() ? pindex->chainPower > chainActive.Tip()->chainPower : true);
4835 // Blocks that are too out-of-order needlessly limit the effectiveness of
4836 // pruning, because pruning will not delete block files that contain any
4837 // blocks which are too close in height to the tip. Apply this test
4838 // regardless of whether pruning is enabled; it should generally be safe to
4839 // not process unrequested blocks.
4840 bool fTooFarAhead = (pindex->GetHeight() > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4842 // TODO: deal better with return value and error conditions for duplicate
4843 // and unrequested blocks.
4844 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4845 if (fAlreadyHave) return true;
4846 if (!fRequested) { // If we didn't ask for it:
4847 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4848 if (!fHasMoreWork) return true; // Don't process less-work chains
4849 if (fTooFarAhead) return true; // Block height is too high
4852 // See method docstring for why this is always disabled
4853 auto verifier = libzcash::ProofVerifier::Disabled();
4854 if ((!CheckBlock(futureblockp,pindex->GetHeight(),pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4856 if ( *futureblockp == 0 )
4858 if (state.IsInvalid() && !state.CorruptionPossible()) {
4859 pindex->nStatus |= BLOCK_FAILED_VALID;
4860 setDirtyBlockIndex.insert(pindex);
4862 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4867 int nHeight = pindex->GetHeight();
4868 // Write block to history file
4870 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4871 CDiskBlockPos blockPos;
4874 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4875 return error("AcceptBlock(): FindBlockPos failed");
4877 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4878 AbortNode(state, "Failed to write block");
4879 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4880 return error("AcceptBlock(): ReceivedBlockTransactions failed");
4881 } catch (const std::runtime_error& e) {
4882 return AbortNode(state, std::string("System error: ") + e.what());
4885 if (fCheckForPruning)
4886 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4887 if ( *futureblockp == 0 )
4889 LogPrintf("AcceptBlock block from future error\n");
4893 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4895 unsigned int nFound = 0;
4896 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4898 if (pstart->nVersion >= minVersion)
4900 pstart = pstart->pprev;
4902 return (nFound >= nRequired);
4905 void komodo_currentheight_set(int32_t height);
4907 CBlockIndex *komodo_ensure(CBlock *pblock, uint256 hash)
4909 CBlockIndex *pindex = 0;
4910 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4911 if ( miSelf != mapBlockIndex.end() )
4913 if ( (pindex = miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4915 miSelf->second = AddToBlockIndex(*pblock);
4916 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4918 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4920 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4921 if ( miSelf != mapBlockIndex.end() )
4923 if ( miSelf->second == 0 )
4925 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4926 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4934 CBlockIndex *oldkomodo_ensure(CBlock *pblock, uint256 hash)
4936 CBlockIndex *pindex=0,*previndex=0;
4937 if ( (pindex = mapBlockIndex[hash]) == 0 )
4939 pindex = new CBlockIndex();
4941 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4942 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4943 pindex->phashBlock = &((*mi).first);
4945 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4946 if ( miSelf == mapBlockIndex.end() )
4948 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4951 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4955 pindex = AddToBlockIndex(*pblock);
4956 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4960 miSelf->second = pindex;
4961 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4962 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4964 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4966 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4967 if ( miSelf == mapBlockIndex.end() )
4968 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4969 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4971 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4973 if ( previndex == 0 )
4974 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4975 if ( previndex != 0 )
4977 miSelf->second = previndex;
4978 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4979 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4981 } else LogPrintf("komodo_ensure unexpected null miprev\n");
4987 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
4989 // Preliminary checks
4990 bool checked; uint256 hash; int32_t futureblock=0;
4991 auto verifier = libzcash::ProofVerifier::Disabled();
4992 hash = pblock->GetHash();
4993 //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
4996 if ( chainActive.LastTip() != 0 )
4997 komodo_currentheight_set(chainActive.LastTip()->GetHeight());
4998 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
4999 bool fRequested = MarkBlockAsReceived(hash);
5000 fRequested |= fForceProcessing;
5001 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
5004 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
5006 if (!checked && futureblock == 0)
5010 Misbehaving(pfrom->GetId(), 1);
5012 return error("%s: CheckBlock FAILED", __func__);
5015 CBlockIndex *pindex = NULL;
5017 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
5018 if (pindex && pfrom) {
5019 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
5022 if (!ret && futureblock == 0)
5023 return error("%s: AcceptBlock FAILED", __func__);
5024 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
5027 if (futureblock == 0 && !ActivateBestChain(state, pblock))
5028 return error("%s: ActivateBestChain failed", __func__);
5029 //fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->GetHeight());
5031 // when we succeed here, we prune all cheat candidates in the cheat list to 250 blocks ago, as they should be used or not
5033 if ((height - 250) > 1)
5034 cheatList.Prune(height - 200);
5039 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
5041 AssertLockHeld(cs_main);
5042 assert(pindexPrev == chainActive.Tip());
5044 CCoinsViewCache viewNew(pcoinsTip);
5045 CBlockIndex indexDummy(block);
5046 indexDummy.pprev = pindexPrev;
5047 indexDummy.SetHeight(pindexPrev->GetHeight() + 1);
5048 // JoinSplit proofs are verified in ConnectBlock
5049 auto verifier = libzcash::ProofVerifier::Disabled();
5050 // NOTE: CheckBlockHeader is called by CheckBlock
5051 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
5053 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
5056 int32_t futureblock;
5057 if (!CheckBlock(&futureblock,indexDummy.GetHeight(),0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
5059 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
5062 if (!ContextualCheckBlock(block, state, pindexPrev))
5064 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
5067 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
5069 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
5072 assert(state.IsValid());
5073 if ( futureblock != 0 )
5079 * BLOCK PRUNING CODE
5082 /* Calculate the amount of disk space the block & undo files currently use */
5083 uint64_t CalculateCurrentUsage()
5085 uint64_t retval = 0;
5086 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
5087 retval += file.nSize + file.nUndoSize;
5092 /* Prune a block file (modify associated database entries)*/
5093 void PruneOneBlockFile(const int fileNumber)
5095 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
5096 CBlockIndex* pindex = it->second;
5097 if (pindex && pindex->nFile == fileNumber) {
5098 pindex->nStatus &= ~BLOCK_HAVE_DATA;
5099 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
5101 pindex->nDataPos = 0;
5102 pindex->nUndoPos = 0;
5103 setDirtyBlockIndex.insert(pindex);
5105 // Prune from mapBlocksUnlinked -- any block we prune would have
5106 // to be downloaded again in order to consider its chain, at which
5107 // point it would be considered as a candidate for
5108 // mapBlocksUnlinked or setBlockIndexCandidates.
5109 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
5110 while (range.first != range.second) {
5111 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
5113 if (it->second == pindex) {
5114 mapBlocksUnlinked.erase(it);
5120 vinfoBlockFile[fileNumber].SetNull();
5121 setDirtyFileInfo.insert(fileNumber);
5125 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
5127 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
5128 CDiskBlockPos pos(*it, 0);
5129 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
5130 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
5131 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
5135 /* Calculate the block/rev files that should be deleted to remain under target*/
5136 void FindFilesToPrune(std::set<int>& setFilesToPrune)
5138 LOCK2(cs_main, cs_LastBlockFile);
5139 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
5142 if (chainActive.Tip()->GetHeight() <= Params().PruneAfterHeight()) {
5145 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->GetHeight() - MIN_BLOCKS_TO_KEEP;
5146 uint64_t nCurrentUsage = CalculateCurrentUsage();
5147 // We don't check to prune until after we've allocated new space for files
5148 // So we should leave a buffer under our target to account for another allocation
5149 // before the next pruning.
5150 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
5151 uint64_t nBytesToPrune;
5154 if (nCurrentUsage + nBuffer >= nPruneTarget) {
5155 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
5156 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
5158 if (vinfoBlockFile[fileNumber].nSize == 0)
5161 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
5164 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
5165 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
5168 PruneOneBlockFile(fileNumber);
5169 // Queue up the files for removal
5170 setFilesToPrune.insert(fileNumber);
5171 nCurrentUsage -= nBytesToPrune;
5176 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
5177 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
5178 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
5179 nLastBlockWeCanPrune, count);
5182 bool CheckDiskSpace(uint64_t nAdditionalBytes)
5184 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
5186 // Check for nMinDiskSpace bytes (currently 50MB)
5187 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
5188 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
5193 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
5195 static int32_t didinit[64];
5198 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5199 boost::filesystem::create_directories(path.parent_path());
5200 FILE* file = fopen(path.string().c_str(), "rb+");
5201 if (!file && !fReadOnly)
5202 file = fopen(path.string().c_str(), "wb+");
5204 LogPrintf("Unable to open file %s\n", path.string());
5207 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
5209 komodo_prefetch(file);
5210 didinit[pos.nFile] = 1;
5213 if (fseek(file, pos.nPos, SEEK_SET)) {
5214 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5222 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
5223 return OpenDiskFile(pos, "blk", fReadOnly);
5226 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5227 return OpenDiskFile(pos, "rev", fReadOnly);
5230 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
5232 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
5235 CBlockIndex * InsertBlockIndex(uint256 hash)
5241 BlockMap::iterator mi = mapBlockIndex.find(hash);
5242 if (mi != mapBlockIndex.end() && mi->second != NULL)
5243 return (*mi).second;
5246 CBlockIndex* pindexNew = new CBlockIndex();
5248 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
5249 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
5250 pindexNew->phashBlock = &((*mi).first);
5251 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
5256 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
5258 bool static LoadBlockIndexDB()
5260 const CChainParams& chainparams = Params();
5261 LogPrintf("%s: start loading guts\n", __func__);
5262 if (!pblocktree->LoadBlockIndexGuts())
5264 LogPrintf("%s: loaded guts\n", __func__);
5265 boost::this_thread::interruption_point();
5267 // Calculate chainPower
5268 vector<pair<int, CBlockIndex*> > vSortedByHeight;
5269 vSortedByHeight.reserve(mapBlockIndex.size());
5270 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5272 CBlockIndex* pindex = item.second;
5273 vSortedByHeight.push_back(make_pair(pindex->GetHeight(), pindex));
5274 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5276 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
5277 sort(vSortedByHeight.begin(), vSortedByHeight.end());
5278 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
5279 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
5281 CBlockIndex* pindex = item.second;
5282 pindex->chainPower = (pindex->pprev ? CChainPower(pindex) + pindex->pprev->chainPower : CChainPower(pindex)) + GetBlockProof(*pindex);
5283 // We can link the chain of blocks for which we've received transactions at some point.
5284 // Pruned nodes may have deleted the block.
5285 if (pindex->nTx > 0) {
5286 if (pindex->pprev) {
5287 if (pindex->pprev->nChainTx) {
5288 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
5289 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
5290 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
5292 pindex->nChainSproutValue = boost::none;
5294 if (pindex->pprev->nChainSaplingValue) {
5295 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
5297 pindex->nChainSaplingValue = boost::none;
5300 pindex->nChainTx = 0;
5301 pindex->nChainSproutValue = boost::none;
5302 pindex->nChainSaplingValue = boost::none;
5303 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
5306 pindex->nChainTx = pindex->nTx;
5307 pindex->nChainSproutValue = pindex->nSproutValue;
5308 pindex->nChainSaplingValue = pindex->nSaplingValue;
5311 // Construct in-memory chain of branch IDs.
5312 // Relies on invariant: a block that does not activate a network upgrade
5313 // will always be valid under the same consensus rules as its parent.
5314 // Genesis block has a branch ID of zero by definition, but has no
5315 // validity status because it is side-loaded into a fresh chain.
5316 // Activation blocks will have branch IDs set (read from disk).
5317 if (pindex->pprev) {
5318 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
5319 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
5322 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
5324 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
5325 setBlockIndexCandidates.insert(pindex);
5326 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->chainPower > pindexBestInvalid->chainPower))
5327 pindexBestInvalid = pindex;
5329 pindex->BuildSkip();
5330 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
5331 pindexBestHeader = pindex;
5332 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5334 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
5336 // Load block file info
5337 pblocktree->ReadLastBlockFile(nLastBlockFile);
5338 vinfoBlockFile.resize(nLastBlockFile + 1);
5339 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
5340 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
5341 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
5343 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
5344 for (int nFile = nLastBlockFile + 1; true; nFile++) {
5345 CBlockFileInfo info;
5346 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
5347 vinfoBlockFile.push_back(info);
5353 // Check presence of blk files
5354 LogPrintf("Checking all blk files are present...\n");
5355 set<int> setBlkDataFiles;
5356 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5358 CBlockIndex* pindex = item.second;
5359 if (pindex->nStatus & BLOCK_HAVE_DATA) {
5360 setBlkDataFiles.insert(pindex->nFile);
5362 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5364 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
5365 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
5367 CDiskBlockPos pos(*it, 0);
5368 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
5373 // Check whether we have ever pruned block & undo files
5374 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
5376 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
5378 // Check whether we need to continue reindexing
5379 bool fReindexing = false;
5380 pblocktree->ReadReindexing(fReindexing);
5381 fReindex |= fReindexing;
5383 // Check whether we have a transaction index
5384 pblocktree->ReadFlag("txindex", fTxIndex);
5385 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
5386 // Check whether we have an address index
5387 pblocktree->ReadFlag("addressindex", fAddressIndex);
5388 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
5390 // Check whether we have a timestamp index
5391 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
5392 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
5394 // Check whether we have a spent index
5395 pblocktree->ReadFlag("spentindex", fSpentIndex);
5396 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
5398 // Fill in-memory data
5399 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5401 CBlockIndex* pindex = item.second;
5402 // - This relationship will always be true even if pprev has multiple
5403 // children, because hashSproutAnchor is technically a property of pprev,
5404 // not its children.
5405 // - This will miss chain tips; we handle the best tip below, and other
5406 // tips will be handled by ConnectTip during a re-org.
5407 if (pindex->pprev) {
5408 pindex->pprev->hashFinalSproutRoot = pindex->hashSproutAnchor;
5410 //komodo_pindex_init(pindex,(int32_t)pindex->GetHeight());
5413 // Load pointer to end of best chain
5414 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
5415 if (it == mapBlockIndex.end())
5418 chainActive.SetTip(it->second);
5420 // Set hashFinalSproutRoot for the end of best chain
5421 it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT);
5423 PruneBlockIndexCandidates();
5426 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
5427 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
5429 int32_t longestchain = komodo_longestchain();
5430 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
5431 // runs, which makes it return 0, so we guess 50% for now
5432 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
5435 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
5436 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
5437 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
5440 EnforceNodeDeprecation(chainActive.Height(), true);
5445 CVerifyDB::CVerifyDB()
5447 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
5450 CVerifyDB::~CVerifyDB()
5452 uiInterface.ShowProgress("", 100);
5455 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
5458 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
5461 // Verify blocks in the best chain
5462 if (nCheckDepth <= 0)
5463 nCheckDepth = 1000000000; // suffices until the year 19000
5464 if (nCheckDepth > chainActive.Height())
5465 nCheckDepth = chainActive.Height();
5466 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
5467 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
5468 CCoinsViewCache coins(coinsview);
5469 CBlockIndex* pindexState = chainActive.Tip();
5470 CBlockIndex* pindexFailure = NULL;
5471 int nGoodTransactions = 0;
5472 CValidationState state;
5473 // No need to verify JoinSplits twice
5474 auto verifier = libzcash::ProofVerifier::Disabled();
5475 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
5476 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
5478 boost::this_thread::interruption_point();
5479 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
5480 if (pindex->GetHeight() < chainActive.Height()-nCheckDepth)
5483 // check level 0: read from disk
5484 if (!ReadBlockFromDisk(block, pindex,0))
5485 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5486 // check level 1: verify block validity
5487 int32_t futureblock;
5488 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->GetHeight(),pindex,block, state, verifier,0) )
5489 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5490 // check level 2: verify undo validity
5491 if (nCheckLevel >= 2 && pindex) {
5493 CDiskBlockPos pos = pindex->GetUndoPos();
5494 if (!pos.IsNull()) {
5495 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5496 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5499 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
5500 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
5502 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5503 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5504 pindexState = pindex->pprev;
5506 nGoodTransactions = 0;
5507 pindexFailure = pindex;
5509 nGoodTransactions += block.vtx.size();
5511 if (ShutdownRequested())
5514 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
5516 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->GetHeight() + 1, nGoodTransactions);
5518 // check level 4: try reconnecting blocks
5519 if (nCheckLevel >= 4) {
5520 CBlockIndex *pindex = pindexState;
5521 while (pindex != chainActive.Tip()) {
5522 boost::this_thread::interruption_point();
5523 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->GetHeight())) / (double)nCheckDepth * 50))));
5524 pindex = chainActive.Next(pindex);
5526 if (!ReadBlockFromDisk(block, pindex,0))
5527 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5528 if (!ConnectBlock(block, state, pindex, coins,false, true))
5529 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->GetHeight(), pindex->GetBlockHash().ToString());
5533 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->GetHeight(), nGoodTransactions);
5538 bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches)
5542 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
5543 // index will have nCachedBranchId set based on the values previously persisted
5544 // to disk. By definition, a set nCachedBranchId means that the block was
5545 // fully-validated under the corresponding consensus rules. Thus we can quickly
5546 // identify whether the current active chain matches our expected sequence of
5547 // consensus rule changes, with two checks:
5549 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
5550 // - nCachedBranchId for each block matches what we expect.
5551 auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) {
5552 auto consensus = params.GetConsensus();
5553 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5554 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->GetHeight(), consensus);
5555 return fFlagSet == fFlagExpected &&
5556 pindex->nCachedBranchId &&
5557 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->GetHeight(), consensus);
5561 while (nHeight <= chainActive.Height()) {
5562 if (!sufficientlyValidated(chainActive[nHeight])) {
5568 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
5569 auto rewindLength = chainActive.Height() - nHeight;
5570 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH)
5572 auto pindexOldTip = chainActive.Tip();
5573 auto pindexRewind = chainActive[nHeight - 1];
5574 auto msg = strprintf(_(
5575 "A block chain rewind has been detected that would roll back %d blocks! "
5576 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5577 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5578 _("Rewind details") + ":\n" +
5579 "- " + strprintf(_("Current tip: %s, height %d"),
5580 pindexOldTip->phashBlock->GetHex(), pindexOldTip->GetHeight()) + "\n" +
5581 "- " + strprintf(_("Rewinding to: %s, height %d"),
5582 pindexRewind->phashBlock->GetHex(), pindexRewind->GetHeight()) + "\n\n" +
5583 _("Please help, human!");
5584 LogPrintf("*** %s\n", msg);
5585 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5590 CValidationState state;
5591 CBlockIndex* pindex = chainActive.Tip();
5592 while (chainActive.Height() >= nHeight) {
5593 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5594 // If pruning, don't try rewinding past the HAVE_DATA point;
5595 // since older blocks can't be served anyway, there's
5596 // no need to walk further, and trying to DisconnectTip()
5597 // will fail (and require a needless reindex/redownload
5598 // of the blockchain).
5601 if (!DisconnectTip(state, true)) {
5602 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->GetHeight());
5604 // Occasionally flush state to disk.
5605 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5609 // Reduce validity flag and have-data flags.
5611 // Collect blocks to be removed (blocks in mapBlockIndex must be at least BLOCK_VALID_TREE).
5612 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5613 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5614 std::vector<const CBlockIndex*> vBlocks;
5615 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5616 CBlockIndex* pindexIter = it->second;
5618 // Note: If we encounter an insufficiently validated block that
5619 // is on chainActive, it must be because we are a pruning node, and
5620 // this block or some successor doesn't HAVE_DATA, so we were unable to
5621 // rewind all the way. Blocks remaining on chainActive at this point
5622 // must not have their validity reduced.
5623 if (pindexIter && !sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
5625 pindexIter->nStatus =
5626 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5627 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
5628 // Remove have-data flags
5629 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
5631 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
5632 pindexIter->nCachedBranchId = boost::none;
5633 // Remove storage location
5634 pindexIter->nFile = 0;
5635 pindexIter->nDataPos = 0;
5636 pindexIter->nUndoPos = 0;
5637 // Remove various other things
5638 pindexIter->nTx = 0;
5639 pindexIter->nChainTx = 0;
5640 pindexIter->nSproutValue = boost::none;
5641 pindexIter->nChainSproutValue = boost::none;
5642 pindexIter->nSaplingValue = 0;
5643 pindexIter->nChainSaplingValue = boost::none;
5644 pindexIter->nSequenceId = 0;
5646 // Make sure it gets written
5647 /* corresponds to commented out block below as an alternative to setDirtyBlockIndex
5648 vBlocks.push_back(pindexIter);
5650 setDirtyBlockIndex.insert(pindexIter);
5651 if (pindexIter == pindexBestInvalid)
5653 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
5654 pindexBestInvalid = NULL;
5658 setBlockIndexCandidates.erase(pindexIter);
5659 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
5660 while (ret.first != ret.second) {
5661 if (ret.first->second == pindexIter) {
5662 mapBlocksUnlinked.erase(ret.first++);
5667 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5668 setBlockIndexCandidates.insert(pindexIter);
5673 // Set pindexBestHeader to the current chain tip
5674 // (since we are about to delete the block it is pointing to)
5675 pindexBestHeader = chainActive.Tip();
5677 // Erase block indices on-disk
5678 if (!pblocktree->EraseBatchSync(vBlocks)) {
5679 return AbortNode(state, "Failed to erase from block index database");
5682 // Erase block indices in-memory
5683 for (auto pindex : vBlocks) {
5684 auto ret = mapBlockIndex.find(*pindex->phashBlock);
5685 if (ret != mapBlockIndex.end()) {
5686 mapBlockIndex.erase(ret);
5692 PruneBlockIndexCandidates();
5696 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5703 void UnloadBlockIndex()
5706 setBlockIndexCandidates.clear();
5707 chainActive.SetTip(NULL);
5708 pindexBestInvalid = NULL;
5709 pindexBestHeader = NULL;
5711 mapOrphanTransactions.clear();
5712 mapOrphanTransactionsByPrev.clear();
5714 mapBlocksUnlinked.clear();
5715 vinfoBlockFile.clear();
5717 nBlockSequenceId = 1;
5718 mapBlockSource.clear();
5719 mapBlocksInFlight.clear();
5720 nQueuedValidatedHeaders = 0;
5721 nPreferredDownload = 0;
5722 setDirtyBlockIndex.clear();
5723 setDirtyFileInfo.clear();
5724 mapNodeState.clear();
5725 recentRejects.reset(NULL);
5727 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5728 delete entry.second;
5730 mapBlockIndex.clear();
5731 fHavePruned = false;
5734 bool LoadBlockIndex()
5736 // Load block index from databases
5737 KOMODO_LOADINGBLOCKS = 1;
5738 if (!fReindex && !LoadBlockIndexDB())
5740 KOMODO_LOADINGBLOCKS = 0;
5743 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5748 bool InitBlockIndex() {
5749 const CChainParams& chainparams = Params();
5752 // Initialize global variables that cannot be constructed at startup.
5753 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5754 // Check whether we're already initialized
5755 if (chainActive.Genesis() != NULL)
5759 // Use the provided setting for -txindex in the new database
5760 fTxIndex = GetBoolArg("-txindex", true);
5761 pblocktree->WriteFlag("txindex", fTxIndex);
5762 // Use the provided setting for -addressindex in the new database
5763 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5764 pblocktree->WriteFlag("addressindex", fAddressIndex);
5766 // Use the provided setting for -timestampindex in the new database
5767 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5768 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5770 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5771 pblocktree->WriteFlag("spentindex", fSpentIndex);
5772 fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
5773 LogPrintf("Initializing databases...\n");
5775 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5778 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5779 // Start new block file
5780 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5781 CDiskBlockPos blockPos;
5782 CValidationState state;
5783 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5784 return error("LoadBlockIndex(): FindBlockPos failed");
5785 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5786 return error("LoadBlockIndex(): writing genesis block to disk failed");
5787 CBlockIndex *pindex = AddToBlockIndex(block);
5789 return error("LoadBlockIndex(): couldnt add to block index");
5790 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5791 return error("LoadBlockIndex(): genesis block not accepted");
5792 if (!ActivateBestChain(state, &block))
5793 return error("LoadBlockIndex(): genesis block cannot be activated");
5794 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5795 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5796 } catch (const std::runtime_error& e) {
5797 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5806 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5808 const CChainParams& chainparams = Params();
5809 // Map of disk positions for blocks with unknown parent (only used for reindex)
5810 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5811 int64_t nStart = GetTimeMillis();
5815 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5816 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5817 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5818 uint64_t nRewind = blkdat.GetPos();
5819 while (!blkdat.eof()) {
5820 boost::this_thread::interruption_point();
5822 blkdat.SetPos(nRewind);
5823 nRewind++; // start one byte further next time, in case of failure
5824 blkdat.SetLimit(); // remove former limit
5825 unsigned int nSize = 0;
5828 unsigned char buf[MESSAGE_START_SIZE];
5829 blkdat.FindByte(Params().MessageStart()[0]);
5830 nRewind = blkdat.GetPos()+1;
5831 blkdat >> FLATDATA(buf);
5832 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5836 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5838 } catch (const std::exception&) {
5839 // no valid block header found; don't complain
5844 uint64_t nBlockPos = blkdat.GetPos();
5846 dbp->nPos = nBlockPos;
5847 blkdat.SetLimit(nBlockPos + nSize);
5848 blkdat.SetPos(nBlockPos);
5851 nRewind = blkdat.GetPos();
5853 // detect out of order blocks, and store them for later
5854 uint256 hash = block.GetHash();
5855 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5856 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5857 block.hashPrevBlock.ToString());
5859 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5863 // process in case the block isn't known yet
5864 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5865 CValidationState state;
5866 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5868 if (state.IsError())
5870 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->GetHeight() % 1000 == 0) {
5871 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->GetHeight());
5874 // Recursively process earlier encountered successors of this block
5875 deque<uint256> queue;
5876 queue.push_back(hash);
5877 while (!queue.empty()) {
5878 uint256 head = queue.front();
5880 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5881 while (range.first != range.second) {
5882 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5883 if (ReadBlockFromDisk(mapBlockIndex.count(hash)!=0?mapBlockIndex[hash]->GetHeight():0,block, it->second,1))
5885 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5887 CValidationState dummy;
5888 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5891 queue.push_back(block.GetHash());
5895 mapBlocksUnknownParent.erase(it);
5898 } catch (const std::exception& e) {
5899 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5902 } catch (const std::runtime_error& e) {
5903 AbortNode(std::string("System error: ") + e.what());
5906 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5910 void static CheckBlockIndex()
5912 const Consensus::Params& consensusParams = Params().GetConsensus();
5913 if (!fCheckBlockIndex) {
5919 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5920 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5921 // iterating the block tree require that chainActive has been initialized.)
5922 if (chainActive.Height() < 0) {
5923 assert(mapBlockIndex.size() <= 1);
5927 // Build forward-pointing map of the entire block tree.
5928 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5929 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5930 if ( it->second != 0 )
5931 forward.insert(std::make_pair(it->second->pprev, it->second));
5933 if ( Params().NetworkIDString() != "regtest" )
5934 assert(forward.size() == mapBlockIndex.size());
5936 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5937 CBlockIndex *pindex = rangeGenesis.first->second;
5938 rangeGenesis.first++;
5939 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5941 // Iterate over the entire block tree, using depth-first search.
5942 // Along the way, remember whether there are blocks on the path from genesis
5943 // block being explored which are the first to have certain properties.
5946 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5947 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5948 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5949 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5950 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5951 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5952 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5953 while (pindex != NULL) {
5955 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5956 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5957 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5958 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5959 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5960 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5961 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5963 // Begin: actual consistency checks.
5964 if (pindex->pprev == NULL) {
5965 // Genesis block checks.
5966 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5967 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5969 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
5970 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5971 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5973 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5974 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5975 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5977 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5978 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5980 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5981 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5982 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5983 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5984 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5985 assert(pindex->GetHeight() == nHeight); // nHeight must be consistent.
5986 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.
5987 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->GetHeight() < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5988 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5989 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5990 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5991 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5992 if (pindexFirstInvalid == NULL) {
5993 // Checks for not-invalid blocks.
5994 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5996 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5997 if (pindexFirstInvalid == NULL) {
5998 // If this block sorts at least as good as the current tip and
5999 // is valid and we have all data for its parents, it must be in
6000 // setBlockIndexCandidates. chainActive.Tip() must also be there
6001 // even if some data has been pruned.
6002 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
6003 assert(setBlockIndexCandidates.count(pindex));
6005 // If some parent is missing, then it could be that this block was in
6006 // setBlockIndexCandidates but had to be removed because of the missing data.
6007 // In this case it must be in mapBlocksUnlinked -- see test below.
6009 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
6010 assert(setBlockIndexCandidates.count(pindex) == 0);
6012 // Check whether this block is in mapBlocksUnlinked.
6013 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
6014 bool foundInUnlinked = false;
6015 while (rangeUnlinked.first != rangeUnlinked.second) {
6016 assert(rangeUnlinked.first->first == pindex->pprev);
6017 if (rangeUnlinked.first->second == pindex) {
6018 foundInUnlinked = true;
6021 rangeUnlinked.first++;
6023 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
6024 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
6025 assert(foundInUnlinked);
6027 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
6028 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
6029 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
6030 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
6031 assert(fHavePruned); // We must have pruned.
6032 // This block may have entered mapBlocksUnlinked if:
6033 // - it has a descendant that at some point had more work than the
6035 // - we tried switching to that descendant but were missing
6036 // data for some intermediate block between chainActive and the
6038 // So if this block is itself better than chainActive.Tip() and it wasn't in
6039 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
6040 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
6041 if (pindexFirstInvalid == NULL) {
6042 assert(foundInUnlinked);
6046 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
6047 // End: actual consistency checks.
6049 // Try descending into the first subnode.
6050 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
6051 if (range.first != range.second) {
6052 // A subnode was found.
6053 pindex = range.first->second;
6057 // This is a leaf node.
6058 // Move upwards until we reach a node of which we have not yet visited the last child.
6060 // We are going to either move to a parent or a sibling of pindex.
6061 // If pindex was the first with a certain property, unset the corresponding variable.
6062 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
6063 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
6064 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
6065 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
6066 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
6067 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
6068 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
6070 CBlockIndex* pindexPar = pindex->pprev;
6071 // Find which child we just visited.
6072 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
6073 while (rangePar.first->second != pindex) {
6074 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
6077 // Proceed to the next one.
6079 if (rangePar.first != rangePar.second) {
6080 // Move to the sibling.
6081 pindex = rangePar.first->second;
6092 // Check that we actually traversed the entire map.
6093 assert(nNodes == forward.size());
6096 //////////////////////////////////////////////////////////////////////////////
6101 std::string GetWarnings(const std::string& strFor)
6104 string strStatusBar;
6107 if (!CLIENT_VERSION_IS_RELEASE)
6108 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
6110 if (GetBoolArg("-testsafemode", false))
6111 strStatusBar = strRPC = "testsafemode enabled";
6113 // Misc warnings like out of disk space and clock is wrong
6114 if (strMiscWarning != "")
6117 strStatusBar = strMiscWarning;
6120 if (fLargeWorkForkFound)
6123 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
6125 else if (fLargeWorkInvalidChainFound)
6128 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.");
6134 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6136 const CAlert& alert = item.second;
6137 if (alert.AppliesToMe() && alert.nPriority > nPriority)
6139 nPriority = alert.nPriority;
6140 strStatusBar = alert.strStatusBar;
6141 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
6142 strRPC = alert.strRPCError;
6148 if (strFor == "statusbar")
6149 return strStatusBar;
6150 else if (strFor == "rpc")
6152 assert(!"GetWarnings(): invalid parameter");
6163 //////////////////////////////////////////////////////////////////////////////
6169 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
6175 assert(recentRejects);
6176 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
6178 // If the chain tip has changed previously rejected transactions
6179 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
6180 // or a double-spend. Reset the rejects filter and give those
6181 // txs a second chance.
6182 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
6183 recentRejects->reset();
6186 return recentRejects->contains(inv.hash) ||
6187 mempool.exists(inv.hash) ||
6188 mapOrphanTransactions.count(inv.hash) ||
6189 pcoinsTip->HaveCoins(inv.hash);
6192 return mapBlockIndex.count(inv.hash);
6194 // Don't know what it is, just say we already got one
6198 void static ProcessGetData(CNode* pfrom)
6200 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
6202 vector<CInv> vNotFound;
6206 while (it != pfrom->vRecvGetData.end()) {
6207 // Don't bother if send buffer is too full to respond anyway
6208 if (pfrom->nSendSize >= SendBufferSize())
6211 const CInv &inv = *it;
6213 boost::this_thread::interruption_point();
6216 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6219 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
6220 if (mi != mapBlockIndex.end())
6222 if (chainActive.Contains(mi->second)) {
6225 static const int nOneMonth = 30 * 24 * 60 * 60;
6226 // To prevent fingerprinting attacks, only send blocks outside of the active
6227 // chain if they are valid, and no more than a month older (both in time, and in
6228 // best equivalent proof of work) than the best header chain we know about.
6229 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
6230 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
6231 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
6233 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
6237 // Pruned nodes may have deleted the block, so check whether
6238 // it's available before trying to send.
6239 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
6241 // Send block from disk
6243 if (!ReadBlockFromDisk(block, (*mi).second,1))
6245 assert(!"cannot load block from disk");
6249 if (inv.type == MSG_BLOCK)
6251 //uint256 hash; int32_t z;
6252 //hash = block.GetHash();
6253 //for (z=31; z>=0; z--)
6254 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
6255 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
6256 pfrom->PushMessage("block", block);
6258 else // MSG_FILTERED_BLOCK)
6260 LOCK(pfrom->cs_filter);
6263 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
6264 pfrom->PushMessage("merkleblock", merkleBlock);
6265 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
6266 // This avoids hurting performance by pointlessly requiring a round-trip
6267 // Note that there is currently no way for a node to request any single transactions we didn't send here -
6268 // they must either disconnect and retry or request the full block.
6269 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
6270 // however we MUST always provide at least what the remote peer needs
6271 typedef std::pair<unsigned int, uint256> PairType;
6272 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
6273 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
6274 pfrom->PushMessage("tx", block.vtx[pair.first]);
6280 // Trigger the peer node to send a getblocks request for the next batch of inventory
6281 if (inv.hash == pfrom->hashContinue)
6283 // Bypass PushInventory, this must send even if redundant,
6284 // and we want it right after the last block so they don't
6285 // wait for other stuff first.
6287 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
6288 pfrom->PushMessage("inv", vInv);
6289 pfrom->hashContinue.SetNull();
6293 else if (inv.IsKnownType())
6295 // Send stream from relay memory
6296 bool pushed = false;
6299 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
6300 if (mi != mapRelay.end()) {
6301 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
6305 if (!pushed && inv.type == MSG_TX) {
6307 if (mempool.lookup(inv.hash, tx)) {
6308 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
6311 pfrom->PushMessage("tx", ss);
6316 vNotFound.push_back(inv);
6320 // Track requests for our stuff.
6321 GetMainSignals().Inventory(inv.hash);
6323 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6328 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
6330 if (!vNotFound.empty()) {
6331 // Let the peer know that we didn't find what it asked for, so it doesn't
6332 // have to wait around forever. Currently only SPV clients actually care
6333 // about this message: it's needed when they are recursively walking the
6334 // dependencies of relevant unconfirmed transactions. SPV clients want to
6335 // do that because they want to know about (and store and rebroadcast and
6336 // risk analyze) the dependencies of transactions relevant to them, without
6337 // having to download the entire memory pool.
6338 pfrom->PushMessage("notfound", vNotFound);
6342 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
6344 const CChainParams& chainparams = Params();
6345 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
6346 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
6347 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
6349 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
6353 //printf("netmsg: %s\n", strCommand.c_str());
6355 if (strCommand == "version")
6357 // Each connection can only send one version message
6358 if (pfrom->nVersion != 0)
6360 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
6361 Misbehaving(pfrom->GetId(), 1);
6368 uint64_t nNonce = 1;
6369 int nVersion; // use temporary for version, don't set version number until validated as connected
6370 vRecv >> nVersion >> pfrom->nServices >> nTime >> addrMe;
6371 if (nVersion == 10300)
6374 if (nVersion < MIN_PEER_PROTO_VERSION)
6376 // disconnect from peers older than this proto version
6377 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6378 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6379 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
6380 pfrom->fDisconnect = true;
6384 // Reject incoming connections from nodes that don't know about the current epoch
6385 const Consensus::Params& params = Params().GetConsensus();
6386 auto currentEpoch = CurrentEpoch(GetHeight(), params);
6387 if (nVersion < params.vUpgrades[currentEpoch].nProtocolVersion)
6389 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion);
6390 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6391 strprintf("Version must be %d or greater",
6392 params.vUpgrades[currentEpoch].nProtocolVersion));
6393 pfrom->fDisconnect = true;
6398 vRecv >> addrFrom >> nNonce;
6399 if (!vRecv.empty()) {
6400 vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
6401 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
6404 vRecv >> pfrom->nStartingHeight;
6406 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
6408 pfrom->fRelayTxes = true;
6410 // Disconnect if we connected to ourself
6411 if (nNonce == nLocalHostNonce && nNonce > 1)
6413 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
6414 pfrom->fDisconnect = true;
6418 pfrom->nVersion = nVersion;
6420 pfrom->addrLocal = addrMe;
6421 if (pfrom->fInbound && addrMe.IsRoutable())
6426 // Be shy and don't send version until we hear
6427 if (pfrom->fInbound)
6428 pfrom->PushVersion();
6430 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
6432 // Potentially mark this peer as a preferred download peer.
6433 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
6436 pfrom->PushMessage("verack");
6437 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6439 if (!pfrom->fInbound)
6441 // Advertise our address
6442 if (fListen && !IsInitialBlockDownload())
6444 CAddress addr = GetLocalAddress(&pfrom->addr);
6445 if (addr.IsRoutable())
6447 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6448 pfrom->PushAddress(addr);
6449 } else if (IsPeerAddrLocalGood(pfrom)) {
6450 addr.SetIP(pfrom->addrLocal);
6451 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6452 pfrom->PushAddress(addr);
6456 // Get recent addresses
6457 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
6459 pfrom->PushMessage("getaddr");
6460 pfrom->fGetAddr = true;
6462 addrman.Good(pfrom->addr);
6464 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
6466 addrman.Add(addrFrom, addrFrom);
6467 addrman.Good(addrFrom);
6474 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6475 item.second.RelayTo(pfrom);
6478 pfrom->fSuccessfullyConnected = true;
6482 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
6484 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
6485 pfrom->cleanSubVer, pfrom->nVersion,
6486 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
6489 int64_t nTimeOffset = nTime - GetTime();
6490 pfrom->nTimeOffset = nTimeOffset;
6491 AddTimeData(pfrom->addr, nTimeOffset);
6495 else if (pfrom->nVersion == 0)
6497 // Must have a version message before anything else
6498 Misbehaving(pfrom->GetId(), 1);
6503 else if (strCommand == "verack")
6505 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6507 // Mark this node as currently connected, so we update its timestamp later.
6508 if (pfrom->fNetworkNode) {
6510 State(pfrom->GetId())->fCurrentlyConnected = true;
6515 // Disconnect existing peer connection when:
6516 // 1. The version message has been received
6517 // 2. Peer version is below the minimum version for the current epoch
6518 else if (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[
6519 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion)
6521 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6522 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6523 strprintf("Version must be %d or greater",
6524 chainparams.GetConsensus().vUpgrades[
6525 CurrentEpoch(GetHeight(), chainparams.GetConsensus())].nProtocolVersion));
6526 pfrom->fDisconnect = true;
6531 else if (strCommand == "addr")
6533 vector<CAddress> vAddr;
6536 // Don't want addr from older versions unless seeding
6537 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
6539 if (vAddr.size() > 1000)
6541 Misbehaving(pfrom->GetId(), 20);
6542 return error("message addr size() = %u", vAddr.size());
6545 // Store the new addresses
6546 vector<CAddress> vAddrOk;
6547 int64_t nNow = GetAdjustedTime();
6548 int64_t nSince = nNow - 10 * 60;
6549 BOOST_FOREACH(CAddress& addr, vAddr)
6551 boost::this_thread::interruption_point();
6553 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6554 addr.nTime = nNow - 5 * 24 * 60 * 60;
6555 pfrom->AddAddressKnown(addr);
6556 bool fReachable = IsReachable(addr);
6557 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
6559 // Relay to a limited number of other nodes
6562 // Use deterministic randomness to send to the same nodes for 24 hours
6563 // at a time so the addrKnowns of the chosen nodes prevent repeats
6564 static uint256 hashSalt;
6565 if (hashSalt.IsNull())
6566 hashSalt = GetRandHash();
6567 uint64_t hashAddr = addr.GetHash();
6568 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
6569 hashRand = Hash(BEGIN(hashRand), END(hashRand));
6570 multimap<uint256, CNode*> mapMix;
6571 BOOST_FOREACH(CNode* pnode, vNodes)
6573 if (pnode->nVersion < CADDR_TIME_VERSION)
6575 unsigned int nPointer;
6576 memcpy(&nPointer, &pnode, sizeof(nPointer));
6577 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
6578 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6579 mapMix.insert(make_pair(hashKey, pnode));
6581 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
6582 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6583 ((*mi).second)->PushAddress(addr);
6586 // Do not store addresses outside our network
6588 vAddrOk.push_back(addr);
6590 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
6591 if (vAddr.size() < 1000)
6592 pfrom->fGetAddr = false;
6593 if (pfrom->fOneShot)
6594 pfrom->fDisconnect = true;
6598 else if (strCommand == "inv")
6602 if (vInv.size() > MAX_INV_SZ)
6604 Misbehaving(pfrom->GetId(), 20);
6605 return error("message inv size() = %u", vInv.size());
6610 std::vector<CInv> vToFetch;
6612 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
6614 const CInv &inv = vInv[nInv];
6616 boost::this_thread::interruption_point();
6617 pfrom->AddInventoryKnown(inv);
6619 bool fAlreadyHave = AlreadyHave(inv);
6620 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
6622 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6625 if (inv.type == MSG_BLOCK) {
6626 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
6627 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
6628 // First request the headers preceding the announced block. In the normal fully-synced
6629 // case where a new block is announced that succeeds the current tip (no reorganization),
6630 // there are no such headers.
6631 // Secondly, and only when we are close to being synced, we request the announced block directly,
6632 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6633 // time the block arrives, the header chain leading up to it is already validated. Not
6634 // doing this will result in the received block being rejected as an orphan in case it is
6635 // not a direct successor.
6636 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
6637 CNodeState *nodestate = State(pfrom->GetId());
6638 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
6639 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6640 vToFetch.push_back(inv);
6641 // Mark block as in flight already, even though the actual "getdata" message only goes out
6642 // later (within the same cs_main lock, though).
6643 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
6645 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->GetHeight(), inv.hash.ToString(), pfrom->id);
6649 // Track requests for our stuff
6650 GetMainSignals().Inventory(inv.hash);
6652 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6653 Misbehaving(pfrom->GetId(), 50);
6654 return error("send buffer size() = %u", pfrom->nSendSize);
6658 if (!vToFetch.empty())
6659 pfrom->PushMessage("getdata", vToFetch);
6663 else if (strCommand == "getdata")
6667 if (vInv.size() > MAX_INV_SZ)
6669 Misbehaving(pfrom->GetId(), 20);
6670 return error("message getdata size() = %u", vInv.size());
6673 if (fDebug || (vInv.size() != 1))
6674 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
6676 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
6677 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
6679 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6680 ProcessGetData(pfrom);
6684 else if (strCommand == "getblocks")
6686 CBlockLocator locator;
6688 vRecv >> locator >> hashStop;
6692 // Find the last block the caller has in the main chain
6693 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
6695 // Send the rest of the chain
6697 pindex = chainActive.Next(pindex);
6699 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
6700 for (; pindex; pindex = chainActive.Next(pindex))
6702 if (pindex->GetBlockHash() == hashStop)
6704 LogPrint("net", " getblocks stopping at %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6707 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6710 // When this block is requested, we'll send an inv that'll
6711 // trigger the peer to getblocks the next batch of inventory.
6712 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->GetHeight(), pindex->GetBlockHash().ToString());
6713 pfrom->hashContinue = pindex->GetBlockHash();
6720 else if (strCommand == "getheaders")
6722 CBlockLocator locator;
6724 vRecv >> locator >> hashStop;
6728 if (IsInitialBlockDownload())
6731 CBlockIndex* pindex = NULL;
6732 if (locator.IsNull())
6734 // If locator is null, return the hashStop block
6735 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6736 if (mi == mapBlockIndex.end())
6738 pindex = (*mi).second;
6742 // Find the last block the caller has in the main chain
6743 pindex = FindForkInGlobalIndex(chainActive, locator);
6745 pindex = chainActive.Next(pindex);
6748 // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6749 vector<CNetworkBlockHeader> vHeaders;
6750 int nLimit = MAX_HEADERS_RESULTS;
6751 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->GetHeight() : -1), hashStop.ToString(), pfrom->id);
6752 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->GetHeight() : -1) )// no need to ever suppress this
6754 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->GetHeight() : -1);
6755 for (; pindex; pindex = chainActive.Next(pindex))
6757 CBlockHeader h = pindex->GetBlockHeader();
6758 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6759 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
6760 vHeaders.push_back(pindex->GetBlockHeader());
6761 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6764 pfrom->PushMessage("headers", vHeaders);
6766 /*else if ( IS_KOMODO_NOTARY != 0 )
6768 static uint32_t counter;
6769 if ( counter++ < 3 )
6770 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);
6775 else if (strCommand == "tx")
6777 vector<uint256> vWorkQueue;
6778 vector<uint256> vEraseQueue;
6782 CInv inv(MSG_TX, tx.GetHash());
6783 pfrom->AddInventoryKnown(inv);
6787 bool fMissingInputs = false;
6788 CValidationState state;
6790 pfrom->setAskFor.erase(inv.hash);
6791 mapAlreadyAskedFor.erase(inv);
6793 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6795 mempool.check(pcoinsTip);
6796 RelayTransaction(tx);
6797 vWorkQueue.push_back(inv.hash);
6799 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6800 pfrom->id, pfrom->cleanSubVer,
6801 tx.GetHash().ToString(),
6802 mempool.mapTx.size());
6804 // Recursively process any orphan transactions that depended on this one
6805 set<NodeId> setMisbehaving;
6806 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6808 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6809 if (itByPrev == mapOrphanTransactionsByPrev.end())
6811 for (set<uint256>::iterator mi = itByPrev->second.begin();
6812 mi != itByPrev->second.end();
6815 const uint256& orphanHash = *mi;
6816 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6817 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6818 bool fMissingInputs2 = false;
6819 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6820 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6821 // anyone relaying LegitTxX banned)
6822 CValidationState stateDummy;
6825 if (setMisbehaving.count(fromPeer))
6827 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6829 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
6830 RelayTransaction(orphanTx);
6831 vWorkQueue.push_back(orphanHash);
6832 vEraseQueue.push_back(orphanHash);
6834 else if (!fMissingInputs2)
6837 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6839 // Punish peer that gave us an invalid orphan tx
6840 Misbehaving(fromPeer, nDos);
6841 setMisbehaving.insert(fromPeer);
6842 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6844 // Has inputs but not accepted to mempool
6845 // Probably non-standard or insufficient fee/priority
6846 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
6847 vEraseQueue.push_back(orphanHash);
6848 assert(recentRejects);
6849 recentRejects->insert(orphanHash);
6851 mempool.check(pcoinsTip);
6855 BOOST_FOREACH(uint256 hash, vEraseQueue)
6856 EraseOrphanTx(hash);
6858 // TODO: currently, prohibit joinsplits and shielded spends/outputs from entering mapOrphans
6859 else if (fMissingInputs &&
6860 tx.vjoinsplit.empty() &&
6861 tx.vShieldedSpend.empty() &&
6862 tx.vShieldedOutput.empty())
6864 // valid stake transactions end up in the orphan tx bin
6865 AddOrphanTx(tx, pfrom->GetId());
6867 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6868 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6869 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6871 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6873 assert(recentRejects);
6874 recentRejects->insert(tx.GetHash());
6876 if (pfrom->fWhitelisted) {
6877 // Always relay transactions received from whitelisted peers, even
6878 // if they were already in the mempool or rejected from it due
6879 // to policy, allowing the node to function as a gateway for
6880 // nodes hidden behind it.
6882 // Never relay transactions that we would assign a non-zero DoS
6883 // score for, as we expect peers to do the same with us in that
6886 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6887 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6888 RelayTransaction(tx);
6890 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6891 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6896 if (state.IsInvalid(nDoS))
6898 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6899 pfrom->id, pfrom->cleanSubVer,
6900 state.GetRejectReason());
6901 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6902 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6904 Misbehaving(pfrom->GetId(), nDoS);
6908 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6910 std::vector<CBlockHeader> headers;
6912 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6913 unsigned int nCount = ReadCompactSize(vRecv);
6914 if (nCount > MAX_HEADERS_RESULTS) {
6915 Misbehaving(pfrom->GetId(), 20);
6916 return error("headers message size = %u", nCount);
6918 headers.resize(nCount);
6919 for (unsigned int n = 0; n < nCount; n++) {
6920 vRecv >> headers[n];
6921 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6927 // Nothing interesting. Stop asking this peers for more headers.
6931 CBlockIndex *pindexLast = NULL;
6932 BOOST_FOREACH(const CBlockHeader& header, headers) {
6933 //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6934 //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
6936 CValidationState state;
6937 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6938 Misbehaving(pfrom->GetId(), 20);
6939 return error("non-continuous headers sequence");
6941 int32_t futureblock;
6942 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6944 if (state.IsInvalid(nDoS) && futureblock == 0)
6946 if (nDoS > 0 && futureblock == 0)
6947 Misbehaving(pfrom->GetId(), nDoS/nDoS);
6948 return error("invalid header received");
6954 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6956 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6957 // Headers message had its maximum size; the peer may have more headers.
6958 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6959 // from there instead.
6960 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->GetHeight() != pfrom->sendhdrsreq )
6962 pfrom->sendhdrsreq = (int32_t)pindexLast->GetHeight();
6963 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->GetHeight(), pfrom->id, pfrom->nStartingHeight);
6964 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6971 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6976 CInv inv(MSG_BLOCK, block.GetHash());
6977 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6979 pfrom->AddInventoryKnown(inv);
6981 CValidationState state;
6982 // Process all blocks from whitelisted peers, even if not requested,
6983 // unless we're still syncing with the network.
6984 // Such an unrequested block may still be processed, subject to the
6985 // conditions in AcceptBlock().
6986 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6987 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
6989 if (state.IsInvalid(nDoS)) {
6990 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6991 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6994 Misbehaving(pfrom->GetId(), nDoS);
7001 // This asymmetric behavior for inbound and outbound connections was introduced
7002 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
7003 // to users' AddrMan and later request them by sending getaddr messages.
7004 // Making nodes which are behind NAT and can only make outgoing connections ignore
7005 // the getaddr message mitigates the attack.
7006 else if ((strCommand == "getaddr") && (pfrom->fInbound))
7008 // Only send one GetAddr response per connection to reduce resource waste
7009 // and discourage addr stamping of INV announcements.
7010 if (pfrom->fSentAddr) {
7011 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
7014 pfrom->fSentAddr = true;
7016 pfrom->vAddrToSend.clear();
7017 vector<CAddress> vAddr = addrman.GetAddr();
7018 BOOST_FOREACH(const CAddress &addr, vAddr)
7019 pfrom->PushAddress(addr);
7023 else if (strCommand == "mempool")
7025 LOCK2(cs_main, pfrom->cs_filter);
7027 std::vector<uint256> vtxid;
7028 mempool.queryHashes(vtxid);
7030 BOOST_FOREACH(uint256& hash, vtxid) {
7031 CInv inv(MSG_TX, hash);
7032 if (pfrom->pfilter) {
7034 bool fInMemPool = mempool.lookup(hash, tx);
7035 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
7036 if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
7038 vInv.push_back(inv);
7039 if (vInv.size() == MAX_INV_SZ) {
7040 pfrom->PushMessage("inv", vInv);
7044 if (vInv.size() > 0)
7045 pfrom->PushMessage("inv", vInv);
7049 else if (strCommand == "ping")
7051 if (pfrom->nVersion > BIP0031_VERSION)
7055 // Echo the message back with the nonce. This allows for two useful features:
7057 // 1) A remote node can quickly check if the connection is operational
7058 // 2) Remote nodes can measure the latency of the network thread. If this node
7059 // is overloaded it won't respond to pings quickly and the remote node can
7060 // avoid sending us more work, like chain download requests.
7062 // The nonce stops the remote getting confused between different pings: without
7063 // it, if the remote node sends a ping once per second and this node takes 5
7064 // seconds to respond to each, the 5th ping the remote sends would appear to
7065 // return very quickly.
7066 pfrom->PushMessage("pong", nonce);
7071 else if (strCommand == "pong")
7073 int64_t pingUsecEnd = nTimeReceived;
7075 size_t nAvail = vRecv.in_avail();
7076 bool bPingFinished = false;
7077 std::string sProblem;
7079 if (nAvail >= sizeof(nonce)) {
7082 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
7083 if (pfrom->nPingNonceSent != 0) {
7084 if (nonce == pfrom->nPingNonceSent) {
7085 // Matching pong received, this ping is no longer outstanding
7086 bPingFinished = true;
7087 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
7088 if (pingUsecTime > 0) {
7089 // Successful ping time measurement, replace previous
7090 pfrom->nPingUsecTime = pingUsecTime;
7091 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
7093 // This should never happen
7094 sProblem = "Timing mishap";
7097 // Nonce mismatches are normal when pings are overlapping
7098 sProblem = "Nonce mismatch";
7100 // This is most likely a bug in another implementation somewhere; cancel this ping
7101 bPingFinished = true;
7102 sProblem = "Nonce zero";
7106 sProblem = "Unsolicited pong without ping";
7109 // This is most likely a bug in another implementation somewhere; cancel this ping
7110 bPingFinished = true;
7111 sProblem = "Short payload";
7114 if (!(sProblem.empty())) {
7115 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
7119 pfrom->nPingNonceSent,
7123 if (bPingFinished) {
7124 pfrom->nPingNonceSent = 0;
7129 else if (fAlerts && strCommand == "alert")
7134 uint256 alertHash = alert.GetHash();
7135 if (pfrom->setKnown.count(alertHash) == 0)
7137 if (alert.ProcessAlert(Params().AlertKey()))
7140 pfrom->setKnown.insert(alertHash);
7143 BOOST_FOREACH(CNode* pnode, vNodes)
7144 alert.RelayTo(pnode);
7148 // Small DoS penalty so peers that send us lots of
7149 // duplicate/expired/invalid-signature/whatever alerts
7150 // eventually get banned.
7151 // This isn't a Misbehaving(100) (immediate ban) because the
7152 // peer might be an older or different implementation with
7153 // a different signature key, etc.
7154 Misbehaving(pfrom->GetId(), 10);
7159 else if (!(nLocalServices & NODE_BLOOM) &&
7160 (strCommand == "filterload" ||
7161 strCommand == "filteradd"))
7163 if (pfrom->nVersion >= NO_BLOOM_VERSION) {
7164 Misbehaving(pfrom->GetId(), 100);
7166 } else if (GetBoolArg("-enforcenodebloom", false)) {
7167 pfrom->fDisconnect = true;
7173 else if (strCommand == "filterload")
7175 CBloomFilter filter;
7178 if (!filter.IsWithinSizeConstraints())
7179 // There is no excuse for sending a too-large filter
7180 Misbehaving(pfrom->GetId(), 100);
7183 LOCK(pfrom->cs_filter);
7184 delete pfrom->pfilter;
7185 pfrom->pfilter = new CBloomFilter(filter);
7186 pfrom->pfilter->UpdateEmptyFull();
7188 pfrom->fRelayTxes = true;
7192 else if (strCommand == "filteradd")
7194 vector<unsigned char> vData;
7197 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
7198 // and thus, the maximum size any matched object can have) in a filteradd message
7199 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
7201 Misbehaving(pfrom->GetId(), 100);
7203 LOCK(pfrom->cs_filter);
7205 pfrom->pfilter->insert(vData);
7207 Misbehaving(pfrom->GetId(), 100);
7212 else if (strCommand == "filterclear")
7214 LOCK(pfrom->cs_filter);
7215 if (nLocalServices & NODE_BLOOM) {
7216 delete pfrom->pfilter;
7217 pfrom->pfilter = new CBloomFilter();
7219 pfrom->fRelayTxes = true;
7223 else if (strCommand == "reject")
7227 string strMsg; unsigned char ccode; string strReason;
7228 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
7231 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
7233 if (strMsg == "block" || strMsg == "tx")
7237 ss << ": hash " << hash.ToString();
7239 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
7240 } catch (const std::ios_base::failure&) {
7241 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
7242 LogPrint("net", "Unparseable reject message received\n");
7246 else if (strCommand == "notfound") {
7247 // We do not care about the NOTFOUND message, but logging an Unknown Command
7248 // message would be undesirable as we transmit it ourselves.
7252 // Ignore unknown commands for extensibility
7253 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
7261 // requires LOCK(cs_vRecvMsg)
7262 bool ProcessMessages(CNode* pfrom)
7265 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
7269 // (4) message start
7277 if (!pfrom->vRecvGetData.empty())
7278 ProcessGetData(pfrom);
7280 // this maintains the order of responses
7281 if (!pfrom->vRecvGetData.empty()) return fOk;
7283 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
7284 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
7285 // Don't bother if send buffer is too full to respond anyway
7286 if (pfrom->nSendSize >= SendBufferSize())
7290 CNetMessage& msg = *it;
7293 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
7294 // msg.hdr.nMessageSize, msg.vRecv.size(),
7295 // msg.complete() ? "Y" : "N");
7297 // end, if an incomplete message is found
7298 if (!msg.complete())
7301 // at this point, any failure means we can delete the current message
7304 // Scan for message start
7305 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
7306 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
7312 CMessageHeader& hdr = msg.hdr;
7313 if (!hdr.IsValid(Params().MessageStart()))
7315 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
7318 string strCommand = hdr.GetCommand();
7321 unsigned int nMessageSize = hdr.nMessageSize;
7324 CDataStream& vRecv = msg.vRecv;
7325 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
7326 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
7327 if (nChecksum != hdr.nChecksum)
7329 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
7330 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
7338 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
7339 boost::this_thread::interruption_point();
7341 catch (const std::ios_base::failure& e)
7343 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
7344 if (strstr(e.what(), "end of data"))
7346 // Allow exceptions from under-length message on vRecv
7347 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());
7349 else if (strstr(e.what(), "size too large"))
7351 // Allow exceptions from over-long size
7352 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
7356 //PrintExceptionContinue(&e, "ProcessMessages()");
7359 catch (const boost::thread_interrupted&) {
7362 catch (const std::exception& e) {
7363 PrintExceptionContinue(&e, "ProcessMessages()");
7365 PrintExceptionContinue(NULL, "ProcessMessages()");
7369 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
7374 // In case the connection got shut down, its receive buffer was wiped
7375 if (!pfrom->fDisconnect)
7376 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
7382 bool SendMessages(CNode* pto, bool fSendTrickle)
7384 const Consensus::Params& consensusParams = Params().GetConsensus();
7386 // Don't send anything until we get its version message
7387 if (pto->nVersion == 0)
7393 bool pingSend = false;
7394 if (pto->fPingQueued) {
7395 // RPC ping request by user
7398 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
7399 // Ping automatically sent as a latency probe & keepalive.
7404 while (nonce == 0) {
7405 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
7407 pto->fPingQueued = false;
7408 pto->nPingUsecStart = GetTimeMicros();
7409 if (pto->nVersion > BIP0031_VERSION) {
7410 pto->nPingNonceSent = nonce;
7411 pto->PushMessage("ping", nonce);
7413 // Peer is too old to support ping command with nonce, pong will never arrive.
7414 pto->nPingNonceSent = 0;
7415 pto->PushMessage("ping");
7419 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
7423 // Address refresh broadcast
7424 static int64_t nLastRebroadcast;
7425 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
7428 BOOST_FOREACH(CNode* pnode, vNodes)
7430 // Periodically clear addrKnown to allow refresh broadcasts
7431 if (nLastRebroadcast)
7432 pnode->addrKnown.reset();
7434 // Rebroadcast our address
7435 AdvertizeLocal(pnode);
7437 if (!vNodes.empty())
7438 nLastRebroadcast = GetTime();
7446 vector<CAddress> vAddr;
7447 vAddr.reserve(pto->vAddrToSend.size());
7448 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
7450 if (!pto->addrKnown.contains(addr.GetKey()))
7452 pto->addrKnown.insert(addr.GetKey());
7453 vAddr.push_back(addr);
7454 // receiver rejects addr messages larger than 1000
7455 if (vAddr.size() >= 1000)
7457 pto->PushMessage("addr", vAddr);
7462 pto->vAddrToSend.clear();
7464 pto->PushMessage("addr", vAddr);
7467 CNodeState &state = *State(pto->GetId());
7468 if (state.fShouldBan) {
7469 if (pto->fWhitelisted)
7470 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
7472 pto->fDisconnect = true;
7473 if (pto->addr.IsLocal())
7474 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
7477 CNode::Ban(pto->addr);
7480 state.fShouldBan = false;
7483 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
7484 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
7485 state.rejects.clear();
7488 if (pindexBestHeader == NULL)
7489 pindexBestHeader = chainActive.Tip();
7490 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.
7491 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
7492 // Only actively request headers from a single peer, unless we're close to today.
7493 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
7494 state.fSyncStarted = true;
7496 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
7497 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->GetHeight(), pto->id, pto->nStartingHeight);
7498 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
7502 // Resend wallet transactions that haven't gotten in a block yet
7503 // Except during reindex, importing and IBD, when old wallet
7504 // transactions become unconfirmed and spams other nodes.
7505 if (!fReindex && !fImporting && !IsInitialBlockDownload())
7507 GetMainSignals().Broadcast(nTimeBestReceived);
7511 // Message: inventory
7514 vector<CInv> vInvWait;
7516 LOCK(pto->cs_inventory);
7517 vInv.reserve(pto->vInventoryToSend.size());
7518 vInvWait.reserve(pto->vInventoryToSend.size());
7519 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
7521 if (pto->setInventoryKnown.count(inv))
7524 // trickle out tx inv to protect privacy
7525 if (inv.type == MSG_TX && !fSendTrickle)
7527 // 1/4 of tx invs blast to all immediately
7528 static uint256 hashSalt;
7529 if (hashSalt.IsNull())
7530 hashSalt = GetRandHash();
7531 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
7532 hashRand = Hash(BEGIN(hashRand), END(hashRand));
7533 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
7537 vInvWait.push_back(inv);
7542 // returns true if wasn't already contained in the set
7543 if (pto->setInventoryKnown.insert(inv).second)
7545 vInv.push_back(inv);
7546 if (vInv.size() >= 1000)
7548 pto->PushMessage("inv", vInv);
7553 pto->vInventoryToSend = vInvWait;
7556 pto->PushMessage("inv", vInv);
7558 // Detect whether we're stalling
7559 int64_t nNow = GetTimeMicros();
7560 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7561 // Stalling only triggers when the block download window cannot move. During normal steady state,
7562 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7563 // should only happen during initial block download.
7564 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
7565 pto->fDisconnect = true;
7567 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
7568 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7569 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7570 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
7571 // to unreasonably increase our timeout.
7572 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7573 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7574 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7575 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7576 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7577 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7578 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
7579 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
7580 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7581 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7582 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7584 if (queuedBlock.nTimeDisconnect < nNow) {
7585 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7586 pto->fDisconnect = true;
7591 // Message: getdata (blocks)
7593 static uint256 zero;
7594 vector<CInv> vGetData;
7595 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
7596 vector<CBlockIndex*> vToDownload;
7597 NodeId staller = -1;
7598 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7599 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7600 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
7601 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
7602 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
7603 pindex->GetHeight(), pto->id);
7605 if (state.nBlocksInFlight == 0 && staller != -1) {
7606 if (State(staller)->nStallingSince == 0) {
7607 State(staller)->nStallingSince = nNow;
7608 LogPrint("net", "Stall started peer=%d\n", staller);
7612 /*CBlockIndex *pindex;
7613 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
7615 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7616 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7617 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7618 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
7619 komodo_requestedcount++;
7620 if ( komodo_requestedcount > 16 )
7622 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7623 komodo_requestedcount = 0;
7628 // Message: getdata (non-blocks)
7630 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
7632 const CInv& inv = (*pto->mapAskFor.begin()).second;
7633 if (!AlreadyHave(inv))
7636 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
7637 vGetData.push_back(inv);
7638 if (vGetData.size() >= 1000)
7640 pto->PushMessage("getdata", vGetData);
7644 //If we're not going to ask, don't expect a response.
7645 pto->setAskFor.erase(inv.hash);
7647 pto->mapAskFor.erase(pto->mapAskFor.begin());
7649 if (!vGetData.empty())
7650 pto->PushMessage("getdata", vGetData);
7656 std::string CBlockFileInfo::ToString() const {
7657 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));
7662 static class CMainCleanup
7668 BlockMap::iterator it1 = mapBlockIndex.begin();
7669 for (; it1 != mapBlockIndex.end(); it1++)
7670 delete (*it1).second;
7671 mapBlockIndex.clear();
7673 // orphan transactions
7674 mapOrphanTransactions.clear();
7675 mapOrphanTransactionsByPrev.clear();
7677 } instance_of_cmaincleanup;
7679 extern "C" const char* getDataDir()
7681 return GetDataDir().string().c_str();
7685 // Set default values of new CMutableTransaction based on consensus rules at given height.
7686 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7688 CMutableTransaction mtx;
7690 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7691 if (isOverwintered) {
7692 mtx.fOverwintered = true;
7693 mtx.nExpiryHeight = nHeight + expiryDelta;
7695 if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) {
7696 mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
7697 mtx.nVersion = SAPLING_TX_VERSION;
7699 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7700 mtx.nVersion = OVERWINTER_TX_VERSION;
7701 mtx.nExpiryHeight = std::min(
7703 static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));