1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
12 #include "arith_uint256.h"
13 #include "importcoin.h"
14 #include "chainparams.h"
15 #include "checkpoints.h"
16 #include "checkqueue.h"
17 #include "consensus/upgrades.h"
18 #include "consensus/validation.h"
19 #include "deprecation.h"
21 #include "merkleblock.h"
23 #include "notarisationdb.h"
26 #include "script/interpreter.h"
28 #include "txmempool.h"
29 #include "ui_interface.h"
32 #include "utilmoneystr.h"
33 #include "validationinterface.h"
34 #include "wallet/asyncrpcoperation_sendmany.h"
35 #include "wallet/asyncrpcoperation_shieldcoinbase.h"
41 #include <unordered_map>
43 #include <boost/algorithm/string/replace.hpp>
44 #include <boost/filesystem.hpp>
45 #include <boost/filesystem/fstream.hpp>
46 #include <boost/math/distributions/poisson.hpp>
47 #include <boost/thread.hpp>
48 #include <boost/static_assert.hpp>
53 # error "Zcash cannot be compiled without assertions."
56 #include "librustzcash.h"
62 CCriticalSection cs_main;
63 extern uint8_t NOTARY_PUBKEY33[33];
64 extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING;
65 int32_t KOMODO_NEWBLOCKS;
66 int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
67 void komodo_broadcast(CBlock *pblock,int32_t limit);
69 BlockMap mapBlockIndex;
71 CBlockIndex *pindexBestHeader = NULL;
72 static int64_t nTimeBestReceived = 0;
73 CWaitableCriticalSection csBestBlock;
74 CConditionVariable cvBlockChange;
75 int nScriptCheckThreads = 0;
76 bool fExperimentalMode = false;
77 bool fImporting = false;
78 bool fReindex = false;
79 bool fTxIndex = false;
80 bool fAddressIndex = false;
81 bool fTimestampIndex = false;
82 bool fSpentIndex = false;
83 bool fHavePruned = false;
84 bool fPruneMode = false;
85 bool fIsBareMultisigStd = true;
86 bool fCheckBlockIndex = false;
87 bool fCheckpointsEnabled = true;
88 bool fCoinbaseEnforcedProtectionEnabled = true;
89 size_t nCoinCacheUsage = 5000 * 300;
90 uint64_t nPruneTarget = 0;
91 bool fAlerts = DEFAULT_ALERTS;
92 /* If the tip is older than this (in seconds), the node is considered to be in initial block download.
94 int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
96 unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
98 /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
99 CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
101 CTxMemPool mempool(::minRelayTxFee);
107 map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
108 map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
109 void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
112 * Returns true if there are nRequired or more blocks of minVersion or above
113 * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
115 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
116 static void CheckBlockIndex();
118 /** Constant stuff for coinbase transactions we create: */
119 CScript COINBASE_FLAGS;
121 const string strMessageMagic = "Komodo Signed Message:\n";
126 struct CBlockIndexWorkComparator
128 bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
129 // First sort by most total work, ...
130 if (pa->nChainWork > pb->nChainWork) return false;
131 if (pa->nChainWork < pb->nChainWork) return true;
133 // ... then by earliest time received, ...
134 if (pa->nSequenceId < pb->nSequenceId) return false;
135 if (pa->nSequenceId > pb->nSequenceId) return true;
137 // Use pointer address as tie breaker (should only happen with blocks
138 // loaded from disk, as those all have id 0).
139 if (pa < pb) return false;
140 if (pa > pb) return true;
147 CBlockIndex *pindexBestInvalid;
150 * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
151 * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
152 * missing the data for the block.
154 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
155 /** Number of nodes with fSyncStarted. */
156 int nSyncStarted = 0;
157 /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
158 * Pruned nodes may have entries where B is missing data.
160 multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
162 CCriticalSection cs_LastBlockFile;
163 std::vector<CBlockFileInfo> vinfoBlockFile;
164 int nLastBlockFile = 0;
165 /** Global flag to indicate we should check to see if there are
166 * block/undo files that should be deleted. Set on startup
167 * or if we allocate more file space when we're in prune mode
169 bool fCheckForPruning = false;
172 * Every received block is assigned a unique and increasing identifier, so we
173 * know which one to give priority in case of a fork.
175 CCriticalSection cs_nBlockSequenceId;
176 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
177 uint32_t nBlockSequenceId = 1;
180 * Sources of received blocks, saved to be able to send them reject
181 * messages or ban them when processing happens afterwards. Protected by
184 map<uint256, NodeId> mapBlockSource;
187 * Filter for transactions that were recently rejected by
188 * AcceptToMemoryPool. These are not rerequested until the chain tip
189 * changes, at which point the entire filter is reset. Protected by
192 * Without this filter we'd be re-requesting txs from each of our peers,
193 * increasing bandwidth consumption considerably. For instance, with 100
194 * peers, half of which relay a tx we don't accept, that might be a 50x
195 * bandwidth increase. A flooding attacker attempting to roll-over the
196 * filter using minimum-sized, 60byte, transactions might manage to send
197 * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
198 * two minute window to send invs to us.
200 * Decreasing the false positive rate is fairly cheap, so we pick one in a
201 * million to make it highly unlikely for users to have issues with this
206 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
207 uint256 hashRecentRejectsChainTip;
209 /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
212 CBlockIndex *pindex; //! Optional.
213 int64_t nTime; //! Time of "getdata" request in microseconds.
214 bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
215 int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
217 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
219 /** Number of blocks in flight with validated headers. */
220 int nQueuedValidatedHeaders = 0;
222 /** Number of preferable block download peers. */
223 int nPreferredDownload = 0;
225 /** Dirty block index entries. */
226 set<CBlockIndex*> setDirtyBlockIndex;
228 /** Dirty block file entries. */
229 set<int> setDirtyFileInfo;
232 //////////////////////////////////////////////////////////////////////////////
234 // Registration of network node signals.
239 struct CBlockReject {
240 unsigned char chRejectCode;
241 string strRejectReason;
246 * Maintain validation-specific state about nodes, protected by cs_main, instead
247 * by CNode's own locks. This simplifies asynchronous operation, where
248 * processing of incoming data is done after the ProcessMessage call returns,
249 * and we're no longer holding the node's locks.
252 //! The peer's address
254 //! Whether we have a fully established connection.
255 bool fCurrentlyConnected;
256 //! Accumulated misbehaviour score for this peer.
258 //! Whether this peer should be disconnected and banned (unless whitelisted).
260 //! String name of this peer (debugging/logging purposes).
262 //! List of asynchronously-determined block rejections to notify this peer about.
263 std::vector<CBlockReject> rejects;
264 //! The best known block we know this peer has announced.
265 CBlockIndex *pindexBestKnownBlock;
266 //! The hash of the last unknown block this peer has announced.
267 uint256 hashLastUnknownBlock;
268 //! The last full block we both have.
269 CBlockIndex *pindexLastCommonBlock;
270 //! Whether we've started headers synchronization with this peer.
272 //! Since when we're stalling block download progress (in microseconds), or 0.
273 int64_t nStallingSince;
274 list<QueuedBlock> vBlocksInFlight;
276 int nBlocksInFlightValidHeaders;
277 //! Whether we consider this a preferred download peer.
278 bool fPreferredDownload;
281 fCurrentlyConnected = false;
284 pindexBestKnownBlock = NULL;
285 hashLastUnknownBlock.SetNull();
286 pindexLastCommonBlock = NULL;
287 fSyncStarted = false;
290 nBlocksInFlightValidHeaders = 0;
291 fPreferredDownload = false;
295 /** Map maintaining per-node state. Requires cs_main. */
296 map<NodeId, CNodeState> mapNodeState;
299 CNodeState *State(NodeId pnode) {
300 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
301 if (it == mapNodeState.end())
309 return chainActive.Height();
312 void UpdatePreferredDownload(CNode* node, CNodeState* state)
314 nPreferredDownload -= state->fPreferredDownload;
316 // Whether this node should be marked as a preferred download node.
317 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
319 nPreferredDownload += state->fPreferredDownload;
322 // Returns time at which to timeout block request (nTime in microseconds)
323 int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
325 return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
328 void InitializeNode(NodeId nodeid, const CNode *pnode) {
330 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
331 state.name = pnode->addrName;
332 state.address = pnode->addr;
335 void FinalizeNode(NodeId nodeid) {
337 CNodeState *state = State(nodeid);
339 if (state->fSyncStarted)
342 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
343 AddressCurrentlyConnected(state->address);
346 BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
347 mapBlocksInFlight.erase(entry.hash);
348 EraseOrphansFor(nodeid);
349 nPreferredDownload -= state->fPreferredDownload;
351 mapNodeState.erase(nodeid);
354 void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
356 /* int expired = pool.Expire(GetTime() - age);
358 LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
360 std::vector<uint256> vNoSpendsRemaining;
361 pool.TrimToSize(limit, &vNoSpendsRemaining);
362 BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
363 pcoinsTip->Uncache(removed);*/
367 // Returns a bool indicating whether we requested this block.
368 bool MarkBlockAsReceived(const uint256& hash) {
369 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
370 if (itInFlight != mapBlocksInFlight.end()) {
371 CNodeState *state = State(itInFlight->second.first);
372 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
373 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
374 state->vBlocksInFlight.erase(itInFlight->second.second);
375 state->nBlocksInFlight--;
376 state->nStallingSince = 0;
377 mapBlocksInFlight.erase(itInFlight);
384 void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
385 CNodeState *state = State(nodeid);
386 assert(state != NULL);
388 // Make sure it's not listed somewhere already.
389 MarkBlockAsReceived(hash);
391 int64_t nNow = GetTimeMicros();
392 QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
393 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
394 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
395 state->nBlocksInFlight++;
396 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
397 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
400 /** Check whether the last unknown block a peer advertized is not yet known. */
401 void ProcessBlockAvailability(NodeId nodeid) {
402 CNodeState *state = State(nodeid);
403 assert(state != NULL);
405 if (!state->hashLastUnknownBlock.IsNull()) {
406 BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
407 if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0)
409 if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
410 state->pindexBestKnownBlock = itOld->second;
411 state->hashLastUnknownBlock.SetNull();
416 /** Update tracking information about which blocks a peer is assumed to have. */
417 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
418 CNodeState *state = State(nodeid);
419 assert(state != NULL);
421 /*ProcessBlockAvailability(nodeid);
423 BlockMap::iterator it = mapBlockIndex.find(hash);
424 if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
425 // An actually better block was announced.
426 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
427 state->pindexBestKnownBlock = it->second;
430 // An unknown block was announced; just assume that the latest one is the best one.
431 state->hashLastUnknownBlock = hash;
435 /** Find the last common ancestor two blocks have.
436 * Both pa and pb must be non-NULL. */
437 CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
438 if (pa->nHeight > pb->nHeight) {
439 pa = pa->GetAncestor(pb->nHeight);
440 } else if (pb->nHeight > pa->nHeight) {
441 pb = pb->GetAncestor(pa->nHeight);
444 while (pa != pb && pa && pb) {
449 // Eventually all chain branches meet at the genesis block.
454 /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
455 * at most count entries. */
456 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
460 vBlocks.reserve(vBlocks.size() + count);
461 CNodeState *state = State(nodeid);
462 assert(state != NULL);
464 // Make sure pindexBestKnownBlock is up to date, we'll need it.
465 ProcessBlockAvailability(nodeid);
467 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
468 // This peer has nothing interesting.
472 if (state->pindexLastCommonBlock == NULL) {
473 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
474 // Guessing wrong in either direction is not a problem.
475 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
478 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
479 // of its current tip anymore. Go back enough to fix that.
480 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
481 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
484 std::vector<CBlockIndex*> vToFetch;
485 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
486 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
487 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
488 // download that next block if the window were 1 larger.
489 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
490 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
491 NodeId waitingfor = -1;
492 while (pindexWalk->nHeight < nMaxHeight) {
493 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
494 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
495 // as iterating over ~100 CBlockIndex* entries anyway.
496 int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
497 vToFetch.resize(nToFetch);
498 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
499 vToFetch[nToFetch - 1] = pindexWalk;
500 for (unsigned int i = nToFetch - 1; i > 0; i--) {
501 vToFetch[i - 1] = vToFetch[i]->pprev;
504 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
505 // are not yet downloaded and not in flight to vBlocks. In the meantime, update
506 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
507 // already part of our chain (and therefore don't need it even if pruned).
508 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
509 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
510 // We consider the chain that this peer is on invalid.
513 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
514 if (pindex->nChainTx)
515 state->pindexLastCommonBlock = pindex;
516 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
517 // The block is not already downloaded, and not yet in flight.
518 if (pindex->nHeight > nWindowEnd) {
519 // We reached the end of the window.
520 if (vBlocks.size() == 0 && waitingfor != nodeid) {
521 // We aren't able to fetch anything, but we would be if the download window was one larger.
522 nodeStaller = waitingfor;
526 vBlocks.push_back(pindex);
527 if (vBlocks.size() == count) {
530 } else if (waitingfor == -1) {
531 // This is the first already-in-flight block.
532 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
540 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
542 CNodeState *state = State(nodeid);
545 stats.nMisbehavior = state->nMisbehavior;
546 stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
547 stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
548 BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
550 stats.vHeightInFlight.push_back(queue.pindex->nHeight);
555 void RegisterNodeSignals(CNodeSignals& nodeSignals)
557 nodeSignals.GetHeight.connect(&GetHeight);
558 nodeSignals.ProcessMessages.connect(&ProcessMessages);
559 nodeSignals.SendMessages.connect(&SendMessages);
560 nodeSignals.InitializeNode.connect(&InitializeNode);
561 nodeSignals.FinalizeNode.connect(&FinalizeNode);
564 void UnregisterNodeSignals(CNodeSignals& nodeSignals)
566 nodeSignals.GetHeight.disconnect(&GetHeight);
567 nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
568 nodeSignals.SendMessages.disconnect(&SendMessages);
569 nodeSignals.InitializeNode.disconnect(&InitializeNode);
570 nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
573 CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
575 // Find the first block the caller has in the main chain
576 BOOST_FOREACH(const uint256& hash, locator.vHave) {
577 BlockMap::iterator mi = mapBlockIndex.find(hash);
578 if (mi != mapBlockIndex.end())
580 CBlockIndex* pindex = (*mi).second;
581 if (pindex != 0 && chain.Contains(pindex))
583 if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
588 return chain.Genesis();
591 CCoinsViewCache *pcoinsTip = NULL;
592 CBlockTreeDB *pblocktree = NULL;
599 UniValue komodo_snapshot(int top)
603 UniValue result(UniValue::VOBJ);
606 if ( pblocktree != 0 ) {
607 result = pblocktree->Snapshot(top);
609 fprintf(stderr,"null pblocktree start with -addressindex=1\n");
612 fprintf(stderr,"getsnapshot requires -addressindex=1\n");
617 //////////////////////////////////////////////////////////////////////////////
619 // mapOrphanTransactions
622 bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
624 uint256 hash = tx.GetHash();
625 if (mapOrphanTransactions.count(hash))
628 // Ignore big transactions, to avoid a
629 // send-big-orphans memory exhaustion attack. If a peer has a legitimate
630 // large transaction with a missing parent then we assume
631 // it will rebroadcast it later, after the parent transaction(s)
632 // have been mined or received.
633 // 10,000 orphans, each of which is at most 5,000 bytes big is
634 // at most 500 megabytes of orphans:
635 unsigned int sz = GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
638 LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
642 mapOrphanTransactions[hash].tx = tx;
643 mapOrphanTransactions[hash].fromPeer = peer;
644 BOOST_FOREACH(const CTxIn& txin, tx.vin)
645 mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
647 LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
648 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
652 void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
654 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
655 if (it == mapOrphanTransactions.end())
657 BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
659 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
660 if (itPrev == mapOrphanTransactionsByPrev.end())
662 itPrev->second.erase(hash);
663 if (itPrev->second.empty())
664 mapOrphanTransactionsByPrev.erase(itPrev);
666 mapOrphanTransactions.erase(it);
669 void EraseOrphansFor(NodeId peer)
672 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
673 while (iter != mapOrphanTransactions.end())
675 map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
676 if (maybeErase->second.fromPeer == peer)
678 EraseOrphanTx(maybeErase->second.tx.GetHash());
682 if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
686 unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
688 unsigned int nEvicted = 0;
689 while (mapOrphanTransactions.size() > nMaxOrphans)
691 // Evict a random orphan:
692 uint256 randomhash = GetRandHash();
693 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
694 if (it == mapOrphanTransactions.end())
695 it = mapOrphanTransactions.begin();
696 EraseOrphanTx(it->first);
703 bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
705 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
706 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
709 // Sapling standard rules apply
710 if (tx.nVersion > CTransaction::SAPLING_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SAPLING_MIN_CURRENT_VERSION) {
711 reason = "sapling-version";
714 } else if (overwinterActive) {
715 // Overwinter standard rules apply
716 if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
717 reason = "overwinter-version";
721 // Sprout standard rules apply
722 if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
728 BOOST_FOREACH(const CTxIn& txin, tx.vin)
730 // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
731 // keys. (remember the 520 byte limit on redeemScript size) That works
732 // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
733 // bytes of scriptSig, which we round off to 1650 bytes for some minor
734 // future-proofing. That's also enough to spend a 20-of-20
735 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
736 // considered standard)
737 if (txin.scriptSig.size() > 1650) {
738 reason = "scriptsig-size";
741 if (!txin.scriptSig.IsPushOnly()) {
742 reason = "scriptsig-not-pushonly";
747 unsigned int v=0,nDataOut = 0;
748 txnouttype whichType;
749 BOOST_FOREACH(const CTxOut& txout, tx.vout)
751 if (!::IsStandard(txout.scriptPubKey, whichType))
753 reason = "scriptpubkey";
754 //fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
758 if (whichType == TX_NULL_DATA)
760 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
762 reason = "opreturn too big";
766 //fprintf(stderr,"is OP_RETURN\n");
768 else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
769 reason = "bare-multisig";
771 } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) {
778 // only one OP_RETURN txout is permitted
780 reason = "multi-op-return";
787 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
790 if (tx.nLockTime == 0)
792 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
794 BOOST_FOREACH(const CTxIn& txin, tx.vin)
796 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)) )
800 else if (!txin.IsFinal())
802 //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
809 bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
811 if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
814 return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
817 bool CheckFinalTx(const CTransaction &tx, int flags)
819 AssertLockHeld(cs_main);
821 // By convention a negative value for flags indicates that the
822 // current network-enforced consensus rules should be used. In
823 // a future soft-fork scenario that would mean checking which
824 // rules would be enforced for the next block and setting the
825 // appropriate flags. At the present time no soft-forks are
826 // scheduled, so no flags are set.
827 flags = std::max(flags, 0);
829 // CheckFinalTx() uses chainActive.Height()+1 to evaluate
830 // nLockTime because when IsFinalTx() is called within
831 // CBlock::AcceptBlock(), the height of the block *being*
832 // evaluated is what is used. Thus if we want to know if a
833 // transaction can be part of the *next* block, we need to call
834 // IsFinalTx() with one more than chainActive.Height().
835 const int nBlockHeight = chainActive.Height() + 1;
837 // Timestamps on the other hand don't get any special treatment,
838 // because we can't know what timestamp the next block will have,
839 // and there aren't timestamp applications where it matters.
840 // However this changes once median past time-locks are enforced:
841 const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
842 ? chainActive.Tip()->GetMedianTimePast()
845 return IsFinalTx(tx, nBlockHeight, nBlockTime);
849 * Check transaction inputs to mitigate two
850 * potential denial-of-service attacks:
852 * 1. scriptSigs with extra data stuffed into them,
853 * not consumed by scriptPubKey (or P2SH script)
854 * 2. P2SH scripts with a crazy number of expensive
855 * CHECKSIG/CHECKMULTISIG operations
857 bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
860 return true; // Coinbases don't use vin normally
862 if (tx.IsCoinImport())
863 return tx.vin[0].scriptSig.IsCoinImport();
865 for (unsigned int i = 0; i < tx.vin.size(); i++)
867 const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
869 vector<vector<unsigned char> > vSolutions;
870 txnouttype whichType;
871 // get the scriptPubKey corresponding to this input:
872 const CScript& prevScript = prev.scriptPubKey;
873 //printf("Previous script: %s\n", prevScript.ToString().c_str());
875 if (!Solver(prevScript, whichType, vSolutions))
877 int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
878 if (nArgsExpected < 0)
881 // Transactions with extra stuff in their scriptSigs are
882 // non-standard. Note that this EvalScript() call will
883 // be quick, because if there are any operations
884 // beside "push data" in the scriptSig
885 // IsStandardTx() will have already returned false
886 // and this method isn't called.
887 vector<vector<unsigned char> > stack;
888 //printf("Checking script: %s\n", tx.vin[i].scriptSig.ToString().c_str());
889 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
892 if (whichType == TX_SCRIPTHASH)
896 CScript subscript(stack.back().begin(), stack.back().end());
897 vector<vector<unsigned char> > vSolutions2;
898 txnouttype whichType2;
899 if (Solver(subscript, whichType2, vSolutions2))
901 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
904 nArgsExpected += tmpExpected;
908 // Any other Script with less than 15 sigops OK:
909 unsigned int sigops = subscript.GetSigOpCount(true);
910 // ... extra data left on the stack after execution is OK, too:
911 return (sigops <= MAX_P2SH_SIGOPS);
915 if (stack.size() != (unsigned int)nArgsExpected)
922 unsigned int GetLegacySigOpCount(const CTransaction& tx)
924 unsigned int nSigOps = 0;
925 BOOST_FOREACH(const CTxIn& txin, tx.vin)
927 nSigOps += txin.scriptSig.GetSigOpCount(false);
929 BOOST_FOREACH(const CTxOut& txout, tx.vout)
931 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
936 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
938 if (tx.IsCoinBase() || tx.IsCoinImport())
941 unsigned int nSigOps = 0;
942 for (unsigned int i = 0; i < tx.vin.size(); i++)
944 const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
945 if (prevout.scriptPubKey.IsPayToScriptHash())
946 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
952 * Ensure that a coinbase transaction is structured according to the consensus rules of the
955 bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight)
957 // if time locks are on, ensure that this coin base is time locked exactly as it should be
958 if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) ||
959 (((nHeight >= 31680) || strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE))
961 CScriptID scriptHash;
963 // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that
964 // holds the full output script, which may include multisig, etc., but starts with
965 // the time lock verify of the correct time lock for this block height
966 if (tx.vout.size() == 2 &&
967 CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) &&
968 tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
969 tx.vout[1].scriptPubKey[0] == OP_RETURN)
972 std::vector<uint8_t> opretData = std::vector<uint8_t>();
973 CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
974 if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
976 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
979 CScriptExt opretScript = CScriptExt(&opretData[1], &opretData[opretData.size()]);
981 if (CScriptID(opretScript) == scriptHash &&
982 opretScript.IsCheckLockTimeVerify(&unlocktime) &&
983 komodo_block_unlocktime(nHeight) == unlocktime)
996 * Check a transaction contextually against a set of consensus rules valid at a given block height.
999 * 1. AcceptToMemoryPool calls CheckTransaction and this function.
1000 * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
1001 * and ContextualCheckBlock (which calls this function).
1003 bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, const int nHeight, const int dosLevel)
1005 bool overwinterActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
1006 bool saplingActive = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING);
1007 bool isSprout = !overwinterActive;
1009 // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
1010 if (isSprout && tx.fOverwintered) {
1011 return state.DoS(IsInitialBlockDownload() ? 0 : dosLevel,
1012 error("ContextualCheckTransaction(): overwinter is not active yet"),
1013 REJECT_INVALID, "tx-overwinter-not-active");
1016 if (saplingActive) {
1017 // Reject transactions with valid version but missing overwintered flag
1018 if (tx.nVersion >= SAPLING_MIN_TX_VERSION && !tx.fOverwintered) {
1019 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwintered flag must be set"),
1020 REJECT_INVALID, "tx-overwintered-flag-not-set");
1023 // Reject transactions with non-Sapling version group ID
1024 if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1025 return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),
1026 REJECT_INVALID, "bad-sapling-tx-version-group-id");
1029 // Reject transactions with invalid version
1030 if (tx.fOverwintered && tx.nVersion < SAPLING_MIN_TX_VERSION ) {
1031 return state.DoS(100, error("CheckTransaction(): Sapling version too low"),
1032 REJECT_INVALID, "bad-tx-sapling-version-too-low");
1035 // Reject transactions with invalid version
1036 if (tx.fOverwintered && tx.nVersion > SAPLING_MAX_TX_VERSION ) {
1037 return state.DoS(100, error("CheckTransaction(): Sapling version too high"),
1038 REJECT_INVALID, "bad-tx-sapling-version-too-high");
1040 } else if (overwinterActive) {
1041 // Reject transactions with valid version but missing overwinter flag
1042 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
1043 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
1044 REJECT_INVALID, "tx-overwinter-flag-not-set");
1047 // Reject transactions with non-Overwinter version group ID
1048 if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1049 return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),
1050 REJECT_INVALID, "bad-overwinter-tx-version-group-id");
1053 // Reject transactions with invalid version
1054 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
1055 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
1056 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
1060 // Rules that apply to Overwinter or later:
1061 if (overwinterActive) {
1062 // Reject transactions intended for Sprout
1063 if (!tx.fOverwintered) {
1064 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
1065 REJECT_INVALID, "tx-overwinter-active");
1068 // Check that all transactions are unexpired
1069 if (IsExpiredTx(tx, nHeight)) {
1070 // Don't increase banscore if the transaction only just expired
1071 int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? dosLevel : 0;
1072 return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
1076 // Rules that apply before Sapling:
1077 if (!saplingActive) {
1079 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1080 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_BEFORE_SAPLING)
1081 return state.DoS(100, error("ContextualCheckTransaction(): size limits failed"),
1082 REJECT_INVALID, "bad-txns-oversize");
1085 uint256 dataToBeSigned;
1088 (!tx.vjoinsplit.empty() ||
1089 !tx.vShieldedSpend.empty() ||
1090 !tx.vShieldedOutput.empty()))
1092 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
1093 // Empty output script.
1096 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1097 } catch (std::logic_error ex) {
1098 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
1099 REJECT_INVALID, "error-computing-signature-hash");
1104 if (!(tx.IsMint() || tx.vjoinsplit.empty()))
1106 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
1108 // We rely on libsodium to check that the signature is canonical.
1109 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1110 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1111 dataToBeSigned.begin(), 32,
1112 tx.joinSplitPubKey.begin()
1114 return state.DoS(IsInitialBlockDownload() ? 0 : 100,
1115 error("CheckTransaction(): invalid joinsplit signature"),
1116 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
1120 if (tx.IsCoinBase())
1122 if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1123 return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1124 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
1127 if (!tx.vShieldedSpend.empty() ||
1128 !tx.vShieldedOutput.empty())
1130 auto ctx = librustzcash_sapling_verification_ctx_init();
1132 for (const SpendDescription &spend : tx.vShieldedSpend) {
1133 if (!librustzcash_sapling_check_spend(
1136 spend.anchor.begin(),
1137 spend.nullifier.begin(),
1139 spend.zkproof.begin(),
1140 spend.spendAuthSig.begin(),
1141 dataToBeSigned.begin()
1144 librustzcash_sapling_verification_ctx_free(ctx);
1145 return state.DoS(100, error("ContextualCheckTransaction(): Sapling spend description invalid"),
1146 REJECT_INVALID, "bad-txns-sapling-spend-description-invalid");
1150 for (const OutputDescription &output : tx.vShieldedOutput) {
1151 if (!librustzcash_sapling_check_output(
1155 output.ephemeralKey.begin(),
1156 output.zkproof.begin()
1159 librustzcash_sapling_verification_ctx_free(ctx);
1160 return state.DoS(100, error("ContextualCheckTransaction(): Sapling output description invalid"),
1161 REJECT_INVALID, "bad-txns-sapling-output-description-invalid");
1165 if (!librustzcash_sapling_final_check(
1168 tx.bindingSig.begin(),
1169 dataToBeSigned.begin()
1172 librustzcash_sapling_verification_ctx_free(ctx);
1173 return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"),
1174 REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid");
1177 librustzcash_sapling_verification_ctx_free(ctx);
1182 bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1183 libzcash::ProofVerifier& verifier)
1185 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
1186 if ( *(int32_t *)&array[0] == 0 )
1187 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
1191 for (k=0; k<numbanned; k++)
1193 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
1195 static uint32_t counter;
1196 if ( counter++ < 100 )
1197 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->nHeight,j);
1202 // Don't count coinbase transactions because mining skews the count
1203 if (!tx.IsCoinBase()) {
1204 transactionsValidated.increment();
1207 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1210 // Ensure that zk-SNARKs v|| y
1211 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1212 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
1213 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
1214 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
1221 bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
1223 // Basic checks that don't depend on any context
1227 * 1. The consensus rule below was:
1228 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1229 * which checked if tx.nVersion fell within the range:
1230 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1231 * 2. The parser allowed tx.nVersion to be negative
1234 * 1. The consensus rule checks to see if tx.Version falls within the range:
1235 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1236 * 2. The previous consensus rule checked for negative values within the range:
1237 * INT32_MIN <= tx.nVersion < 0
1238 * This is unnecessary for Overwinter transactions since the parser now
1239 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1240 * and when Overwinter is not active ContextualCheckTransaction rejects
1241 * transactions with fOverwintered set. When fOverwintered is set,
1242 * this function and ContextualCheckTransaction will together check to
1243 * ensure tx.nVersion avoids the following ranges:
1244 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1245 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1247 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
1248 return state.DoS(100, error("CheckTransaction(): version too low"),
1249 REJECT_INVALID, "bad-txns-version-too-low");
1251 else if (tx.fOverwintered) {
1252 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1253 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
1254 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
1256 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID &&
1257 tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) {
1258 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
1259 REJECT_INVALID, "bad-tx-version-group-id");
1261 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1262 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
1263 REJECT_INVALID, "bad-tx-expiry-height-too-high");
1267 // Transactions containing empty `vin` must have either non-empty
1268 // `vjoinsplit` or non-empty `vShieldedSpend`.
1269 if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
1270 return state.DoS(10, error("CheckTransaction(): vin empty"),
1271 REJECT_INVALID, "bad-txns-vin-empty");
1272 // Transactions containing empty `vout` must have either non-empty
1273 // `vjoinsplit` or non-empty `vShieldedOutput`.
1274 if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
1275 return state.DoS(10, error("CheckTransaction(): vout empty"),
1276 REJECT_INVALID, "bad-txns-vout-empty");
1279 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE >= MAX_TX_SIZE_AFTER_SAPLING); // sanity
1280 BOOST_STATIC_ASSERT(MAX_TX_SIZE_AFTER_SAPLING > MAX_TX_SIZE_BEFORE_SAPLING); // sanity
1281 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE_AFTER_SAPLING)
1282 return state.DoS(100, error("CheckTransaction(): size limits failed"),
1283 REJECT_INVALID, "bad-txns-oversize");
1285 // Check for negative or overflow output values
1286 CAmount nValueOut = 0;
1287 int32_t iscoinbase = tx.IsCoinBase();
1288 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1290 if (txout.nValue < 0)
1291 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
1292 REJECT_INVALID, "bad-txns-vout-negative");
1293 if (txout.nValue > MAX_MONEY)
1295 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1296 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1298 if ( ASSETCHAINS_PRIVATE != 0 )
1300 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
1301 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetValueOut() > 0 )
1302 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
1304 if ( txout.scriptPubKey.size() > IGUANA_MAXSCRIPTSIZE )
1305 return state.DoS(100, error("CheckTransaction(): txout.scriptPubKey.size() too big"),REJECT_INVALID, "bad-txns-vout-negative");
1306 nValueOut += txout.nValue;
1307 if (!MoneyRange(nValueOut))
1308 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1309 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1312 // Check for non-zero valueBalance when there are no Sapling inputs or outputs
1313 if (tx.vShieldedSpend.empty() && tx.vShieldedOutput.empty() && tx.valueBalance != 0) {
1314 return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"),
1315 REJECT_INVALID, "bad-txns-valuebalance-nonzero");
1318 // Check for overflow valueBalance
1319 if (tx.valueBalance > MAX_MONEY || tx.valueBalance < -MAX_MONEY) {
1320 return state.DoS(100, error("CheckTransaction(): abs(tx.valueBalance) too large"),
1321 REJECT_INVALID, "bad-txns-valuebalance-toolarge");
1324 if (tx.valueBalance <= 0) {
1325 // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
1326 nValueOut += -tx.valueBalance;
1328 if (!MoneyRange(nValueOut)) {
1329 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1330 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1334 // Ensure that joinsplit values are well-formed
1335 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1337 if ( ASSETCHAINS_PUBLIC != 0 )
1339 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1340 REJECT_INVALID, "bad-txns-acprivacy-chain");
1342 if (joinsplit.vpub_old < 0) {
1343 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
1344 REJECT_INVALID, "bad-txns-vpub_old-negative");
1347 if (joinsplit.vpub_new < 0) {
1348 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
1349 REJECT_INVALID, "bad-txns-vpub_new-negative");
1352 if (joinsplit.vpub_old > MAX_MONEY) {
1353 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
1354 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
1357 if (joinsplit.vpub_new > MAX_MONEY) {
1358 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
1359 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
1362 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1363 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
1364 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1367 nValueOut += joinsplit.vpub_old;
1368 if (!MoneyRange(nValueOut)) {
1369 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1370 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
1374 // Ensure input values do not exceed MAX_MONEY
1375 // We have not resolved the txin values at this stage,
1376 // but we do know what the joinsplits claim to add
1377 // to the value pool.
1379 CAmount nValueIn = 0;
1380 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1382 nValueIn += it->vpub_new;
1384 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1385 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1386 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1390 // Also check for Sapling
1391 if (tx.valueBalance >= 0) {
1392 // NB: positive valueBalance "adds" money to the transparent value pool, just as inputs do
1393 nValueIn += tx.valueBalance;
1395 if (!MoneyRange(nValueIn)) {
1396 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1397 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1402 // Check for duplicate inputs
1403 set<COutPoint> vInOutPoints;
1404 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1406 if (vInOutPoints.count(txin.prevout))
1407 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
1408 REJECT_INVALID, "bad-txns-inputs-duplicate");
1409 vInOutPoints.insert(txin.prevout);
1412 // Check for duplicate joinsplit nullifiers in this transaction
1414 set<uint256> vJoinSplitNullifiers;
1415 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
1417 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
1419 if (vJoinSplitNullifiers.count(nf))
1420 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1421 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1423 vJoinSplitNullifiers.insert(nf);
1428 // Check for duplicate sapling nullifiers in this transaction
1430 set<uint256> vSaplingNullifiers;
1431 BOOST_FOREACH(const SpendDescription& spend_desc, tx.vShieldedSpend)
1433 if (vSaplingNullifiers.count(spend_desc.nullifier))
1434 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
1435 REJECT_INVALID, "bad-spend-description-nullifiers-duplicate");
1437 vSaplingNullifiers.insert(spend_desc.nullifier);
1443 // There should be no joinsplits in a coinbase transaction
1444 if (tx.vjoinsplit.size() > 0)
1445 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1446 REJECT_INVALID, "bad-cb-has-joinsplits");
1448 // A coinbase transaction cannot have spend descriptions or output descriptions
1449 if (tx.vShieldedSpend.size() > 0)
1450 return state.DoS(100, error("CheckTransaction(): coinbase has spend descriptions"),
1451 REJECT_INVALID, "bad-cb-has-spend-description");
1452 if (tx.vShieldedOutput.size() > 0)
1453 return state.DoS(100, error("CheckTransaction(): coinbase has output descriptions"),
1454 REJECT_INVALID, "bad-cb-has-output-description");
1456 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
1457 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
1458 REJECT_INVALID, "bad-cb-length");
1462 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1463 if (txin.prevout.IsNull())
1464 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1465 REJECT_INVALID, "bad-txns-prevout-null");
1471 CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
1473 extern int32_t KOMODO_ON_DEMAND;
1476 uint256 hash = tx.GetHash();
1477 double dPriorityDelta = 0;
1478 CAmount nFeeDelta = 0;
1479 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1480 if (dPriorityDelta > 0 || nFeeDelta > 0)
1484 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
1488 // There is a free transaction area in blocks created by most miners,
1489 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
1490 // to be considered to fall into this category. We don't want to encourage sending
1491 // multiple transactions instead of one big transaction to avoid fees.
1492 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
1496 if (!MoneyRange(nMinFee))
1497 nMinFee = MAX_MONEY;
1502 bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
1504 AssertLockHeld(cs_main);
1505 if (pfMissingInputs)
1506 *pfMissingInputs = false;
1508 int flag=0,nextBlockHeight = chainActive.Height() + 1;
1509 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
1511 // Node operator can choose to reject tx by number of transparent inputs
1512 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1513 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1514 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
1518 size_t n = tx.vin.size();
1520 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1525 auto verifier = libzcash::ProofVerifier::Strict();
1526 if ( komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
1528 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
1529 return error("AcceptToMemoryPool: komodo_validate_interest failed");
1531 if (!CheckTransaction(tx, state, verifier))
1533 return error("AcceptToMemoryPool: CheckTransaction failed");
1535 // DoS level set to 10 to be more forgiving.
1536 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
1537 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10))
1539 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
1542 // Coinbase is only valid in a block, not as a loose transaction
1543 if (tx.IsCoinBase())
1545 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1546 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1548 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1550 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
1552 //fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
1553 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1555 // Only accept nLockTime-using transactions that can be mined in the next
1556 // block; we don't want our mempool filled up with transactions that can't
1558 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
1560 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
1561 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
1563 // is it already in the memory pool?
1564 uint256 hash = tx.GetHash();
1565 if (pool.exists(hash))
1567 //fprintf(stderr,"already in mempool\n");
1568 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
1571 // Check for conflicts with in-memory transactions
1573 LOCK(pool.cs); // protect pool.mapNextTx
1574 for (unsigned int i = 0; i < tx.vin.size(); i++)
1576 COutPoint outpoint = tx.vin[i].prevout;
1577 if (pool.mapNextTx.count(outpoint))
1579 // Disable replacement feature for now
1583 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
1584 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
1585 if (pool.nullifierExists(nf, SPROUT)) {
1586 fprintf(stderr,"pool.mapNullifiers.count\n");
1591 for (const SpendDescription &spendDescription : tx.vShieldedSpend) {
1592 if (pool.nullifierExists(spendDescription.nullifier, SAPLING)) {
1600 CCoinsViewCache view(&dummy);
1602 CAmount nValueIn = 0;
1605 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1606 view.SetBackend(viewMemPool);
1608 // do we already have it?
1609 if (view.HaveCoins(hash))
1611 //fprintf(stderr,"view.HaveCoins(hash) error\n");
1612 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
1615 if (tx.IsCoinImport())
1617 // Inverse of normal case; if input exists, it's been spent
1618 if (ExistsImportTombstone(tx, view))
1619 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
1623 // do all inputs exist?
1624 // Note that this does not check for the presence of actual outputs (see the next check for that),
1625 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1626 BOOST_FOREACH(const CTxIn txin, tx.vin)
1628 if (!view.HaveCoins(txin.prevout.hash))
1630 if (pfMissingInputs)
1631 *pfMissingInputs = true;
1632 //fprintf(stderr,"missing inputs\n");
1637 // are the actual inputs available?
1638 if (!view.HaveInputs(tx))
1640 //fprintf(stderr,"accept failure.1\n");
1641 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
1644 // are the joinsplit's requirements met?
1645 if (!view.HaveJoinSplitRequirements(tx))
1647 //fprintf(stderr,"accept failure.2\n");
1648 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1651 // Bring the best block into scope
1652 view.GetBestBlock();
1654 nValueIn = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime);
1655 if ( 0 && interest != 0 )
1656 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
1657 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1658 view.SetBackend(dummy);
1661 // Check for non-standard pay-to-script-hash in inputs
1662 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
1663 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1665 // Check that the transaction doesn't have an excessive number of
1666 // sigops, making it impossible to mine. Since the coinbase transaction
1667 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
1668 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1669 // merely non-standard transaction.
1670 unsigned int nSigOps = GetLegacySigOpCount(tx);
1671 nSigOps += GetP2SHSigOpCount(tx, view);
1672 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
1674 fprintf(stderr,"accept failure.4\n");
1675 return state.DoS(0, error("AcceptToMemoryPool: too many sigops %s, %d > %d", hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
1678 CAmount nValueOut = tx.GetValueOut();
1679 CAmount nFees = nValueIn-nValueOut;
1680 double dPriority = view.GetPriority(tx, chainActive.Height());
1682 // Keep track of transactions that spend a coinbase, which we re-scan
1683 // during reorgs to ensure COINBASE_MATURITY is still met.
1684 bool fSpendsCoinbase = false;
1685 if (!tx.IsCoinImport()) {
1686 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1687 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1688 if (coins->IsCoinBase()) {
1689 fSpendsCoinbase = true;
1695 // Grab the branch ID we expect this transaction to commit to. We don't
1696 // yet know if it does, but if the entry gets added to the mempool, then
1697 // it has passed ContextualCheckInputs and therefore this is correct.
1698 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1700 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
1701 unsigned int nSize = entry.GetTxSize();
1703 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1704 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1705 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1707 // Don't accept it if it can't get into a block
1708 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1709 if (fLimitFree && nFees < txMinFee)
1711 //fprintf(stderr,"accept failure.5\n");
1712 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1716 // Require that free transactions have sufficient priority to be mined in the next block.
1717 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
1718 fprintf(stderr,"accept failure.6\n");
1719 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1722 // Continuously rate-limit free (really, very-low-fee) transactions
1723 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1724 // be annoying or make others' transactions take longer to confirm.
1725 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1727 static CCriticalSection csFreeLimiter;
1728 static double dFreeCount;
1729 static int64_t nLastTime;
1730 int64_t nNow = GetTime();
1732 LOCK(csFreeLimiter);
1734 // Use an exponentially decaying ~10-minute window:
1735 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1737 // -limitfreerelay unit is thousand-bytes-per-minute
1738 // At default rate it would take over a month to fill 1GB
1739 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
1741 fprintf(stderr,"accept failure.7\n");
1742 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1744 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1745 dFreeCount += nSize;
1748 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
1750 string errmsg = strprintf("absurdly high fees %s, %d > %d",
1752 nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1753 LogPrint("mempool", errmsg.c_str());
1754 return state.Error("AcceptToMemoryPool: " + errmsg);
1757 // Check against previous transactions
1758 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1759 PrecomputedTransactionData txdata(tx);
1760 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1762 //fprintf(stderr,"accept failure.9\n");
1763 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
1766 // Check again against just the consensus-critical mandatory script
1767 // verification flags, in case of bugs in the standard flags that cause
1768 // transactions to pass as valid when they're actually invalid. For
1769 // instance the STRICTENC flag was incorrectly allowing certain
1770 // CHECKSIG NOT scripts to pass, even though they were invalid.
1772 // There is a similar check in CreateNewBlock() to prevent creating
1773 // invalid blocks, however allowing such transactions into the mempool
1774 // can be exploited as a DoS attack.
1775 // XXX: is this neccesary for CryptoConditions?
1776 if ( KOMODO_CONNECTING <= 0 && chainActive.LastTip() != 0 )
1779 KOMODO_CONNECTING = (1<<30) + (int32_t)chainActive.LastTip()->nHeight + 1;
1781 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
1784 KOMODO_CONNECTING = -1;
1785 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
1788 KOMODO_CONNECTING = -1;
1790 // Store transaction in memory
1791 if ( komodo_is_notarytx(tx) == 0 )
1793 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
1795 if (!tx.IsCoinImport())
1797 // Add memory address index
1798 if (fAddressIndex) {
1799 pool.addAddressIndex(entry, view);
1802 // Add memory spent index
1804 pool.addSpentIndex(entry, view);
1809 SyncWithWallets(tx, NULL);
1814 bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1816 if (!fTimestampIndex)
1817 return error("Timestamp index not enabled");
1819 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1820 return error("Unable to get hashes for timestamps");
1825 bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1830 if (mempool.getSpentIndex(key, value))
1833 if (!pblocktree->ReadSpentIndex(key, value))
1839 bool GetAddressIndex(uint160 addressHash, int type,
1840 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1843 return error("address index not enabled");
1845 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1846 return error("unable to get txids for address");
1851 bool GetAddressUnspent(uint160 addressHash, int type,
1852 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1855 return error("address index not enabled");
1857 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1858 return error("unable to get txids for address");
1863 /*uint64_t myGettxout(uint256 hash,int32_t n)
1866 LOCK2(cs_main,mempool.cs);
1867 CCoinsViewMemPool view(pcoinsTip, mempool);
1868 if (!view.GetCoins(hash, coins))
1870 if ( n < 0 || (unsigned int)n >= coins.vout.size() || coins.vout[n].IsNull() )
1872 else return(coins.vout[n].nValue);
1875 bool myAddtomempool(CTransaction &tx)
1877 CValidationState state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false;
1878 if ( mempool.lookup(tx.GetHash(),Ltx) == 0 )
1879 return(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees));
1883 bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1885 // need a GetTransaction without lock so the validation code for assets can run without deadlock
1887 //fprintf(stderr,"check mempool\n");
1888 if (mempool.lookup(hash, txOut))
1890 //fprintf(stderr,"found in mempool\n");
1894 //fprintf(stderr,"check disk\n");
1898 //fprintf(stderr,"ReadTxIndex\n");
1899 if (pblocktree->ReadTxIndex(hash, postx)) {
1900 //fprintf(stderr,"OpenBlockFile\n");
1901 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1903 return error("%s: OpenBlockFile failed", __func__);
1904 CBlockHeader header;
1905 //fprintf(stderr,"seek and read\n");
1908 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1910 } catch (const std::exception& e) {
1911 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1913 hashBlock = header.GetHash();
1914 if (txOut.GetHash() != hash)
1915 return error("%s: txid mismatch", __func__);
1916 //fprintf(stderr,"found on disk\n");
1920 //fprintf(stderr,"not found\n");
1924 /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
1925 bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1927 CBlockIndex *pindexSlow = NULL;
1931 if (mempool.lookup(hash, txOut))
1938 if (pblocktree->ReadTxIndex(hash, postx)) {
1939 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1941 return error("%s: OpenBlockFile failed", __func__);
1942 CBlockHeader header;
1945 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1947 } catch (const std::exception& e) {
1948 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1950 hashBlock = header.GetHash();
1951 if (txOut.GetHash() != hash)
1952 return error("%s: txid mismatch", __func__);
1957 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1960 CCoinsViewCache &view = *pcoinsTip;
1961 const CCoins* coins = view.AccessCoins(hash);
1963 nHeight = coins->nHeight;
1966 pindexSlow = chainActive[nHeight];
1971 if (ReadBlockFromDisk(block, pindexSlow,1)) {
1972 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1973 if (tx.GetHash() == hash) {
1975 hashBlock = pindexSlow->GetBlockHash();
1985 /*char *komodo_getspendscript(uint256 hash,int32_t n)
1987 CTransaction tx; uint256 hashBlock;
1988 if ( !GetTransaction(hash,tx,hashBlock,true) )
1990 printf("null GetTransaction\n");
1993 if ( n >= 0 && n < tx.vout.size() )
1994 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
1995 else printf("getspendscript illegal n.%d\n",n);
2000 //////////////////////////////////////////////////////////////////////////////
2002 // CBlock and CBlockIndex
2005 bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
2007 // Open history file to append
2008 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
2009 if (fileout.IsNull())
2010 return error("WriteBlockToDisk: OpenBlockFile failed");
2012 // Write index header
2013 unsigned int nSize = GetSerializeSize(fileout, block);
2014 fileout << FLATDATA(messageStart) << nSize;
2017 long fileOutPos = ftell(fileout.Get());
2019 return error("WriteBlockToDisk: ftell failed");
2020 pos.nPos = (unsigned int)fileOutPos;
2026 bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
2028 uint8_t pubkey33[33];
2031 // Open history file to read
2032 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
2033 if (filein.IsNull())
2035 //fprintf(stderr,"readblockfromdisk err A\n");
2036 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
2043 catch (const std::exception& e) {
2044 fprintf(stderr,"readblockfromdisk err B\n");
2045 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
2048 if ( 0 && checkPOW != 0 )
2050 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
2051 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
2053 int32_t i; for (i=0; i<33; i++)
2054 fprintf(stderr,"%02x",pubkey33[i]);
2055 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
2057 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
2063 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
2067 if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW))
2069 if (block.GetHash() != pindex->GetBlockHash())
2070 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
2071 pindex->ToString(), pindex->GetBlockPos().ToString());
2075 //uint64_t komodo_moneysupply(int32_t height);
2076 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
2077 extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
2078 extern uint32_t ASSETCHAINS_MAGIC;
2079 extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
2080 extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
2082 CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
2084 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
2085 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2088 return(100000000 * COIN); // ICO allocation
2089 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
2095 return(komodo_ac_block_subsidy(nHeight));
2098 // Mining slow start
2099 // The subsidy is ramped up linearly, skipping the middle payout of
2100 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
2101 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
2102 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2103 nSubsidy *= nHeight;
2105 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
2106 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
2107 nSubsidy *= (nHeight+1);
2111 assert(nHeight > consensusParams.SubsidySlowStartShift());
2112 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
2113 // Force block reward to zero when right shift is undefined.
2114 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
2115 //if (halvings >= 64)
2118 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
2119 //nSubsidy >>= halvings;
2123 bool IsInitialBlockDownload()
2125 const CChainParams& chainParams = Params();
2127 // Once this function has returned false, it must remain false.
2128 static std::atomic<bool> latchToFalse{false};
2129 // Optimization: pre-test latch before taking the lock.
2130 if (latchToFalse.load(std::memory_order_relaxed))
2134 if (latchToFalse.load(std::memory_order_relaxed))
2137 if (fImporting || fReindex)
2139 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2143 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2145 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload - %d blocks\n", Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2150 CBlockIndex *ptr = chainActive.Tip();
2154 if (ptr->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork))
2157 state = ((chainActive.Height() < ptr->nHeight - 24*60) ||
2158 ptr->GetBlockTime() < (GetTime() - nMaxTipAge));
2160 //fprintf(stderr,"state.%d ht.%d vs %d, t.%u %u\n",state,(int32_t)chainActive.Height(),(uint32_t)ptr->nHeight,(int32_t)ptr->GetBlockTime(),(uint32_t)(GetTime() - chainParams.MaxTipAge()));
2163 LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
2164 latchToFalse.store(true, std::memory_order_relaxed);
2169 // determine if we are in sync with the best chain
2172 const CChainParams& chainParams = Params();
2175 if (fImporting || fReindex)
2177 //fprintf(stderr,"IsInSync: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
2180 if (fCheckpointsEnabled)
2182 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
2184 //fprintf(stderr,"IsInSync: checkpoint -> initialdownload chainActive.Height().%d GetTotalBlocksEstimate(chainParams.Checkpoints().%d\n", chainActive.Height(), Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()));
2189 CBlockIndex *pbi = chainActive.Tip();
2190 int longestchain = komodo_longestchain();
2192 (pindexBestHeader == 0) ||
2193 ((pindexBestHeader->nHeight - 1) > pbi->nHeight) ||
2194 (longestchain != 0 && longestchain > pbi->nHeight) )
2200 static bool fLargeWorkForkFound = false;
2201 static bool fLargeWorkInvalidChainFound = false;
2202 static CBlockIndex *pindexBestForkTip = NULL;
2203 static CBlockIndex *pindexBestForkBase = NULL;
2205 void CheckForkWarningConditions()
2207 AssertLockHeld(cs_main);
2208 // Before we get past initial download, we cannot reliably alert about forks
2209 // (we assume we don't get stuck on a fork before finishing our initial sync)
2210 if (IsInitialBlockDownload())
2213 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
2214 // of our head, drop it
2215 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 288)
2216 pindexBestForkTip = NULL;
2218 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.LastTip()->nChainWork + (GetBlockProof(*chainActive.LastTip()) * 6)))
2220 if (!fLargeWorkForkFound && pindexBestForkBase)
2222 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
2223 pindexBestForkBase->phashBlock->ToString() + std::string("'");
2224 CAlert::Notify(warning, true);
2226 if (pindexBestForkTip && pindexBestForkBase)
2228 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__,
2229 pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
2230 pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
2231 fLargeWorkForkFound = true;
2235 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
2236 LogPrintf("%s: %s\n", warning.c_str(), __func__);
2237 CAlert::Notify(warning, true);
2238 fLargeWorkInvalidChainFound = true;
2243 fLargeWorkForkFound = false;
2244 fLargeWorkInvalidChainFound = false;
2248 void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
2250 AssertLockHeld(cs_main);
2251 // If we are on a fork that is sufficiently large, set a warning flag
2252 CBlockIndex* pfork = pindexNewForkTip;
2253 CBlockIndex* plonger = chainActive.LastTip();
2254 while (pfork && pfork != plonger)
2256 while (plonger && plonger->nHeight > pfork->nHeight)
2257 plonger = plonger->pprev;
2258 if (pfork == plonger)
2260 pfork = pfork->pprev;
2263 // We define a condition where we should warn the user about as a fork of at least 7 blocks
2264 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
2265 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
2266 // hash rate operating on the fork.
2267 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
2268 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
2269 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
2270 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
2271 pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
2272 chainActive.Height() - pindexNewForkTip->nHeight < 72)
2274 pindexBestForkTip = pindexNewForkTip;
2275 pindexBestForkBase = pfork;
2278 CheckForkWarningConditions();
2281 // Requires cs_main.
2282 void Misbehaving(NodeId pnode, int howmuch)
2287 CNodeState *state = State(pnode);
2291 state->nMisbehavior += howmuch;
2292 int banscore = GetArg("-banscore", 101);
2293 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
2295 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2296 state->fShouldBan = true;
2298 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
2301 void static InvalidChainFound(CBlockIndex* pindexNew)
2303 if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
2304 pindexBestInvalid = pindexNew;
2306 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
2307 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
2308 log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
2309 pindexNew->GetBlockTime()));
2310 CBlockIndex *tip = chainActive.LastTip();
2312 LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
2313 tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
2314 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
2315 CheckForkWarningConditions();
2318 void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2320 if (state.IsInvalid(nDoS)) {
2321 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2322 if (it != mapBlockSource.end() && State(it->second)) {
2323 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
2324 State(it->second)->rejects.push_back(reject);
2326 Misbehaving(it->second, nDoS);
2329 if (!state.CorruptionPossible()) {
2330 pindex->nStatus |= BLOCK_FAILED_VALID;
2331 setDirtyBlockIndex.insert(pindex);
2332 setBlockIndexCandidates.erase(pindex);
2333 InvalidChainFound(pindex);
2337 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
2339 if (!tx.IsMint()) // mark inputs spent
2341 txundo.vprevout.reserve(tx.vin.size());
2342 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
2343 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2344 unsigned nPos = txin.prevout.n;
2346 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2348 // mark an outpoint spent, and construct undo information
2349 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2351 if (coins->vout.size() == 0) {
2352 CTxInUndo& undo = txundo.vprevout.back();
2353 undo.nHeight = coins->nHeight;
2354 undo.fCoinBase = coins->fCoinBase;
2355 undo.nVersion = coins->nVersion;
2361 inputs.SetNullifiers(tx, true);
2363 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
2366 if (tx.IsCoinImport()) {
2367 // add a tombstone for the burnTx
2368 AddImportTombstone(tx, inputs, nHeight);
2372 void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
2375 UpdateCoins(tx, inputs, txundo, nHeight);
2378 bool CScriptCheck::operator()() {
2379 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
2380 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2381 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
2382 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
2387 int GetSpendHeight(const CCoinsViewCache& inputs)
2390 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2391 return pindexPrev->nHeight + 1;
2394 namespace Consensus {
2395 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2397 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2398 // for an attacker to attempt to split the network.
2399 if (!inputs.HaveInputs(tx))
2400 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
2402 // are the JoinSplit's requirements met?
2403 if (!inputs.HaveJoinSplitRequirements(tx))
2404 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
2406 CAmount nValueIn = 0;
2408 for (unsigned int i = 0; i < tx.vin.size(); i++)
2410 const COutPoint &prevout = tx.vin[i].prevout;
2411 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2414 if (coins->IsCoinBase()) {
2415 // Ensure that coinbases are matured
2416 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2417 return state.Invalid(
2418 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2419 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2422 // ensure that output of coinbases are not still time locked
2423 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2424 if (nSpendHeight < unlockTime && coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE) {
2425 return state.Invalid(
2426 error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2427 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2430 // Ensure that coinbases cannot be spent to transparent outputs
2431 // Disabled on regtest
2432 if (fCoinbaseEnforcedProtectionEnabled &&
2433 consensusParams.fCoinbaseMustBeProtected &&
2435 (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
2436 return state.Invalid(
2437 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2438 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
2442 // Check for negative or overflow input values
2443 nValueIn += coins->vout[prevout.n].nValue;
2444 #ifdef KOMODO_ENABLE_INTEREST
2445 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight >= 60000 )
2447 if ( coins->vout[prevout.n].nValue >= 10*COIN )
2449 int64_t interest; int32_t txheight; uint32_t locktime;
2450 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
2452 //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);
2453 nValueIn += interest;
2458 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
2459 return state.DoS(100, error("CheckInputs(): txin values out of range"),
2460 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2464 nValueIn += tx.GetShieldedValueIn();
2465 if (!MoneyRange(nValueIn))
2466 return state.DoS(100, error("CheckInputs(): shielded input to transparent value pool out of range"),
2467 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
2469 if (nValueIn < tx.GetValueOut())
2471 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2472 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
2473 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
2475 // Tally transaction fees
2476 CAmount nTxFee = nValueIn - tx.GetValueOut();
2478 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
2479 REJECT_INVALID, "bad-txns-fee-negative");
2481 if (!MoneyRange(nFees))
2482 return state.DoS(100, error("CheckInputs(): nFees out of range"),
2483 REJECT_INVALID, "bad-txns-fee-outofrange");
2486 }// namespace Consensus
2488 bool ContextualCheckInputs(
2489 const CTransaction& tx,
2490 CValidationState &state,
2491 const CCoinsViewCache &inputs,
2495 PrecomputedTransactionData& txdata,
2496 const Consensus::Params& consensusParams,
2497 uint32_t consensusBranchId,
2498 std::vector<CScriptCheck> *pvChecks)
2502 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2507 pvChecks->reserve(tx.vin.size());
2509 // The first loop above does all the inexpensive checks.
2510 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2511 // Helps prevent CPU exhaustion attacks.
2513 // Skip ECDSA signature verification when connecting blocks
2514 // before the last block chain checkpoint. This is safe because block merkle hashes are
2515 // still computed and checked, and any change will be caught at the next checkpoint.
2516 if (fScriptChecks) {
2517 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2518 const COutPoint &prevout = tx.vin[i].prevout;
2519 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2523 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
2525 pvChecks->push_back(CScriptCheck());
2526 check.swap(pvChecks->back());
2527 } else if (!check()) {
2528 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2529 // Check whether the failure was caused by a
2530 // non-mandatory script verification check, such as
2531 // non-standard DER encodings or non-null dummy
2532 // arguments; if so, don't trigger DoS protection to
2533 // avoid splitting the network between upgraded and
2534 // non-upgraded nodes.
2535 CScriptCheck check2(*coins, tx, i,
2536 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
2538 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
2540 // Failures of other flags indicate a transaction that is
2541 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2542 // such nodes as they are not following the protocol. That
2543 // said during an upgrade careful thought should be taken
2544 // as to the correct behavior - we may want to continue
2545 // peering with non-upgraded nodes even after a soft-fork
2546 // super-majority vote has passed.
2547 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
2553 if (tx.IsCoinImport())
2555 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2556 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2563 /*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)
2565 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2566 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2570 if (!tx.IsCoinBase())
2572 // While checking, GetBestBlock() refers to the parent block.
2573 // This is also true for mempool checks.
2574 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2575 int nSpendHeight = pindexPrev->nHeight + 1;
2576 for (unsigned int i = 0; i < tx.vin.size(); i++)
2578 const COutPoint &prevout = tx.vin[i].prevout;
2579 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2580 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2584 // If prev is coinbase, check that it's matured
2585 if (coins->IsCoinBase()) {
2586 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2587 COINBASE_MATURITY = _COINBASE_MATURITY;
2588 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2589 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2591 return state.Invalid(
2592 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2603 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2605 // Open history file to append
2606 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2607 if (fileout.IsNull())
2608 return error("%s: OpenUndoFile failed", __func__);
2610 // Write index header
2611 unsigned int nSize = GetSerializeSize(fileout, blockundo);
2612 fileout << FLATDATA(messageStart) << nSize;
2615 long fileOutPos = ftell(fileout.Get());
2617 return error("%s: ftell failed", __func__);
2618 pos.nPos = (unsigned int)fileOutPos;
2619 fileout << blockundo;
2621 // calculate & write checksum
2622 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2623 hasher << hashBlock;
2624 hasher << blockundo;
2625 fileout << hasher.GetHash();
2630 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2632 // Open history file to read
2633 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2634 if (filein.IsNull())
2635 return error("%s: OpenBlockFile failed", __func__);
2638 uint256 hashChecksum;
2640 filein >> blockundo;
2641 filein >> hashChecksum;
2643 catch (const std::exception& e) {
2644 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2647 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2648 hasher << hashBlock;
2649 hasher << blockundo;
2650 if (hashChecksum != hasher.GetHash())
2651 return error("%s: Checksum mismatch", __func__);
2656 /** Abort with a message */
2657 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2659 strMiscWarning = strMessage;
2660 LogPrintf("*** %s\n", strMessage);
2661 uiInterface.ThreadSafeMessageBox(
2662 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2663 "", CClientUIInterface::MSG_ERROR);
2668 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2670 AbortNode(strMessage, userMessage);
2671 return state.Error(strMessage);
2677 * Apply the undo operation of a CTxInUndo to the given chain state.
2678 * @param undo The undo object.
2679 * @param view The coins view to which to apply the changes.
2680 * @param out The out point that corresponds to the tx input.
2681 * @return True on success.
2683 static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2687 CCoinsModifier coins = view.ModifyCoins(out.hash);
2688 if (undo.nHeight != 0) {
2689 // undo data contains height: this is the last output of the prevout tx being spent
2690 if (!coins->IsPruned())
2691 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2693 coins->fCoinBase = undo.fCoinBase;
2694 coins->nHeight = undo.nHeight;
2695 coins->nVersion = undo.nVersion;
2697 if (coins->IsPruned())
2698 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2700 if (coins->IsAvailable(out.n))
2701 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2702 if (coins->vout.size() < out.n+1)
2703 coins->vout.resize(out.n+1);
2704 coins->vout[out.n] = undo.txout;
2710 void ConnectNotarisations(const CBlock &block, int height)
2712 // Record Notarisations
2713 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2714 if (notarisations.size() > 0) {
2715 CDBBatch batch = CDBBatch(*pnotarisations);
2716 batch.Write(block.GetHash(), notarisations);
2717 WriteBackNotarisations(notarisations, batch);
2718 pnotarisations->WriteBatch(batch, true);
2719 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2720 notarisations.size(), block.GetHash().GetHex().data());
2725 void DisconnectNotarisations(const CBlock &block)
2727 // Delete from notarisations cache
2728 NotarisationsInBlock nibs;
2729 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2730 CDBBatch batch = CDBBatch(*pnotarisations);
2731 batch.Erase(block.GetHash());
2732 EraseBackNotarisations(nibs, batch);
2733 pnotarisations->WriteBatch(batch, true);
2734 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2735 nibs.size(), block.GetHash().GetHex().data());
2740 bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
2742 assert(pindex->GetBlockHash() == view.GetBestBlock());
2748 komodo_disconnect(pindex,block);
2749 CBlockUndo blockUndo;
2750 CDiskBlockPos pos = pindex->GetUndoPos();
2752 return error("DisconnectBlock(): no undo data available");
2753 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
2754 return error("DisconnectBlock(): failure reading undo data");
2756 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2757 return error("DisconnectBlock(): block and undo data inconsistent");
2758 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2759 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2760 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2762 // undo transactions in reverse order
2763 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2764 const CTransaction &tx = block.vtx[i];
2765 uint256 hash = tx.GetHash();
2766 if (fAddressIndex) {
2768 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2769 const CTxOut &out = tx.vout[k];
2771 if (out.scriptPubKey.IsPayToScriptHash()) {
2772 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2774 // undo receiving activity
2775 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2777 // undo unspent index
2778 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2781 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
2782 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2784 // undo receiving activity
2785 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2787 // undo unspent index
2788 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2791 else if (out.scriptPubKey.IsPayToPublicKey()) {
2792 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2794 // undo receiving activity
2795 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2797 // undo unspent index
2798 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2801 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2802 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2804 // undo receiving activity
2805 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2807 // undo unspent index
2808 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2819 // Check that all outputs are available and match the outputs in the block itself
2822 CCoinsModifier outs = view.ModifyCoins(hash);
2823 outs->ClearUnspendable();
2825 CCoins outsBlock(tx, pindex->nHeight);
2826 // The CCoins serialization does not serialize negative numbers.
2827 // No network rules currently depend on the version here, so an inconsistency is harmless
2828 // but it must be corrected before txout nversion ever influences a network rule.
2829 if (outsBlock.nVersion < 0)
2830 outs->nVersion = outsBlock.nVersion;
2831 if (*outs != outsBlock)
2832 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2838 // unspend nullifiers
2839 view.SetNullifiers(tx, false);
2843 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2844 if (txundo.vprevout.size() != tx.vin.size())
2845 return error("DisconnectBlock(): transaction and undo data inconsistent");
2846 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2847 const COutPoint &out = tx.vin[j].prevout;
2848 const CTxInUndo &undo = txundo.vprevout[j];
2849 if (!ApplyTxInUndo(undo, view, out))
2852 const CTxIn input = tx.vin[j];
2855 // undo and delete the spent index
2856 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2859 if (fAddressIndex) {
2860 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2861 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2862 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2864 // undo spending activity
2865 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2867 // restore unspent index
2868 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2872 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
2873 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2875 // undo spending activity
2876 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2878 // restore unspent index
2879 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2882 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2883 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2885 // undo spending activity
2886 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2888 // restore unspent index
2889 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2892 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2893 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2895 // undo spending activity
2896 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2898 // restore unspent index
2899 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2908 else if (tx.IsCoinImport())
2910 RemoveImportTombstone(tx, view);
2914 // set the old best Sprout anchor back
2915 view.PopAnchor(blockUndo.old_sprout_tree_root, SPROUT);
2917 // set the old best Sapling anchor back
2918 // We can get this from the `hashFinalSaplingRoot` of the last block
2919 // However, this is only reliable if the last block was on or after
2920 // the Sapling activation height. Otherwise, the last anchor was the
2922 if (NetworkUpgradeActive(pindex->pprev->nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2923 view.PopAnchor(pindex->pprev->hashFinalSaplingRoot, SAPLING);
2925 view.PopAnchor(SaplingMerkleTree::empty_root(), SAPLING);
2928 // move best block pointer to prevout block
2929 view.SetBestBlock(pindex->pprev->GetBlockHash());
2936 if (fAddressIndex) {
2937 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2938 return AbortNode(state, "Failed to delete address index");
2940 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2941 return AbortNode(state, "Failed to write address unspent index");
2948 void static FlushBlockFile(bool fFinalize = false)
2950 LOCK(cs_LastBlockFile);
2952 CDiskBlockPos posOld(nLastBlockFile, 0);
2954 FILE *fileOld = OpenBlockFile(posOld);
2957 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2958 FileCommit(fileOld);
2962 fileOld = OpenUndoFile(posOld);
2965 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2966 FileCommit(fileOld);
2971 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
2973 static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
2975 void ThreadScriptCheck() {
2976 RenameThread("zcash-scriptch");
2977 scriptcheckqueue.Thread();
2981 // Called periodically asynchronously; alerts if it smells like
2982 // we're being fed a bad chain (blocks being generated much
2983 // too slowly or too quickly).
2985 void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2986 int64_t nPowTargetSpacing)
2988 if (bestHeader == NULL || initialDownloadCheck()) return;
2990 static int64_t lastAlertTime = 0;
2991 int64_t now = GetAdjustedTime();
2992 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
2994 const int SPAN_HOURS=4;
2995 const int SPAN_SECONDS=SPAN_HOURS*60*60;
2996 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
2998 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
3000 std::string strWarning;
3001 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
3004 const CBlockIndex* i = bestHeader;
3006 while (i->GetBlockTime() >= startTime) {
3009 if (i == NULL) return; // Ran out of chain, we must not be fully synced
3012 // How likely is it to find that many by chance?
3013 double p = boost::math::pdf(poisson, nBlocks);
3015 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
3016 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
3018 // Aim for one false-positive about every fifty years of normal running:
3019 const int FIFTY_YEARS = 50*365*24*60*60;
3020 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
3022 if (bestHeader->nHeight > BLOCKS_EXPECTED)
3024 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
3026 // Many fewer blocks than expected: alert!
3027 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
3028 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3030 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
3032 // Many more blocks than expected: alert!
3033 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
3034 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
3037 if (!strWarning.empty())
3039 strMiscWarning = strWarning;
3040 CAlert::Notify(strWarning, true);
3041 lastAlertTime = now;
3046 static int64_t nTimeVerify = 0;
3047 static int64_t nTimeConnect = 0;
3048 static int64_t nTimeIndex = 0;
3049 static int64_t nTimeCallbacks = 0;
3050 static int64_t nTimeTotal = 0;
3052 bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
3054 const CChainParams& chainparams = Params();
3055 if ( KOMODO_STOPAT != 0 && pindex->nHeight > KOMODO_STOPAT )
3057 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->nHeight);
3058 AssertLockHeld(cs_main);
3059 bool fExpensiveChecks = true;
3060 if (fCheckpointsEnabled) {
3061 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
3062 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
3063 // This block is an ancestor of a checkpoint: disable script checks
3064 fExpensiveChecks = false;
3067 auto verifier = libzcash::ProofVerifier::Strict();
3068 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
3069 int32_t futureblock;
3070 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
3071 if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
3073 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
3077 // verify that the view's current state corresponds to the previous block
3078 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
3079 if ( hashPrevBlock != view.GetBestBlock() )
3081 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
3082 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
3083 REJECT_INVALID, "hashPrevBlock-not-bestblock");
3085 assert(hashPrevBlock == view.GetBestBlock());
3087 // Special case for the genesis block, skipping connection of its transactions
3088 // (its coinbase is unspendable)
3089 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
3091 view.SetBestBlock(pindex->GetBlockHash());
3092 // Before the genesis block, there was an empty tree
3093 SproutMerkleTree tree;
3094 pindex->hashSproutAnchor = tree.root();
3095 // The genesis block contained no JoinSplits
3096 pindex->hashFinalSproutRoot = pindex->hashSproutAnchor;
3101 bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
3102 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->nHeight > KOMODO_TESTNET_EXPIRATION ) // "testnet"
3104 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
3105 // unless those are already completely spent.
3106 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
3107 const CCoins* coins = view.AccessCoins(tx.GetHash());
3108 if (coins && !coins->IsPruned())
3109 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
3110 REJECT_INVALID, "bad-txns-BIP30");
3113 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
3115 // DERSIG (BIP66) is also always enforced, but does not have a flag.
3117 CBlockUndo blockundo;
3119 if ( ASSETCHAINS_CC != 0 )
3121 if ( scriptcheckqueue.IsIdle() == 0 )
3123 fprintf(stderr,"scriptcheckqueue isnt idle\n");
3127 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
3129 int64_t nTimeStart = GetTimeMicros();
3132 int64_t interest,sum = 0;
3133 unsigned int nSigOps = 0;
3134 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
3135 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
3136 vPos.reserve(block.vtx.size());
3137 blockundo.vtxundo.reserve(block.vtx.size() - 1);
3138 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
3139 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
3140 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
3141 // Construct the incremental merkle tree at the current
3143 auto old_sprout_tree_root = view.GetBestAnchor(SPROUT);
3144 // saving the top anchor in the block index as we go.
3146 pindex->hashSproutAnchor = old_sprout_tree_root;
3149 SproutMerkleTree sprout_tree;
3151 // This should never fail: we should always be able to get the root
3152 // that is on the tip of our chain
3153 assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree));
3156 // Consistency check: the root of the tree we're given should
3157 // match what we asked for.
3158 assert(sprout_tree.root() == old_sprout_tree_root);
3161 SaplingMerkleTree sapling_tree;
3162 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
3164 // Grab the consensus branch ID for the block's height
3165 auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus());
3167 std::vector<PrecomputedTransactionData> txdata;
3168 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
3169 for (unsigned int i = 0; i < block.vtx.size(); i++)
3171 const CTransaction &tx = block.vtx[i];
3172 const uint256 txhash = tx.GetHash();
3173 nInputs += tx.vin.size();
3174 nSigOps += GetLegacySigOpCount(tx);
3175 if (nSigOps > MAX_BLOCK_SIGOPS)
3176 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3177 REJECT_INVALID, "bad-blk-sigops");
3178 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->nHeight,tx.nLockTime);
3181 if (!view.HaveInputs(tx))
3183 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
3184 REJECT_INVALID, "bad-txns-inputs-missingorspent");
3186 // are the JoinSplit's requirements met?
3187 if (!view.HaveJoinSplitRequirements(tx))
3188 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
3189 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
3190 if (fAddressIndex || fSpentIndex)
3192 for (size_t j = 0; j < tx.vin.size(); j++) {
3194 const CTxIn input = tx.vin[j];
3195 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
3199 if (prevout.scriptPubKey.IsPayToScriptHash()) {
3200 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
3203 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
3204 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
3207 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
3208 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
3211 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
3212 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
3216 hashBytes.SetNull();
3220 if (fAddressIndex && addressType > 0) {
3221 // record spending activity
3222 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
3224 // remove address from unspent index
3225 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
3229 // add the spent index to determine the txid and input that spent an output
3230 // and to find the amount and address from an input
3231 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes)));
3236 // Add in sigops done by pay-to-script-hash inputs;
3237 // this is to prevent a "rogue miner" from creating
3238 // an incredibly-expensive-to-validate block.
3239 nSigOps += GetP2SHSigOpCount(tx, view);
3240 if (nSigOps > MAX_BLOCK_SIGOPS)
3241 return state.DoS(100, error("ConnectBlock(): too many sigops"),
3242 REJECT_INVALID, "bad-blk-sigops");
3245 txdata.emplace_back(tx);
3247 if (!tx.IsCoinBase())
3249 nFees += view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
3252 std::vector<CScriptCheck> vChecks;
3253 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
3255 control.Add(vChecks);
3258 if (fAddressIndex) {
3259 for (unsigned int k = 0; k < tx.vout.size(); k++) {
3260 const CTxOut &out = tx.vout[k];
3261 //fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
3262 if (out.scriptPubKey.IsPayToScriptHash()) {
3263 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
3265 // record receiving activity
3266 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3268 // record unspent output
3269 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3272 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
3273 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
3275 // record receiving activity
3276 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3278 // record unspent output
3279 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3282 else if (out.scriptPubKey.IsPayToPublicKey()) {
3283 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
3285 // record receiving activity
3286 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3288 // record unspent output
3289 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3292 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
3293 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
3295 // record receiving activity
3296 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3298 // record unspent output
3299 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3309 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3310 // komodo_earned_interest(pindex->nHeight,sum);
3313 blockundo.vtxundo.push_back(CTxUndo());
3315 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
3317 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
3318 BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) {
3319 // Insert the note commitments into our temporary tree.
3321 sprout_tree.append(note_commitment);
3325 BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) {
3326 sapling_tree.append(outputDescription.cm);
3329 vPos.push_back(std::make_pair(tx.GetHash(), pos));
3330 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
3333 view.PushAnchor(sprout_tree);
3334 view.PushAnchor(sapling_tree);
3336 pindex->hashFinalSproutRoot = sprout_tree.root();
3338 blockundo.old_sprout_tree_root = old_sprout_tree_root;
3340 // If Sapling is active, block.hashFinalSaplingRoot must be the
3341 // same as the root of the Sapling tree
3342 if (NetworkUpgradeActive(pindex->nHeight, chainparams.GetConsensus(), Consensus::UPGRADE_SAPLING)) {
3343 if (block.hashFinalSaplingRoot != sapling_tree.root()) {
3344 return state.DoS(100,
3345 error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect"),
3346 REJECT_INVALID, "bad-sapling-root-in-block");
3349 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3350 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);
3352 CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
3353 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
3355 uint64_t checktoshis;
3356 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
3358 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
3359 blockReward += checktoshis;
3360 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
3363 if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->nHeight == 1 && block.vtx[0].GetValueOut() != blockReward)
3365 return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
3366 REJECT_INVALID, "bad-cb-amount");
3368 if ( block.vtx[0].GetValueOut() > blockReward+1 )
3370 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
3372 return state.DoS(100,
3373 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3374 block.vtx[0].GetValueOut(), blockReward),
3375 REJECT_INVALID, "bad-cb-amount");
3376 } else if ( IS_KOMODO_NOTARY != 0 )
3377 fprintf(stderr,"allow nHeight.%d coinbase %.8f vs %.8f interest %.8f\n",(int32_t)pindex->nHeight,dstr(block.vtx[0].GetValueOut()),dstr(blockReward),dstr(sum));
3379 if (!control.Wait())
3380 return state.DoS(100, false);
3381 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3382 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);
3387 // Write undo information to disk
3388 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
3390 if (pindex->GetUndoPos().IsNull()) {
3392 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
3393 return error("ConnectBlock(): FindUndoPos failed");
3394 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
3395 return AbortNode(state, "Failed to write undo data");
3397 // update nUndoPos in block index
3398 pindex->nUndoPos = pos.nPos;
3399 pindex->nStatus |= BLOCK_HAVE_UNDO;
3402 // Now that all consensus rules have been validated, set nCachedBranchId.
3403 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3404 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
3405 "nCachedBranchId must be set after all consensus rules have been validated.");
3406 if (IsActivationHeightForAnyUpgrade(pindex->nHeight, Params().GetConsensus())) {
3407 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
3408 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus());
3409 } else if (pindex->pprev) {
3410 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
3413 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
3414 setDirtyBlockIndex.insert(pindex);
3417 ConnectNotarisations(block, pindex->nHeight);
3420 if (!pblocktree->WriteTxIndex(vPos))
3421 return AbortNode(state, "Failed to write transaction index");
3422 if (fAddressIndex) {
3423 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3424 return AbortNode(state, "Failed to write address index");
3427 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3428 return AbortNode(state, "Failed to write address unspent index");
3433 if (!pblocktree->UpdateSpentIndex(spentIndex))
3434 return AbortNode(state, "Failed to write transaction index");
3436 if (fTimestampIndex) {
3437 unsigned int logicalTS = pindex->nTime;
3438 unsigned int prevLogicalTS = 0;
3440 // retrieve logical timestamp of the previous block
3442 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3443 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3445 if (logicalTS <= prevLogicalTS) {
3446 logicalTS = prevLogicalTS + 1;
3447 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3450 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3451 return AbortNode(state, "Failed to write timestamp index");
3453 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3454 return AbortNode(state, "Failed to write blockhash index");
3457 // add this block to the view's block chain
3458 view.SetBestBlock(pindex->GetBlockHash());
3460 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3461 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
3463 // Watch for changes to the previous coinbase transaction.
3464 static uint256 hashPrevBestCoinBase;
3465 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
3466 hashPrevBestCoinBase = block.vtx[0].GetHash();
3468 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3469 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
3471 //FlushStateToDisk();
3472 komodo_connectblock(pindex,*(CBlock *)&block);
3476 enum FlushStateMode {
3478 FLUSH_STATE_IF_NEEDED,
3479 FLUSH_STATE_PERIODIC,
3484 * Update the on-disk chain state.
3485 * The caches and indexes are flushed depending on the mode we're called with
3486 * if they're too large, if it's been a while since the last write,
3487 * or always and in all cases if we're in prune mode and are deleting files.
3489 bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
3490 LOCK2(cs_main, cs_LastBlockFile);
3491 static int64_t nLastWrite = 0;
3492 static int64_t nLastFlush = 0;
3493 static int64_t nLastSetChain = 0;
3494 std::set<int> setFilesToPrune;
3495 bool fFlushForPrune = false;
3497 if (fPruneMode && fCheckForPruning && !fReindex) {
3498 FindFilesToPrune(setFilesToPrune);
3499 fCheckForPruning = false;
3500 if (!setFilesToPrune.empty()) {
3501 fFlushForPrune = true;
3503 pblocktree->WriteFlag("prunedblockfiles", true);
3508 int64_t nNow = GetTimeMicros();
3509 // Avoid writing/flushing immediately after startup.
3510 if (nLastWrite == 0) {
3513 if (nLastFlush == 0) {
3516 if (nLastSetChain == 0) {
3517 nLastSetChain = nNow;
3519 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3520 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3521 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3522 // The cache is over the limit, we have to write now.
3523 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3524 // 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.
3525 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3526 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3527 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3528 // Combine all conditions that result in a full cache flush.
3529 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3530 // Write blocks and block index to disk.
3531 if (fDoFullFlush || fPeriodicWrite) {
3532 // Depend on nMinDiskSpace to ensure we can write block index
3533 if (!CheckDiskSpace(0))
3534 return state.Error("out of disk space");
3535 // First make sure all block and undo data is flushed to disk.
3537 // Then update all block file information (which may refer to block and undo files).
3539 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3540 vFiles.reserve(setDirtyFileInfo.size());
3541 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3542 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3543 setDirtyFileInfo.erase(it++);
3545 std::vector<const CBlockIndex*> vBlocks;
3546 vBlocks.reserve(setDirtyBlockIndex.size());
3547 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3548 vBlocks.push_back(*it);
3549 setDirtyBlockIndex.erase(it++);
3551 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3552 return AbortNode(state, "Files to write to block index database");
3555 // Finally remove any pruned files
3557 UnlinkPrunedFiles(setFilesToPrune);
3560 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3562 // Typical CCoins structures on disk are around 128 bytes in size.
3563 // Pushing a new one to the database can cause it to be written
3564 // twice (once in the log, and once in the tables). This is already
3565 // an overestimation, as most will delete an existing entry or
3566 // overwrite one. Still, use a conservative safety factor of 2.
3567 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3568 return state.Error("out of disk space");
3569 // Flush the chainstate (which may refer to block index entries).
3570 if (!pcoinsTip->Flush())
3571 return AbortNode(state, "Failed to write to coin database");
3574 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3575 // Update best block in wallet (so we can detect restored wallets).
3576 GetMainSignals().SetBestChain(chainActive.GetLocator());
3577 nLastSetChain = nNow;
3579 } catch (const std::runtime_error& e) {
3580 return AbortNode(state, std::string("System error while flushing: ") + e.what());
3585 void FlushStateToDisk() {
3586 CValidationState state;
3587 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3590 void PruneAndFlush() {
3591 CValidationState state;
3592 fCheckForPruning = true;
3593 FlushStateToDisk(state, FLUSH_STATE_NONE);
3596 /** Update chainActive and related internal data structures. */
3597 void static UpdateTip(CBlockIndex *pindexNew) {
3598 const CChainParams& chainParams = Params();
3599 chainActive.SetTip(pindexNew);
3602 nTimeBestReceived = GetTime();
3603 mempool.AddTransactionsUpdated(1);
3606 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
3607 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
3609 int32_t longestchain = komodo_longestchain();
3610 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
3613 LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
3614 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3615 log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.LastTip()->nChainTx,
3616 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
3617 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
3619 cvBlockChange.notify_all();
3621 // Check the version of the last 100 blocks to see if we need to upgrade:
3622 static bool fWarned = false;
3623 if (!IsInitialBlockDownload() && !fWarned)
3626 const CBlockIndex* pindex = chainActive.Tip();
3627 for (int i = 0; i < 100 && pindex != NULL; i++)
3629 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3631 pindex = pindex->pprev;
3634 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
3635 if (nUpgraded > 100/2)
3637 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
3638 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
3639 CAlert::Notify(strMiscWarning, true);
3646 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3647 * mempool.removeWithoutBranchId after this, with cs_main held.
3649 bool static DisconnectTip(CValidationState &state, bool fBare = false) {
3650 CBlockIndex *pindexDelete = chainActive.Tip();
3651 assert(pindexDelete);
3652 // Read block from disk.
3654 if (!ReadBlockFromDisk(block, pindexDelete,1))
3655 return AbortNode(state, "Failed to read block");
3656 // Apply the block atomically to the chain state.
3657 uint256 sproutAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3658 uint256 saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3659 int64_t nStart = GetTimeMicros();
3661 CCoinsViewCache view(pcoinsTip);
3662 if (!DisconnectBlock(block, state, pindexDelete, view))
3663 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
3664 assert(view.Flush());
3665 DisconnectNotarisations(block);
3667 pindexDelete->segid = -2;
3668 pindexDelete->newcoins = 0;
3669 pindexDelete->zfunds = 0;
3671 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
3672 uint256 sproutAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SPROUT);
3673 uint256 saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor(SAPLING);
3674 // Write the chain state to disk, if necessary.
3675 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3679 // resurrect mempool transactions from the disconnected block.
3680 for (int i = 0; i < block.vtx.size(); i++)
3682 // ignore validation errors in resurrected transactions
3683 CTransaction &tx = block.vtx[i];
3684 list<CTransaction> removed;
3685 CValidationState stateDummy;
3686 // don't keep staking or invalid transactions
3687 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (komodo_isPoS((CBlock *)&block) != 0))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
3689 mempool.remove(tx, removed, true);
3692 if (sproutAnchorBeforeDisconnect != sproutAnchorAfterDisconnect) {
3693 // The anchor may not change between block disconnects,
3694 // in which case we don't want to evict from the mempool yet!
3695 mempool.removeWithAnchor(sproutAnchorBeforeDisconnect, SPROUT);
3697 if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) {
3698 // The anchor may not change between block disconnects,
3699 // in which case we don't want to evict from the mempool yet!
3700 mempool.removeWithAnchor(saplingAnchorBeforeDisconnect, SAPLING);
3704 // Update chainActive and related variables.
3705 UpdateTip(pindexDelete->pprev);
3707 // Get the current commitment tree
3708 SproutMerkleTree newSproutTree;
3709 SaplingMerkleTree newSaplingTree;
3710 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree));
3711 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree));
3712 // Let wallets know transactions went from 1-confirmed to
3713 // 0-confirmed or conflicted:
3714 for (int i = 0; i < block.vtx.size(); i++)
3716 CTransaction &tx = block.vtx[i];
3717 if ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
3719 EraseFromWallets(tx.GetHash());
3723 SyncWithWallets(tx, NULL);
3726 // Update cached incremental witnesses
3727 GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false);
3731 static int64_t nTimeReadFromDisk = 0;
3732 static int64_t nTimeConnectTotal = 0;
3733 static int64_t nTimeFlush = 0;
3734 static int64_t nTimeChainState = 0;
3735 static int64_t nTimePostConnect = 0;
3738 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3739 * corresponding to pindexNew, to bypass loading it again from disk.
3740 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
3742 bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
3744 assert(pindexNew->pprev == chainActive.Tip());
3745 // Read block from disk.
3746 int64_t nTime1 = GetTimeMicros();
3749 if (!ReadBlockFromDisk(block, pindexNew,1))
3750 return AbortNode(state, "Failed to read block");
3753 KOMODO_CONNECTING = (int32_t)pindexNew->nHeight;
3754 // Get the current commitment tree
3755 SproutMerkleTree oldSproutTree;
3756 SaplingMerkleTree oldSaplingTree;
3757 assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree));
3758 assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree));
3759 // Apply the block atomically to the chain state.
3760 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3762 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3764 CCoinsViewCache view(pcoinsTip);
3765 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
3766 KOMODO_CONNECTING = -1;
3767 GetMainSignals().BlockChecked(*pblock, state);
3769 if (state.IsInvalid())
3770 InvalidBlockFound(pindexNew, state);
3771 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
3773 mapBlockSource.erase(pindexNew->GetBlockHash());
3774 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3775 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3776 assert(view.Flush());
3778 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3779 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3780 // Write the chain state to disk, if necessary.
3781 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
3783 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3784 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3785 // Remove conflicting transactions from the mempool.
3786 list<CTransaction> txConflicted;
3787 mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
3789 // Remove transactions that expire at new block height from mempool
3790 mempool.removeExpired(pindexNew->nHeight);
3792 // Update chainActive & related variables.
3793 UpdateTip(pindexNew);
3794 // Tell wallet about transactions that went from mempool
3796 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
3797 SyncWithWallets(tx, NULL);
3799 // ... and about transactions that got confirmed:
3800 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3801 SyncWithWallets(tx, pblock);
3803 // Update cached incremental witnesses
3804 GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true);
3806 EnforceNodeDeprecation(pindexNew->nHeight);
3808 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3809 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3810 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3811 if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->nHeight >= KOMODO_LONGESTCHAIN )
3813 else KOMODO_INSYNC = 0;
3814 //fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->nHeight,KOMODO_INSYNC);
3815 if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
3816 komodo_broadcast(pblock,8);
3821 * Return the tip of the chain with the most work in it, that isn't
3822 * known to be invalid (it's however far from certain to be valid).
3824 static CBlockIndex* FindMostWorkChain() {
3826 CBlockIndex *pindexNew = NULL;
3828 // Find the best candidate header.
3830 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3831 if (it == setBlockIndexCandidates.rend())
3836 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3837 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3838 CBlockIndex *pindexTest = pindexNew;
3839 bool fInvalidAncestor = false;
3840 while (pindexTest && !chainActive.Contains(pindexTest)) {
3841 assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
3843 // Pruned nodes may have entries in setBlockIndexCandidates for
3844 // which block files have been deleted. Remove those as candidates
3845 // for the most work chain if we come across them; we can't switch
3846 // to a chain unless we have all the non-active-chain parent blocks.
3847 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3848 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3849 if (fFailedChain || fMissingData) {
3850 // Candidate chain is not usable (either invalid or missing data)
3851 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
3852 pindexBestInvalid = pindexNew;
3853 CBlockIndex *pindexFailed = pindexNew;
3854 // Remove the entire chain from the set.
3855 while (pindexTest != pindexFailed) {
3857 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3858 } else if (fMissingData) {
3859 // If we're missing data, then add back to mapBlocksUnlinked,
3860 // so that if the block arrives in the future we can try adding
3861 // to setBlockIndexCandidates again.
3862 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3864 setBlockIndexCandidates.erase(pindexFailed);
3865 pindexFailed = pindexFailed->pprev;
3867 setBlockIndexCandidates.erase(pindexTest);
3868 fInvalidAncestor = true;
3871 pindexTest = pindexTest->pprev;
3873 if (!fInvalidAncestor)
3878 /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
3879 static void PruneBlockIndexCandidates() {
3880 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3881 // reorganization to a better block fails.
3882 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3883 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
3884 setBlockIndexCandidates.erase(it++);
3886 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3887 assert(!setBlockIndexCandidates.empty());
3891 * Try to make some progress towards making pindexMostWork the active block.
3892 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3894 static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
3895 AssertLockHeld(cs_main);
3896 bool fInvalidFound = false;
3897 const CBlockIndex *pindexOldTip = chainActive.Tip();
3898 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
3900 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3901 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3902 // then pindexFork will be null, and we would need to remove the entire chain including
3903 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3904 auto reorgLength = pindexOldTip ? pindexOldTip->nHeight - (pindexFork ? pindexFork->nHeight : -1) : 0;
3905 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3906 if (reorgLength > MAX_REORG_LENGTH) {
3907 auto msg = strprintf(_(
3908 "A block chain reorganization has been detected that would roll back %d blocks! "
3909 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3910 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3911 _("Reorganization details") + ":\n" +
3912 "- " + strprintf(_("Current tip: %s, height %d, work %s"),
3913 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" +
3914 "- " + strprintf(_("New tip: %s, height %d, work %s"),
3915 pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" +
3916 "- " + strprintf(_("Fork point: %s %s, height %d"),
3917 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" +
3918 _("Please help, human!");
3919 LogPrintf("*** %s\n", msg);
3920 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3925 // Disconnect active blocks which are no longer in the best chain.
3926 bool fBlocksDisconnected = false;
3927 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3928 if (!DisconnectTip(state))
3930 fBlocksDisconnected = true;
3932 if ( KOMODO_REWIND != 0 )
3934 CBlockIndex *tipindex;
3935 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->nHeight,KOMODO_REWIND);
3936 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->nHeight > KOMODO_REWIND )
3938 fBlocksDisconnected = true;
3939 fprintf(stderr,"%d ",(int32_t)tipindex->nHeight);
3940 InvalidateBlock(state,tipindex);
3941 if ( !DisconnectTip(state) )
3944 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
3946 fprintf(stderr,"resuming normal operations\n");
3950 // Build list of new blocks to connect.
3951 std::vector<CBlockIndex*> vpindexToConnect;
3952 bool fContinue = true;
3953 int nHeight = pindexFork ? pindexFork->nHeight : -1;
3954 while (fContinue && nHeight != pindexMostWork->nHeight) {
3955 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3956 // a few blocks along the way.
3957 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
3958 vpindexToConnect.clear();
3959 vpindexToConnect.reserve(nTargetHeight - nHeight);
3960 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3961 while (pindexIter && pindexIter->nHeight != nHeight) {
3962 vpindexToConnect.push_back(pindexIter);
3963 pindexIter = pindexIter->pprev;
3965 nHeight = nTargetHeight;
3967 // Connect new blocks.
3968 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
3969 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
3970 if (state.IsInvalid()) {
3971 // The block violates a consensus rule.
3972 if (!state.CorruptionPossible())
3973 InvalidChainFound(vpindexToConnect.back());
3974 state = CValidationState();
3975 fInvalidFound = true;
3979 // A system error occurred (disk space, database error, ...).
3983 PruneBlockIndexCandidates();
3984 if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
3985 // We're in a better position than we were. Return temporarily to release the lock.
3993 if (fBlocksDisconnected) {
3994 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
3996 mempool.removeWithoutBranchId(
3997 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
3998 mempool.check(pcoinsTip);
4000 // Callbacks/notifications for a new best chain.
4002 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
4004 CheckForkWarningConditions();
4010 * Make the best chain active, in multiple steps. The result is either failure
4011 * or an activated best chain. pblock is either NULL or a pointer to a block
4012 * that is already loaded (to avoid loading it again from disk).
4014 bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
4015 CBlockIndex *pindexNewTip = NULL;
4016 CBlockIndex *pindexMostWork = NULL;
4017 const CChainParams& chainParams = Params();
4019 boost::this_thread::interruption_point();
4021 bool fInitialDownload;
4024 pindexMostWork = FindMostWorkChain();
4026 // Whether we have anything to do at all.
4027 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
4030 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
4032 pindexNewTip = chainActive.Tip();
4033 fInitialDownload = IsInitialBlockDownload();
4035 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
4037 // Notifications/callbacks that can run without cs_main
4038 if (!fInitialDownload) {
4039 uint256 hashNewTip = pindexNewTip->GetBlockHash();
4040 // Relay inventory, but don't relay old inventory during initial block download.
4041 int nBlockEstimate = 0;
4042 if (fCheckpointsEnabled)
4043 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
4044 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
4045 // in a stalled download if the block file is pruned before the request.
4046 if (nLocalServices & NODE_NETWORK) {
4048 BOOST_FOREACH(CNode* pnode, vNodes)
4049 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
4050 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
4052 // Notify external listeners about the new tip.
4053 GetMainSignals().UpdatedBlockTip(pindexNewTip);
4054 uiInterface.NotifyBlockTip(hashNewTip);
4055 } //else fprintf(stderr,"initial download skips propagation\n");
4056 } while(pindexMostWork != chainActive.Tip());
4059 // Write changes periodically to disk, after relay.
4060 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
4067 bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
4068 AssertLockHeld(cs_main);
4070 // Mark the block itself as invalid.
4071 pindex->nStatus |= BLOCK_FAILED_VALID;
4072 setDirtyBlockIndex.insert(pindex);
4073 setBlockIndexCandidates.erase(pindex);
4075 while (chainActive.Contains(pindex)) {
4076 CBlockIndex *pindexWalk = chainActive.Tip();
4077 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
4078 setDirtyBlockIndex.insert(pindexWalk);
4079 setBlockIndexCandidates.erase(pindexWalk);
4080 // ActivateBestChain considers blocks already in chainActive
4081 // unconditionally valid already, so force disconnect away from it.
4082 if (!DisconnectTip(state)) {
4083 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4084 mempool.removeWithoutBranchId(
4085 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
4089 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
4091 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
4093 BlockMap::iterator it = mapBlockIndex.begin();
4094 while (it != mapBlockIndex.end() && it->second != 0 ) {
4095 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
4096 setBlockIndexCandidates.insert(it->second);
4101 InvalidChainFound(pindex);
4102 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
4103 mempool.removeWithoutBranchId(
4104 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
4108 bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
4109 AssertLockHeld(cs_main);
4111 int nHeight = pindex->nHeight;
4113 // Remove the invalidity flag from this block and all its descendants.
4114 BlockMap::iterator it = mapBlockIndex.begin();
4115 while (it != mapBlockIndex.end()) {
4116 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
4117 it->second->nStatus &= ~BLOCK_FAILED_MASK;
4118 setDirtyBlockIndex.insert(it->second);
4119 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
4120 setBlockIndexCandidates.insert(it->second);
4122 if (it->second == pindexBestInvalid) {
4123 // Reset invalid block marker if it was pointing to one of those.
4124 pindexBestInvalid = NULL;
4130 // Remove the invalidity flag from all ancestors too.
4131 while (pindex != NULL) {
4132 if (pindex->nStatus & BLOCK_FAILED_MASK) {
4133 pindex->nStatus &= ~BLOCK_FAILED_MASK;
4134 setDirtyBlockIndex.insert(pindex);
4136 pindex = pindex->pprev;
4141 CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
4143 // Check for duplicate
4144 uint256 hash = block.GetHash();
4145 BlockMap::iterator it = mapBlockIndex.find(hash);
4146 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
4147 if (it != mapBlockIndex.end())
4149 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
4151 // 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
4152 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
4155 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
4157 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
4158 return(0); // return here to avoid the state of pindex->nHeight not set and pprev NULL
4161 // Construct new block index object
4162 CBlockIndex* pindexNew = new CBlockIndex(block);
4164 // We assign the sequence id to blocks only when the full data is available,
4165 // to avoid miners withholding blocks but broadcasting headers, to get a
4166 // competitive advantage.
4167 pindexNew->nSequenceId = 0;
4168 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4169 pindexNew->phashBlock = &((*mi).first);
4170 if (miPrev != mapBlockIndex.end())
4172 if ( (pindexNew->pprev= (*miPrev).second) != 0 )
4173 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
4174 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
4175 pindexNew->BuildSkip();
4177 pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
4178 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
4179 if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
4180 pindexBestHeader = pindexNew;
4182 setDirtyBlockIndex.insert(pindexNew);
4183 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
4184 mi->second = pindexNew;
4188 /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
4189 bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
4191 pindexNew->nTx = block.vtx.size();
4192 pindexNew->nChainTx = 0;
4193 CAmount sproutValue = 0;
4194 CAmount saplingValue = 0;
4195 for (auto tx : block.vtx) {
4196 // Negative valueBalance "takes" money from the transparent value pool
4197 // and adds it to the Sapling value pool. Positive valueBalance "gives"
4198 // money to the transparent value pool, removing from the Sapling value
4199 // pool. So we invert the sign here.
4200 saplingValue += -tx.valueBalance;
4202 for (auto js : tx.vjoinsplit) {
4203 sproutValue += js.vpub_old;
4204 sproutValue -= js.vpub_new;
4207 pindexNew->nSproutValue = sproutValue;
4208 pindexNew->nChainSproutValue = boost::none;
4209 pindexNew->nSaplingValue = saplingValue;
4210 pindexNew->nChainSaplingValue = boost::none;
4211 pindexNew->nFile = pos.nFile;
4212 pindexNew->nDataPos = pos.nPos;
4213 pindexNew->nUndoPos = 0;
4214 pindexNew->nStatus |= BLOCK_HAVE_DATA;
4215 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
4216 setDirtyBlockIndex.insert(pindexNew);
4218 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
4219 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
4220 deque<CBlockIndex*> queue;
4221 queue.push_back(pindexNew);
4223 // Recursively process any descendant blocks that now may be eligible to be connected.
4224 while (!queue.empty()) {
4225 CBlockIndex *pindex = queue.front();
4227 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
4228 if (pindex->pprev) {
4229 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4230 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4232 pindex->nChainSproutValue = boost::none;
4234 if (pindex->pprev->nChainSaplingValue) {
4235 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
4237 pindex->nChainSaplingValue = boost::none;
4240 pindex->nChainSproutValue = pindex->nSproutValue;
4241 pindex->nChainSaplingValue = pindex->nSaplingValue;
4244 LOCK(cs_nBlockSequenceId);
4245 pindex->nSequenceId = nBlockSequenceId++;
4247 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
4248 setBlockIndexCandidates.insert(pindex);
4250 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
4251 while (range.first != range.second) {
4252 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
4253 queue.push_back(it->second);
4255 mapBlocksUnlinked.erase(it);
4259 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
4260 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
4267 bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
4269 LOCK(cs_LastBlockFile);
4271 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
4272 if (vinfoBlockFile.size() <= nFile) {
4273 vinfoBlockFile.resize(nFile + 1);
4277 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
4279 if (vinfoBlockFile.size() <= nFile) {
4280 vinfoBlockFile.resize(nFile + 1);
4284 pos.nPos = vinfoBlockFile[nFile].nSize;
4287 if (nFile != nLastBlockFile) {
4289 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
4291 FlushBlockFile(!fKnown);
4292 nLastBlockFile = nFile;
4295 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
4297 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
4299 vinfoBlockFile[nFile].nSize += nAddSize;
4302 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4303 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
4304 if (nNewChunks > nOldChunks) {
4306 fCheckForPruning = true;
4307 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
4308 FILE *file = OpenBlockFile(pos);
4310 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
4311 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
4316 return state.Error("out of disk space");
4320 setDirtyFileInfo.insert(nFile);
4324 bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
4328 LOCK(cs_LastBlockFile);
4330 unsigned int nNewSize;
4331 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
4332 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
4333 setDirtyFileInfo.insert(nFile);
4335 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4336 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4337 if (nNewChunks > nOldChunks) {
4339 fCheckForPruning = true;
4340 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
4341 FILE *file = OpenUndoFile(pos);
4343 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
4344 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
4349 return state.Error("out of disk space");
4355 bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
4360 uint256 hash; int32_t i;
4361 hash = blockhdr.GetHash();
4362 for (i=31; i>=0; i--)
4363 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4364 fprintf(stderr," <- CheckBlockHeader\n");
4365 if ( chainActive.LastTip() != 0 )
4367 hash = chainActive.LastTip()->GetBlockHash();
4368 for (i=31; i>=0; i--)
4369 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4370 fprintf(stderr," <- chainTip\n");
4374 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
4376 CBlockIndex *tipindex;
4377 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
4378 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
4380 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
4381 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4383 //fprintf(stderr,"now its valid\n");
4387 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4389 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
4390 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4393 // Check block version
4394 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
4395 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
4397 // Check Equihash solution is valid
4400 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4401 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4403 // Check proof of work matches claimed amount
4404 /*komodo_index2pubkey33(pubkey33,pindex,height);
4405 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
4406 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
4410 int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
4411 int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
4413 bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
4414 libzcash::ProofVerifier& verifier,
4415 bool fCheckPOW, bool fCheckMerkleRoot)
4417 uint8_t pubkey33[33]; uint256 hash;
4418 // These are checks that are independent of context.
4419 hash = block.GetHash();
4420 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
4421 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
4423 if ( *futureblockp == 0 )
4425 LogPrintf("CheckBlock header error");
4431 //if ( !CheckEquihashSolution(&block, Params()) )
4432 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4433 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
4434 if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
4436 int32_t z; for (z=31; z>=0; z--)
4437 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
4438 fprintf(stderr," failed hash ht.%d\n",height);
4439 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
4441 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
4442 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4444 // Check the merkle root.
4445 if (fCheckMerkleRoot) {
4447 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4448 if (block.hashMerkleRoot != hashMerkleRoot2)
4449 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
4450 REJECT_INVALID, "bad-txnmrklroot", true);
4452 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4453 // of transactions in a block without affecting the merkle root of a block,
4454 // while still invalidating it.
4456 return state.DoS(100, error("CheckBlock: duplicate transaction"),
4457 REJECT_INVALID, "bad-txns-duplicate", true);
4460 // All potential-corruption validation must be done before we do any
4461 // transaction validation, as otherwise we may mark the header as invalid
4462 // because we receive the wrong transactions for it.
4465 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
4466 return state.DoS(100, error("CheckBlock: size limits failed"),
4467 REJECT_INVALID, "bad-blk-length");
4469 // First transaction must be coinbase, the rest must not be
4470 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
4471 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
4472 REJECT_INVALID, "bad-cb-missing");
4474 for (unsigned int i = 1; i < block.vtx.size(); i++)
4475 if (block.vtx[i].IsCoinBase())
4476 return state.DoS(100, error("CheckBlock: more than one coinbase"),
4477 REJECT_INVALID, "bad-cb-multiple");
4479 // Check transactions
4480 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
4482 CValidationState stateDummy; int32_t i,j,rejects=0,lastrejects=0;
4483 //fprintf(stderr,"put block's tx into mempool\n");
4486 for (i=0; i<block.vtx.size(); i++)
4488 CTransaction Tx; const CTransaction &tx = (CTransaction)block.vtx[i];
4489 if ( tx.IsCoinBase() != 0 )
4491 else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || komodo_isPoS((CBlock *)&block) != 0) )
4494 if ( myAddtomempool(Tx) == false ) // happens with out of order tx in block on resync
4497 if ( rejects == 0 || rejects == lastrejects )
4499 if ( 0 && lastrejects != 0 )
4500 fprintf(stderr,"lastrejects.%d -> all tx in mempool\n",lastrejects);
4503 //fprintf(stderr,"addtomempool ht.%d for CC checking: n.%d rejects.%d last.%d\n",height,(int32_t)block.vtx.size(),rejects,lastrejects);
4504 lastrejects = rejects;
4507 //fprintf(stderr,"done putting block's tx into mempool\n");
4509 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4511 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
4512 return error("CheckBlock: komodo_validate_interest failed");
4513 if (!CheckTransaction(tx, state, verifier))
4514 return error("CheckBlock: CheckTransaction failed");
4516 unsigned int nSigOps = 0;
4517 BOOST_FOREACH(const CTransaction& tx, block.vtx)
4519 nSigOps += GetLegacySigOpCount(tx);
4521 if (nSigOps > MAX_BLOCK_SIGOPS)
4522 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
4523 REJECT_INVALID, "bad-blk-sigops", true);
4524 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
4526 //static uint32_t counter;
4527 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
4528 // fprintf(stderr,"check deposit rejection\n");
4529 LogPrintf("CheckBlockHeader komodo_check_deposit error");
4535 bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4537 const CChainParams& chainParams = Params();
4538 const Consensus::Params& consensusParams = chainParams.GetConsensus();
4539 uint256 hash = block.GetHash();
4540 if (hash == consensusParams.hashGenesisBlock)
4545 int nHeight = pindexPrev->nHeight+1;
4547 // Check proof of work
4548 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
4550 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) <<
4551 " for block #" << nHeight << endl;
4552 return state.DoS(100, error("%s: incorrect proof of work", __func__),
4553 REJECT_INVALID, "bad-diffbits");
4556 // Check timestamp against prev
4557 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
4559 return state.Invalid(error("%s: block's timestamp is too early", __func__),
4560 REJECT_INVALID, "time-too-old");
4563 // Check that timestamp is not too far in the future
4564 if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
4566 return state.Invalid(error("%s: block timestamp too far in the future", __func__),
4567 REJECT_INVALID, "time-too-new");
4570 if (fCheckpointsEnabled)
4572 // Check that the block chain matches the known block chain up to a checkpoint
4573 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
4575 /*CBlockIndex *heightblock = chainActive[nHeight];
4576 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4578 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4581 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
4583 // Don't accept any forks from the main chain prior to last checkpoint
4584 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
4585 int32_t notarized_height;
4586 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight > 1 )
4588 CBlockIndex *heightblock = chainActive[nHeight];
4589 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4591 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
4595 if ( pcheckpoint != 0 && nHeight < pcheckpoint->nHeight )
4596 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->nHeight));
4597 if ( komodo_checkpoint(¬arized_height,nHeight,hash) < 0 )
4599 CBlockIndex *heightblock = chainActive[nHeight];
4600 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4602 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4604 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4608 // Reject block.nVersion < 4 blocks
4609 if (block.nVersion < 4)
4610 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
4611 REJECT_OBSOLETE, "bad-version");
4616 bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4618 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
4619 const Consensus::Params& consensusParams = Params().GetConsensus();
4621 // Check that all transactions are finalized
4622 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
4624 // Check transaction contextually against consensus rules at block height
4625 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4626 return false; // Failure reason has been set in validation state object
4629 int nLockTimeFlags = 0;
4630 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
4631 ? pindexPrev->GetMedianTimePast()
4632 : block.GetBlockTime();
4633 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
4634 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
4638 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4639 // In Zcash this has been enforced since launch, except that the genesis
4640 // block didn't include the height in the coinbase (see Zcash protocol spec
4641 // section '6.8 Bitcoin Improvement Proposals').
4644 CScript expect = CScript() << nHeight;
4645 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4646 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
4647 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
4653 bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
4655 static uint256 zero;
4656 const CChainParams& chainparams = Params();
4657 AssertLockHeld(cs_main);
4659 // Check for duplicate
4660 uint256 hash = block.GetHash();
4661 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4662 CBlockIndex *pindex = NULL;
4663 if (miSelf != mapBlockIndex.end())
4665 // Block header is already known.
4666 if ( (pindex= miSelf->second) == 0 )
4667 miSelf->second = pindex = AddToBlockIndex(block);
4670 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
4671 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
4672 /*if ( pindex != 0 && hash == komodo_requestedhash )
4674 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4675 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4676 komodo_requestedcount = 0;
4679 //if ( pindex == 0 )
4680 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
4683 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
4685 if ( *futureblockp == 0 )
4687 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
4691 // Get prev block index
4692 CBlockIndex* pindexPrev = NULL;
4693 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4695 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
4696 if (mi == mapBlockIndex.end())
4698 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
4700 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
4702 pindexPrev = (*mi).second;
4703 if (pindexPrev == 0 )
4705 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
4708 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
4709 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
4711 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4713 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4714 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
4719 if ( (pindex= AddToBlockIndex(block)) != 0 )
4721 miSelf = mapBlockIndex.find(hash);
4722 if (miSelf != mapBlockIndex.end())
4723 miSelf->second = pindex;
4724 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
4729 /*if ( pindex != 0 && hash == komodo_requestedhash )
4731 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4732 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
4733 komodo_requestedcount = 0;
4738 bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
4740 const CChainParams& chainparams = Params();
4741 AssertLockHeld(cs_main);
4743 CBlockIndex *&pindex = *ppindex;
4744 if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
4746 if ( *futureblockp == 0 )
4748 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
4754 LogPrintf("AcceptBlock null pindex error\n");
4757 //fprintf(stderr,"acceptblockheader passed\n");
4758 // Try to process all requested blocks that we don't have, but only
4759 // process an unrequested block if it's new and has enough work to
4760 // advance our tip, and isn't too many blocks ahead.
4761 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4762 bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
4763 // Blocks that are too out-of-order needlessly limit the effectiveness of
4764 // pruning, because pruning will not delete block files that contain any
4765 // blocks which are too close in height to the tip. Apply this test
4766 // regardless of whether pruning is enabled; it should generally be safe to
4767 // not process unrequested blocks.
4768 bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
4770 // TODO: deal better with return value and error conditions for duplicate
4771 // and unrequested blocks.
4772 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
4773 if (fAlreadyHave) return true;
4774 if (!fRequested) { // If we didn't ask for it:
4775 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4776 if (!fHasMoreWork) return true; // Don't process less-work chains
4777 if (fTooFarAhead) return true; // Block height is too high
4780 // See method docstring for why this is always disabled
4781 auto verifier = libzcash::ProofVerifier::Disabled();
4782 if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
4784 if ( *futureblockp == 0 )
4786 if (state.IsInvalid() && !state.CorruptionPossible()) {
4787 pindex->nStatus |= BLOCK_FAILED_VALID;
4788 setDirtyBlockIndex.insert(pindex);
4790 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
4795 int nHeight = pindex->nHeight;
4796 // Write block to history file
4798 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4799 CDiskBlockPos blockPos;
4802 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
4803 return error("AcceptBlock(): FindBlockPos failed");
4805 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
4806 AbortNode(state, "Failed to write block");
4807 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
4808 return error("AcceptBlock(): ReceivedBlockTransactions failed");
4809 } catch (const std::runtime_error& e) {
4810 return AbortNode(state, std::string("System error: ") + e.what());
4813 if (fCheckForPruning)
4814 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
4815 if ( *futureblockp == 0 )
4817 LogPrintf("AcceptBlock block from future error\n");
4821 static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
4823 unsigned int nFound = 0;
4824 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
4826 if (pstart->nVersion >= minVersion)
4828 pstart = pstart->pprev;
4830 return (nFound >= nRequired);
4833 void komodo_currentheight_set(int32_t height);
4835 CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4837 CBlockIndex *pindex = 0;
4838 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4839 if ( miSelf != mapBlockIndex.end() )
4841 if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4843 miSelf->second = AddToBlockIndex(*pblock);
4844 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4846 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4848 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4849 if ( miSelf != mapBlockIndex.end() )
4851 if ( miSelf->second == 0 )
4853 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4854 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4862 CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
4864 CBlockIndex *pindex=0,*previndex=0;
4865 if ( (pindex= mapBlockIndex[hash]) == 0 )
4867 pindex = new CBlockIndex();
4869 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4870 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4871 pindex->phashBlock = &((*mi).first);
4873 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4874 if ( miSelf == mapBlockIndex.end() )
4876 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4879 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4883 pindex = AddToBlockIndex(*pblock);
4884 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4888 miSelf->second = pindex;
4889 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4890 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4892 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4894 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4895 if ( miSelf == mapBlockIndex.end() )
4896 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4897 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
4899 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4901 if ( previndex == 0 )
4902 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4903 if ( previndex != 0 )
4905 miSelf->second = previndex;
4906 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4907 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4909 } else LogPrintf("komodo_ensure unexpected null miprev\n");
4915 bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
4917 // Preliminary checks
4918 bool checked; uint256 hash; int32_t futureblock=0;
4919 auto verifier = libzcash::ProofVerifier::Disabled();
4920 hash = pblock->GetHash();
4921 //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight);
4924 if ( chainActive.LastTip() != 0 )
4925 komodo_currentheight_set(chainActive.LastTip()->nHeight);
4926 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
4927 bool fRequested = MarkBlockAsReceived(hash);
4928 fRequested |= fForceProcessing;
4929 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
4932 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
4934 if (!checked && futureblock == 0)
4938 Misbehaving(pfrom->GetId(), 1);
4940 return error("%s: CheckBlock FAILED", __func__);
4943 CBlockIndex *pindex = NULL;
4946 // without the komodo_ensure call, it is quite possible to get a non-error but null pindex returned from AcceptBlockHeader. In a 2 node network, it will be a long time before that block is reprocessed. Even though restarting makes it rescan, it seems much better to keep the nodes in sync
4947 komodo_ensure(pblock, hash);
4949 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
4950 if (pindex && pfrom) {
4951 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
4954 if (!ret && futureblock == 0)
4955 return error("%s: AcceptBlock FAILED", __func__);
4956 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
4959 if (futureblock == 0 && !ActivateBestChain(state, pblock))
4960 return error("%s: ActivateBestChain failed", __func__);
4961 //fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight);
4966 bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4968 AssertLockHeld(cs_main);
4969 assert(pindexPrev == chainActive.Tip());
4971 CCoinsViewCache viewNew(pcoinsTip);
4972 CBlockIndex indexDummy(block);
4973 indexDummy.pprev = pindexPrev;
4974 indexDummy.nHeight = pindexPrev->nHeight + 1;
4975 // JoinSplit proofs are verified in ConnectBlock
4976 auto verifier = libzcash::ProofVerifier::Disabled();
4977 // NOTE: CheckBlockHeader is called by CheckBlock
4978 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
4980 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
4983 int32_t futureblock;
4984 if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
4986 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
4989 if (!ContextualCheckBlock(block, state, pindexPrev))
4991 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
4994 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
4996 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
4999 assert(state.IsValid());
5000 if ( futureblock != 0 )
5006 * BLOCK PRUNING CODE
5009 /* Calculate the amount of disk space the block & undo files currently use */
5010 uint64_t CalculateCurrentUsage()
5012 uint64_t retval = 0;
5013 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
5014 retval += file.nSize + file.nUndoSize;
5019 /* Prune a block file (modify associated database entries)*/
5020 void PruneOneBlockFile(const int fileNumber)
5022 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
5023 CBlockIndex* pindex = it->second;
5024 if (pindex->nFile == fileNumber) {
5025 pindex->nStatus &= ~BLOCK_HAVE_DATA;
5026 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
5028 pindex->nDataPos = 0;
5029 pindex->nUndoPos = 0;
5030 setDirtyBlockIndex.insert(pindex);
5032 // Prune from mapBlocksUnlinked -- any block we prune would have
5033 // to be downloaded again in order to consider its chain, at which
5034 // point it would be considered as a candidate for
5035 // mapBlocksUnlinked or setBlockIndexCandidates.
5036 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
5037 while (range.first != range.second) {
5038 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
5040 if (it->second == pindex) {
5041 mapBlocksUnlinked.erase(it);
5047 vinfoBlockFile[fileNumber].SetNull();
5048 setDirtyFileInfo.insert(fileNumber);
5052 void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
5054 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
5055 CDiskBlockPos pos(*it, 0);
5056 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
5057 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
5058 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
5062 /* Calculate the block/rev files that should be deleted to remain under target*/
5063 void FindFilesToPrune(std::set<int>& setFilesToPrune)
5065 LOCK2(cs_main, cs_LastBlockFile);
5066 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
5069 if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
5072 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
5073 uint64_t nCurrentUsage = CalculateCurrentUsage();
5074 // We don't check to prune until after we've allocated new space for files
5075 // So we should leave a buffer under our target to account for another allocation
5076 // before the next pruning.
5077 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
5078 uint64_t nBytesToPrune;
5081 if (nCurrentUsage + nBuffer >= nPruneTarget) {
5082 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
5083 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
5085 if (vinfoBlockFile[fileNumber].nSize == 0)
5088 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
5091 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
5092 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
5095 PruneOneBlockFile(fileNumber);
5096 // Queue up the files for removal
5097 setFilesToPrune.insert(fileNumber);
5098 nCurrentUsage -= nBytesToPrune;
5103 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
5104 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
5105 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
5106 nLastBlockWeCanPrune, count);
5109 bool CheckDiskSpace(uint64_t nAdditionalBytes)
5111 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
5113 // Check for nMinDiskSpace bytes (currently 50MB)
5114 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
5115 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
5120 FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
5122 static int32_t didinit[64];
5125 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5126 boost::filesystem::create_directories(path.parent_path());
5127 FILE* file = fopen(path.string().c_str(), "rb+");
5128 if (!file && !fReadOnly)
5129 file = fopen(path.string().c_str(), "wb+");
5131 LogPrintf("Unable to open file %s\n", path.string());
5134 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
5136 komodo_prefetch(file);
5137 didinit[pos.nFile] = 1;
5140 if (fseek(file, pos.nPos, SEEK_SET)) {
5141 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5149 FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
5150 return OpenDiskFile(pos, "blk", fReadOnly);
5153 FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5154 return OpenDiskFile(pos, "rev", fReadOnly);
5157 boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
5159 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
5162 CBlockIndex * InsertBlockIndex(uint256 hash)
5168 BlockMap::iterator mi = mapBlockIndex.find(hash);
5169 if (mi != mapBlockIndex.end())
5170 return (*mi).second;
5173 CBlockIndex* pindexNew = new CBlockIndex();
5175 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
5176 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
5177 pindexNew->phashBlock = &((*mi).first);
5178 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
5183 //void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
5185 bool static LoadBlockIndexDB()
5187 const CChainParams& chainparams = Params();
5188 LogPrintf("%s: start loading guts\n", __func__);
5189 if (!pblocktree->LoadBlockIndexGuts())
5191 LogPrintf("%s: loaded guts\n", __func__);
5192 boost::this_thread::interruption_point();
5194 // Calculate nChainWork
5195 vector<pair<int, CBlockIndex*> > vSortedByHeight;
5196 vSortedByHeight.reserve(mapBlockIndex.size());
5197 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5199 CBlockIndex* pindex = item.second;
5200 vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
5201 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
5203 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
5204 sort(vSortedByHeight.begin(), vSortedByHeight.end());
5205 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
5206 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
5208 CBlockIndex* pindex = item.second;
5209 pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
5210 // We can link the chain of blocks for which we've received transactions at some point.
5211 // Pruned nodes may have deleted the block.
5212 if (pindex->nTx > 0) {
5213 if (pindex->pprev) {
5214 if (pindex->pprev->nChainTx) {
5215 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
5216 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
5217 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
5219 pindex->nChainSproutValue = boost::none;
5221 if (pindex->pprev->nChainSaplingValue) {
5222 pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
5224 pindex->nChainSaplingValue = boost::none;
5227 pindex->nChainTx = 0;
5228 pindex->nChainSproutValue = boost::none;
5229 pindex->nChainSaplingValue = boost::none;
5230 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
5233 pindex->nChainTx = pindex->nTx;
5234 pindex->nChainSproutValue = pindex->nSproutValue;
5235 pindex->nChainSaplingValue = pindex->nSaplingValue;
5238 // Construct in-memory chain of branch IDs.
5239 // Relies on invariant: a block that does not activate a network upgrade
5240 // will always be valid under the same consensus rules as its parent.
5241 // Genesis block has a branch ID of zero by definition, but has no
5242 // validity status because it is side-loaded into a fresh chain.
5243 // Activation blocks will have branch IDs set (read from disk).
5244 if (pindex->pprev) {
5245 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
5246 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
5249 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
5251 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
5252 setBlockIndexCandidates.insert(pindex);
5253 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
5254 pindexBestInvalid = pindex;
5256 pindex->BuildSkip();
5257 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
5258 pindexBestHeader = pindex;
5259 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
5261 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
5263 // Load block file info
5264 pblocktree->ReadLastBlockFile(nLastBlockFile);
5265 vinfoBlockFile.resize(nLastBlockFile + 1);
5266 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
5267 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
5268 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
5270 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
5271 for (int nFile = nLastBlockFile + 1; true; nFile++) {
5272 CBlockFileInfo info;
5273 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
5274 vinfoBlockFile.push_back(info);
5280 // Check presence of blk files
5281 LogPrintf("Checking all blk files are present...\n");
5282 set<int> setBlkDataFiles;
5283 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5285 CBlockIndex* pindex = item.second;
5286 if (pindex->nStatus & BLOCK_HAVE_DATA) {
5287 setBlkDataFiles.insert(pindex->nFile);
5289 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
5291 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
5292 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
5294 CDiskBlockPos pos(*it, 0);
5295 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
5300 // Check whether we have ever pruned block & undo files
5301 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
5303 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
5305 // Check whether we need to continue reindexing
5306 bool fReindexing = false;
5307 pblocktree->ReadReindexing(fReindexing);
5308 fReindex |= fReindexing;
5310 // Check whether we have a transaction index
5311 pblocktree->ReadFlag("txindex", fTxIndex);
5312 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
5313 // Check whether we have an address index
5314 pblocktree->ReadFlag("addressindex", fAddressIndex);
5315 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
5317 // Check whether we have a timestamp index
5318 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
5319 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
5321 // Check whether we have a spent index
5322 pblocktree->ReadFlag("spentindex", fSpentIndex);
5323 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
5325 // Fill in-memory data
5326 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5328 CBlockIndex* pindex = item.second;
5329 // - This relationship will always be true even if pprev has multiple
5330 // children, because hashSproutAnchor is technically a property of pprev,
5331 // not its children.
5332 // - This will miss chain tips; we handle the best tip below, and other
5333 // tips will be handled by ConnectTip during a re-org.
5334 if (pindex->pprev) {
5335 pindex->pprev->hashFinalSproutRoot = pindex->hashSproutAnchor;
5337 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
5340 // Load pointer to end of best chain
5341 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
5342 if (it == mapBlockIndex.end())
5345 chainActive.SetTip(it->second);
5347 // Set hashFinalSproutRoot for the end of best chain
5348 it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT);
5350 PruneBlockIndexCandidates();
5353 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
5354 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
5356 int32_t longestchain = komodo_longestchain();
5357 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
5358 // runs, which makes it return 0, so we guess 50% for now
5359 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
5362 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
5363 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
5364 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
5367 EnforceNodeDeprecation(chainActive.Height(), true);
5372 CVerifyDB::CVerifyDB()
5374 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
5377 CVerifyDB::~CVerifyDB()
5379 uiInterface.ShowProgress("", 100);
5382 bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
5385 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
5388 // Verify blocks in the best chain
5389 if (nCheckDepth <= 0)
5390 nCheckDepth = 1000000000; // suffices until the year 19000
5391 if (nCheckDepth > chainActive.Height())
5392 nCheckDepth = chainActive.Height();
5393 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
5394 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
5395 CCoinsViewCache coins(coinsview);
5396 CBlockIndex* pindexState = chainActive.Tip();
5397 CBlockIndex* pindexFailure = NULL;
5398 int nGoodTransactions = 0;
5399 CValidationState state;
5400 // No need to verify JoinSplits twice
5401 auto verifier = libzcash::ProofVerifier::Disabled();
5402 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
5403 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
5405 boost::this_thread::interruption_point();
5406 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
5407 if (pindex->nHeight < chainActive.Height()-nCheckDepth)
5410 // check level 0: read from disk
5411 if (!ReadBlockFromDisk(block, pindex,0))
5412 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5413 // check level 1: verify block validity
5414 int32_t futureblock;
5415 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0) )
5416 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
5417 // check level 2: verify undo validity
5418 if (nCheckLevel >= 2 && pindex) {
5420 CDiskBlockPos pos = pindex->GetUndoPos();
5421 if (!pos.IsNull()) {
5422 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5423 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
5426 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
5427 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
5429 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5430 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5431 pindexState = pindex->pprev;
5433 nGoodTransactions = 0;
5434 pindexFailure = pindex;
5436 nGoodTransactions += block.vtx.size();
5438 if (ShutdownRequested())
5441 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
5443 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
5445 // check level 4: try reconnecting blocks
5446 if (nCheckLevel >= 4) {
5447 CBlockIndex *pindex = pindexState;
5448 while (pindex != chainActive.Tip()) {
5449 boost::this_thread::interruption_point();
5450 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
5451 pindex = chainActive.Next(pindex);
5453 if (!ReadBlockFromDisk(block, pindex,0))
5454 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5455 if (!ConnectBlock(block, state, pindex, coins,false, true))
5456 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
5460 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
5465 bool RewindBlockIndex(const CChainParams& params, bool& clearWitnessCaches)
5469 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
5470 // index will have nCachedBranchId set based on the values previously persisted
5471 // to disk. By definition, a set nCachedBranchId means that the block was
5472 // fully-validated under the corresponding consensus rules. Thus we can quickly
5473 // identify whether the current active chain matches our expected sequence of
5474 // consensus rule changes, with two checks:
5476 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
5477 // - nCachedBranchId for each block matches what we expect.
5478 auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) {
5479 auto consensus = params.GetConsensus();
5480 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5481 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus);
5482 return fFlagSet == fFlagExpected &&
5483 pindex->nCachedBranchId &&
5484 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->nHeight, consensus);
5488 while (nHeight <= chainActive.Height()) {
5489 if (!sufficientlyValidated(chainActive[nHeight])) {
5495 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
5496 auto rewindLength = chainActive.Height() - nHeight;
5497 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH)
5499 auto pindexOldTip = chainActive.Tip();
5500 auto pindexRewind = chainActive[nHeight - 1];
5501 auto msg = strprintf(_(
5502 "A block chain rewind has been detected that would roll back %d blocks! "
5503 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5504 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5505 _("Rewind details") + ":\n" +
5506 "- " + strprintf(_("Current tip: %s, height %d"),
5507 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
5508 "- " + strprintf(_("Rewinding to: %s, height %d"),
5509 pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
5510 _("Please help, human!");
5511 LogPrintf("*** %s\n", msg);
5512 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5517 CValidationState state;
5518 CBlockIndex* pindex = chainActive.Tip();
5519 while (chainActive.Height() >= nHeight) {
5520 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5521 // If pruning, don't try rewinding past the HAVE_DATA point;
5522 // since older blocks can't be served anyway, there's
5523 // no need to walk further, and trying to DisconnectTip()
5524 // will fail (and require a needless reindex/redownload
5525 // of the blockchain).
5528 if (!DisconnectTip(state, true)) {
5529 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
5531 // Occasionally flush state to disk.
5532 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5536 // Reduce validity flag and have-data flags.
5538 // Collect blocks to be removed (blocks in mapBlockIndex must be at least BLOCK_VALID_TREE).
5539 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5540 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5541 std::vector<const CBlockIndex*> vBlocks;
5542 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5543 CBlockIndex* pindexIter = it->second;
5545 // Note: If we encounter an insufficiently validated block that
5546 // is on chainActive, it must be because we are a pruning node, and
5547 // this block or some successor doesn't HAVE_DATA, so we were unable to
5548 // rewind all the way. Blocks remaining on chainActive at this point
5549 // must not have their validity reduced.
5550 if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
5552 pindexIter->nStatus =
5553 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5554 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
5555 // Remove have-data flags
5556 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
5558 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
5559 pindexIter->nCachedBranchId = boost::none;
5560 // Remove storage location
5561 pindexIter->nFile = 0;
5562 pindexIter->nDataPos = 0;
5563 pindexIter->nUndoPos = 0;
5564 // Remove various other things
5565 pindexIter->nTx = 0;
5566 pindexIter->nChainTx = 0;
5567 pindexIter->nSproutValue = boost::none;
5568 pindexIter->nChainSproutValue = boost::none;
5569 pindexIter->nSaplingValue = 0;
5570 pindexIter->nChainSaplingValue = boost::none;
5571 pindexIter->nSequenceId = 0;
5573 // Make sure it gets written
5574 /* corresponds to commented out block below as an alternative to setDirtyBlockIndex
5575 vBlocks.push_back(pindexIter);
5577 setDirtyBlockIndex.insert(pindexIter);
5578 if (pindexIter == pindexBestInvalid)
5580 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
5581 pindexBestInvalid = NULL;
5585 setBlockIndexCandidates.erase(pindexIter);
5586 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
5587 while (ret.first != ret.second) {
5588 if (ret.first->second == pindexIter) {
5589 mapBlocksUnlinked.erase(ret.first++);
5594 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5595 setBlockIndexCandidates.insert(pindexIter);
5600 // Set pindexBestHeader to the current chain tip
5601 // (since we are about to delete the block it is pointing to)
5602 pindexBestHeader = chainActive.Tip();
5604 // Erase block indices on-disk
5605 if (!pblocktree->EraseBatchSync(vBlocks)) {
5606 return AbortNode(state, "Failed to erase from block index database");
5609 // Erase block indices in-memory
5610 for (auto pindex : vBlocks) {
5611 auto ret = mapBlockIndex.find(*pindex->phashBlock);
5612 if (ret != mapBlockIndex.end()) {
5613 mapBlockIndex.erase(ret);
5619 PruneBlockIndexCandidates();
5623 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5630 void UnloadBlockIndex()
5633 setBlockIndexCandidates.clear();
5634 chainActive.SetTip(NULL);
5635 pindexBestInvalid = NULL;
5636 pindexBestHeader = NULL;
5638 mapOrphanTransactions.clear();
5639 mapOrphanTransactionsByPrev.clear();
5641 mapBlocksUnlinked.clear();
5642 vinfoBlockFile.clear();
5644 nBlockSequenceId = 1;
5645 mapBlockSource.clear();
5646 mapBlocksInFlight.clear();
5647 nQueuedValidatedHeaders = 0;
5648 nPreferredDownload = 0;
5649 setDirtyBlockIndex.clear();
5650 setDirtyFileInfo.clear();
5651 mapNodeState.clear();
5652 recentRejects.reset(NULL);
5654 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5655 delete entry.second;
5657 mapBlockIndex.clear();
5658 fHavePruned = false;
5661 bool LoadBlockIndex()
5663 // Load block index from databases
5664 KOMODO_LOADINGBLOCKS = 1;
5665 if (!fReindex && !LoadBlockIndexDB())
5667 KOMODO_LOADINGBLOCKS = 0;
5670 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
5675 bool InitBlockIndex() {
5676 const CChainParams& chainparams = Params();
5679 // Initialize global variables that cannot be constructed at startup.
5680 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
5681 // Check whether we're already initialized
5682 if (chainActive.Genesis() != NULL)
5686 // Use the provided setting for -txindex in the new database
5687 fTxIndex = GetBoolArg("-txindex", true);
5688 pblocktree->WriteFlag("txindex", fTxIndex);
5689 // Use the provided setting for -addressindex in the new database
5690 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5691 pblocktree->WriteFlag("addressindex", fAddressIndex);
5693 // Use the provided setting for -timestampindex in the new database
5694 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5695 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5697 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5698 pblocktree->WriteFlag("spentindex", fSpentIndex);
5699 fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
5700 LogPrintf("Initializing databases...\n");
5702 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5705 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5706 // Start new block file
5707 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5708 CDiskBlockPos blockPos;
5709 CValidationState state;
5710 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5711 return error("LoadBlockIndex(): FindBlockPos failed");
5712 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5713 return error("LoadBlockIndex(): writing genesis block to disk failed");
5714 CBlockIndex *pindex = AddToBlockIndex(block);
5716 return error("LoadBlockIndex(): couldnt add to block index");
5717 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5718 return error("LoadBlockIndex(): genesis block not accepted");
5719 if (!ActivateBestChain(state, &block))
5720 return error("LoadBlockIndex(): genesis block cannot be activated");
5721 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
5722 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
5723 } catch (const std::runtime_error& e) {
5724 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
5733 bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
5735 const CChainParams& chainparams = Params();
5736 // Map of disk positions for blocks with unknown parent (only used for reindex)
5737 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5738 int64_t nStart = GetTimeMillis();
5742 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
5743 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5744 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
5745 uint64_t nRewind = blkdat.GetPos();
5746 while (!blkdat.eof()) {
5747 boost::this_thread::interruption_point();
5749 blkdat.SetPos(nRewind);
5750 nRewind++; // start one byte further next time, in case of failure
5751 blkdat.SetLimit(); // remove former limit
5752 unsigned int nSize = 0;
5755 unsigned char buf[MESSAGE_START_SIZE];
5756 blkdat.FindByte(Params().MessageStart()[0]);
5757 nRewind = blkdat.GetPos()+1;
5758 blkdat >> FLATDATA(buf);
5759 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
5763 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5765 } catch (const std::exception&) {
5766 // no valid block header found; don't complain
5771 uint64_t nBlockPos = blkdat.GetPos();
5773 dbp->nPos = nBlockPos;
5774 blkdat.SetLimit(nBlockPos + nSize);
5775 blkdat.SetPos(nBlockPos);
5778 nRewind = blkdat.GetPos();
5780 // detect out of order blocks, and store them for later
5781 uint256 hash = block.GetHash();
5782 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
5783 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
5784 block.hashPrevBlock.ToString());
5786 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5790 // process in case the block isn't known yet
5791 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
5792 CValidationState state;
5793 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
5795 if (state.IsError())
5797 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
5798 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
5801 // Recursively process earlier encountered successors of this block
5802 deque<uint256> queue;
5803 queue.push_back(hash);
5804 while (!queue.empty()) {
5805 uint256 head = queue.front();
5807 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5808 while (range.first != range.second) {
5809 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5810 if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1))
5812 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
5814 CValidationState dummy;
5815 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
5818 queue.push_back(block.GetHash());
5822 mapBlocksUnknownParent.erase(it);
5825 } catch (const std::exception& e) {
5826 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
5829 } catch (const std::runtime_error& e) {
5830 AbortNode(std::string("System error: ") + e.what());
5833 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
5837 void static CheckBlockIndex()
5839 const Consensus::Params& consensusParams = Params().GetConsensus();
5840 if (!fCheckBlockIndex) {
5846 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5847 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5848 // iterating the block tree require that chainActive has been initialized.)
5849 if (chainActive.Height() < 0) {
5850 assert(mapBlockIndex.size() <= 1);
5854 // Build forward-pointing map of the entire block tree.
5855 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5856 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5857 if ( it->second != 0 )
5858 forward.insert(std::make_pair(it->second->pprev, it->second));
5860 if ( Params().NetworkIDString() != "regtest" )
5861 assert(forward.size() == mapBlockIndex.size());
5863 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5864 CBlockIndex *pindex = rangeGenesis.first->second;
5865 rangeGenesis.first++;
5866 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
5868 // Iterate over the entire block tree, using depth-first search.
5869 // Along the way, remember whether there are blocks on the path from genesis
5870 // block being explored which are the first to have certain properties.
5873 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5874 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
5875 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
5876 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
5877 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
5878 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5879 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5880 while (pindex != NULL) {
5882 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5883 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
5884 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
5885 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
5886 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
5887 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5888 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
5890 // Begin: actual consistency checks.
5891 if (pindex->pprev == NULL) {
5892 // Genesis block checks.
5893 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
5894 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5896 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
5897 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5898 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5900 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5901 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5902 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5904 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5905 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5907 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5908 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5909 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5910 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
5911 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
5912 assert(pindex->nHeight == nHeight); // nHeight must be consistent.
5913 assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
5914 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5915 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5916 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5917 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5918 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5919 if (pindexFirstInvalid == NULL) {
5920 // Checks for not-invalid blocks.
5921 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5923 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5924 if (pindexFirstInvalid == NULL) {
5925 // If this block sorts at least as good as the current tip and
5926 // is valid and we have all data for its parents, it must be in
5927 // setBlockIndexCandidates. chainActive.Tip() must also be there
5928 // even if some data has been pruned.
5929 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5930 assert(setBlockIndexCandidates.count(pindex));
5932 // If some parent is missing, then it could be that this block was in
5933 // setBlockIndexCandidates but had to be removed because of the missing data.
5934 // In this case it must be in mapBlocksUnlinked -- see test below.
5936 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
5937 assert(setBlockIndexCandidates.count(pindex) == 0);
5939 // Check whether this block is in mapBlocksUnlinked.
5940 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5941 bool foundInUnlinked = false;
5942 while (rangeUnlinked.first != rangeUnlinked.second) {
5943 assert(rangeUnlinked.first->first == pindex->pprev);
5944 if (rangeUnlinked.first->second == pindex) {
5945 foundInUnlinked = true;
5948 rangeUnlinked.first++;
5950 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5951 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5952 assert(foundInUnlinked);
5954 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5955 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5956 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5957 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5958 assert(fHavePruned); // We must have pruned.
5959 // This block may have entered mapBlocksUnlinked if:
5960 // - it has a descendant that at some point had more work than the
5962 // - we tried switching to that descendant but were missing
5963 // data for some intermediate block between chainActive and the
5965 // So if this block is itself better than chainActive.Tip() and it wasn't in
5966 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5967 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5968 if (pindexFirstInvalid == NULL) {
5969 assert(foundInUnlinked);
5973 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5974 // End: actual consistency checks.
5976 // Try descending into the first subnode.
5977 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5978 if (range.first != range.second) {
5979 // A subnode was found.
5980 pindex = range.first->second;
5984 // This is a leaf node.
5985 // Move upwards until we reach a node of which we have not yet visited the last child.
5987 // We are going to either move to a parent or a sibling of pindex.
5988 // If pindex was the first with a certain property, unset the corresponding variable.
5989 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
5990 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
5991 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
5992 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
5993 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
5994 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
5995 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
5997 CBlockIndex* pindexPar = pindex->pprev;
5998 // Find which child we just visited.
5999 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
6000 while (rangePar.first->second != pindex) {
6001 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
6004 // Proceed to the next one.
6006 if (rangePar.first != rangePar.second) {
6007 // Move to the sibling.
6008 pindex = rangePar.first->second;
6019 // Check that we actually traversed the entire map.
6020 assert(nNodes == forward.size());
6023 //////////////////////////////////////////////////////////////////////////////
6028 std::string GetWarnings(const std::string& strFor)
6031 string strStatusBar;
6034 if (!CLIENT_VERSION_IS_RELEASE)
6035 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
6037 if (GetBoolArg("-testsafemode", false))
6038 strStatusBar = strRPC = "testsafemode enabled";
6040 // Misc warnings like out of disk space and clock is wrong
6041 if (strMiscWarning != "")
6044 strStatusBar = strMiscWarning;
6047 if (fLargeWorkForkFound)
6050 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
6052 else if (fLargeWorkInvalidChainFound)
6055 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.");
6061 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6063 const CAlert& alert = item.second;
6064 if (alert.AppliesToMe() && alert.nPriority > nPriority)
6066 nPriority = alert.nPriority;
6067 strStatusBar = alert.strStatusBar;
6068 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
6069 strRPC = alert.strRPCError;
6075 if (strFor == "statusbar")
6076 return strStatusBar;
6077 else if (strFor == "rpc")
6079 assert(!"GetWarnings(): invalid parameter");
6090 //////////////////////////////////////////////////////////////////////////////
6096 bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
6102 assert(recentRejects);
6103 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
6105 // If the chain tip has changed previously rejected transactions
6106 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
6107 // or a double-spend. Reset the rejects filter and give those
6108 // txs a second chance.
6109 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
6110 recentRejects->reset();
6113 return recentRejects->contains(inv.hash) ||
6114 mempool.exists(inv.hash) ||
6115 mapOrphanTransactions.count(inv.hash) ||
6116 pcoinsTip->HaveCoins(inv.hash);
6119 return mapBlockIndex.count(inv.hash);
6121 // Don't know what it is, just say we already got one
6125 void static ProcessGetData(CNode* pfrom)
6127 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
6129 vector<CInv> vNotFound;
6133 while (it != pfrom->vRecvGetData.end()) {
6134 // Don't bother if send buffer is too full to respond anyway
6135 if (pfrom->nSendSize >= SendBufferSize())
6138 const CInv &inv = *it;
6140 boost::this_thread::interruption_point();
6143 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6146 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
6147 if (mi != mapBlockIndex.end())
6149 if (chainActive.Contains(mi->second)) {
6152 static const int nOneMonth = 30 * 24 * 60 * 60;
6153 // To prevent fingerprinting attacks, only send blocks outside of the active
6154 // chain if they are valid, and no more than a month older (both in time, and in
6155 // best equivalent proof of work) than the best header chain we know about.
6156 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
6157 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
6158 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
6160 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
6164 // Pruned nodes may have deleted the block, so check whether
6165 // it's available before trying to send.
6166 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
6168 // Send block from disk
6170 if (!ReadBlockFromDisk(block, (*mi).second,1))
6172 assert(!"cannot load block from disk");
6176 if (inv.type == MSG_BLOCK)
6178 //uint256 hash; int32_t z;
6179 //hash = block.GetHash();
6180 //for (z=31; z>=0; z--)
6181 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
6182 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
6183 pfrom->PushMessage("block", block);
6185 else // MSG_FILTERED_BLOCK)
6187 LOCK(pfrom->cs_filter);
6190 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
6191 pfrom->PushMessage("merkleblock", merkleBlock);
6192 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
6193 // This avoids hurting performance by pointlessly requiring a round-trip
6194 // Note that there is currently no way for a node to request any single transactions we didn't send here -
6195 // they must either disconnect and retry or request the full block.
6196 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
6197 // however we MUST always provide at least what the remote peer needs
6198 typedef std::pair<unsigned int, uint256> PairType;
6199 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
6200 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
6201 pfrom->PushMessage("tx", block.vtx[pair.first]);
6207 // Trigger the peer node to send a getblocks request for the next batch of inventory
6208 if (inv.hash == pfrom->hashContinue)
6210 // Bypass PushInventory, this must send even if redundant,
6211 // and we want it right after the last block so they don't
6212 // wait for other stuff first.
6214 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
6215 pfrom->PushMessage("inv", vInv);
6216 pfrom->hashContinue.SetNull();
6220 else if (inv.IsKnownType())
6222 // Send stream from relay memory
6223 bool pushed = false;
6226 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
6227 if (mi != mapRelay.end()) {
6228 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
6232 if (!pushed && inv.type == MSG_TX) {
6234 if (mempool.lookup(inv.hash, tx)) {
6235 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
6238 pfrom->PushMessage("tx", ss);
6243 vNotFound.push_back(inv);
6247 // Track requests for our stuff.
6248 GetMainSignals().Inventory(inv.hash);
6250 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
6255 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
6257 if (!vNotFound.empty()) {
6258 // Let the peer know that we didn't find what it asked for, so it doesn't
6259 // have to wait around forever. Currently only SPV clients actually care
6260 // about this message: it's needed when they are recursively walking the
6261 // dependencies of relevant unconfirmed transactions. SPV clients want to
6262 // do that because they want to know about (and store and rebroadcast and
6263 // risk analyze) the dependencies of transactions relevant to them, without
6264 // having to download the entire memory pool.
6265 pfrom->PushMessage("notfound", vNotFound);
6269 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
6271 const CChainParams& chainparams = Params();
6272 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
6273 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
6274 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
6276 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
6280 if (strCommand == "version")
6282 // Each connection can only send one version message
6283 if (pfrom->nVersion != 0)
6285 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
6286 Misbehaving(pfrom->GetId(), 1);
6293 uint64_t nNonce = 1;
6294 int nVersion; // use temporary for version, don't set version number until validated as connected
6295 vRecv >> nVersion >> pfrom->nServices >> nTime >> addrMe;
6296 if (nVersion < MIN_PEER_PROTO_VERSION)
6298 // disconnect from peers older than this proto version
6299 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6300 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6301 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
6302 pfrom->fDisconnect = true;
6306 // When Overwinter is active, reject incoming connections from non-Overwinter nodes
6307 const Consensus::Params& params = Params().GetConsensus();
6308 if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER)
6309 && nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)
6311 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, nVersion);
6312 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6313 strprintf("Version must be %d or greater",
6314 params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
6315 pfrom->fDisconnect = true;
6319 if (nVersion == 10300)
6322 vRecv >> addrFrom >> nNonce;
6323 if (!vRecv.empty()) {
6324 vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
6325 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
6328 vRecv >> pfrom->nStartingHeight;
6330 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
6332 pfrom->fRelayTxes = true;
6334 // Disconnect if we connected to ourself
6335 if (nNonce == nLocalHostNonce && nNonce > 1)
6337 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
6338 pfrom->fDisconnect = true;
6342 pfrom->nVersion = nVersion;
6344 pfrom->addrLocal = addrMe;
6345 if (pfrom->fInbound && addrMe.IsRoutable())
6350 // Be shy and don't send version until we hear
6351 if (pfrom->fInbound)
6352 pfrom->PushVersion();
6354 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
6356 // Potentially mark this peer as a preferred download peer.
6357 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
6360 pfrom->PushMessage("verack");
6361 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6363 if (!pfrom->fInbound)
6365 // Advertise our address
6366 if (fListen && !IsInitialBlockDownload())
6368 CAddress addr = GetLocalAddress(&pfrom->addr);
6369 if (addr.IsRoutable())
6371 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6372 pfrom->PushAddress(addr);
6373 } else if (IsPeerAddrLocalGood(pfrom)) {
6374 addr.SetIP(pfrom->addrLocal);
6375 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
6376 pfrom->PushAddress(addr);
6380 // Get recent addresses
6381 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
6383 pfrom->PushMessage("getaddr");
6384 pfrom->fGetAddr = true;
6386 addrman.Good(pfrom->addr);
6388 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
6390 addrman.Add(addrFrom, addrFrom);
6391 addrman.Good(addrFrom);
6398 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
6399 item.second.RelayTo(pfrom);
6402 pfrom->fSuccessfullyConnected = true;
6406 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
6408 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
6409 pfrom->cleanSubVer, pfrom->nVersion,
6410 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
6413 int64_t nTimeOffset = nTime - GetTime();
6414 pfrom->nTimeOffset = nTimeOffset;
6415 AddTimeData(pfrom->addr, nTimeOffset);
6419 else if (pfrom->nVersion == 0)
6421 // Must have a version message before anything else
6422 Misbehaving(pfrom->GetId(), 1);
6427 else if (strCommand == "verack")
6429 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
6431 // Mark this node as currently connected, so we update its timestamp later.
6432 if (pfrom->fNetworkNode) {
6434 State(pfrom->GetId())->fCurrentlyConnected = true;
6439 // Disconnect existing peer connection when:
6440 // 1. The version message has been received
6441 // 2. Overwinter is active
6442 // 3. Peer version is pre-Overwinter
6443 else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
6444 && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
6446 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6447 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
6448 strprintf("Version must be %d or greater",
6449 chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
6450 pfrom->fDisconnect = true;
6455 else if (strCommand == "addr")
6457 vector<CAddress> vAddr;
6460 // Don't want addr from older versions unless seeding
6461 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
6463 if (vAddr.size() > 1000)
6465 Misbehaving(pfrom->GetId(), 20);
6466 return error("message addr size() = %u", vAddr.size());
6469 // Store the new addresses
6470 vector<CAddress> vAddrOk;
6471 int64_t nNow = GetAdjustedTime();
6472 int64_t nSince = nNow - 10 * 60;
6473 BOOST_FOREACH(CAddress& addr, vAddr)
6475 boost::this_thread::interruption_point();
6477 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6478 addr.nTime = nNow - 5 * 24 * 60 * 60;
6479 pfrom->AddAddressKnown(addr);
6480 bool fReachable = IsReachable(addr);
6481 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
6483 // Relay to a limited number of other nodes
6486 // Use deterministic randomness to send to the same nodes for 24 hours
6487 // at a time so the addrKnowns of the chosen nodes prevent repeats
6488 static uint256 hashSalt;
6489 if (hashSalt.IsNull())
6490 hashSalt = GetRandHash();
6491 uint64_t hashAddr = addr.GetHash();
6492 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
6493 hashRand = Hash(BEGIN(hashRand), END(hashRand));
6494 multimap<uint256, CNode*> mapMix;
6495 BOOST_FOREACH(CNode* pnode, vNodes)
6497 if (pnode->nVersion < CADDR_TIME_VERSION)
6499 unsigned int nPointer;
6500 memcpy(&nPointer, &pnode, sizeof(nPointer));
6501 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
6502 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6503 mapMix.insert(make_pair(hashKey, pnode));
6505 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
6506 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6507 ((*mi).second)->PushAddress(addr);
6510 // Do not store addresses outside our network
6512 vAddrOk.push_back(addr);
6514 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
6515 if (vAddr.size() < 1000)
6516 pfrom->fGetAddr = false;
6517 if (pfrom->fOneShot)
6518 pfrom->fDisconnect = true;
6522 else if (strCommand == "inv")
6526 if (vInv.size() > MAX_INV_SZ)
6528 Misbehaving(pfrom->GetId(), 20);
6529 return error("message inv size() = %u", vInv.size());
6534 std::vector<CInv> vToFetch;
6536 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
6538 const CInv &inv = vInv[nInv];
6540 boost::this_thread::interruption_point();
6541 pfrom->AddInventoryKnown(inv);
6543 bool fAlreadyHave = AlreadyHave(inv);
6544 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
6546 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6549 if (inv.type == MSG_BLOCK) {
6550 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
6551 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
6552 // First request the headers preceding the announced block. In the normal fully-synced
6553 // case where a new block is announced that succeeds the current tip (no reorganization),
6554 // there are no such headers.
6555 // Secondly, and only when we are close to being synced, we request the announced block directly,
6556 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6557 // time the block arrives, the header chain leading up to it is already validated. Not
6558 // doing this will result in the received block being rejected as an orphan in case it is
6559 // not a direct successor.
6560 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
6561 CNodeState *nodestate = State(pfrom->GetId());
6562 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
6563 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
6564 vToFetch.push_back(inv);
6565 // Mark block as in flight already, even though the actual "getdata" message only goes out
6566 // later (within the same cs_main lock, though).
6567 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
6569 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
6573 // Track requests for our stuff
6574 GetMainSignals().Inventory(inv.hash);
6576 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6577 Misbehaving(pfrom->GetId(), 50);
6578 return error("send buffer size() = %u", pfrom->nSendSize);
6582 if (!vToFetch.empty())
6583 pfrom->PushMessage("getdata", vToFetch);
6587 else if (strCommand == "getdata")
6591 if (vInv.size() > MAX_INV_SZ)
6593 Misbehaving(pfrom->GetId(), 20);
6594 return error("message getdata size() = %u", vInv.size());
6597 if (fDebug || (vInv.size() != 1))
6598 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
6600 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
6601 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
6603 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6604 ProcessGetData(pfrom);
6608 else if (strCommand == "getblocks")
6610 CBlockLocator locator;
6612 vRecv >> locator >> hashStop;
6616 // Find the last block the caller has in the main chain
6617 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
6619 // Send the rest of the chain
6621 pindex = chainActive.Next(pindex);
6623 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
6624 for (; pindex; pindex = chainActive.Next(pindex))
6626 if (pindex->GetBlockHash() == hashStop)
6628 LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
6631 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
6634 // When this block is requested, we'll send an inv that'll
6635 // trigger the peer to getblocks the next batch of inventory.
6636 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
6637 pfrom->hashContinue = pindex->GetBlockHash();
6644 else if (strCommand == "getheaders")
6646 CBlockLocator locator;
6648 vRecv >> locator >> hashStop;
6652 if (IsInitialBlockDownload())
6655 CBlockIndex* pindex = NULL;
6656 if (locator.IsNull())
6658 // If locator is null, return the hashStop block
6659 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
6660 if (mi == mapBlockIndex.end())
6662 pindex = (*mi).second;
6666 // Find the last block the caller has in the main chain
6667 pindex = FindForkInGlobalIndex(chainActive, locator);
6669 pindex = chainActive.Next(pindex);
6672 // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6673 vector<CNetworkBlockHeader> vHeaders;
6674 int nLimit = MAX_HEADERS_RESULTS;
6675 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
6676 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) )// no need to ever suppress this
6678 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->nHeight : -1);
6679 for (; pindex; pindex = chainActive.Next(pindex))
6681 CBlockHeader h = pindex->GetBlockHeader();
6682 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6683 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
6684 vHeaders.push_back(pindex->GetBlockHeader());
6685 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6688 pfrom->PushMessage("headers", vHeaders);
6690 /*else if ( IS_KOMODO_NOTARY != 0 )
6692 static uint32_t counter;
6693 if ( counter++ < 3 )
6694 fprintf(stderr,"you can ignore redundant getheaders from peer.%d %d prev.%d\n",(int32_t)pfrom->id,(int32_t)(pindex ? pindex->nHeight : -1),pfrom->lasthdrsreq);
6699 else if (strCommand == "tx")
6701 vector<uint256> vWorkQueue;
6702 vector<uint256> vEraseQueue;
6706 CInv inv(MSG_TX, tx.GetHash());
6707 pfrom->AddInventoryKnown(inv);
6711 bool fMissingInputs = false;
6712 CValidationState state;
6714 pfrom->setAskFor.erase(inv.hash);
6715 mapAlreadyAskedFor.erase(inv);
6717 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
6719 mempool.check(pcoinsTip);
6720 RelayTransaction(tx);
6721 vWorkQueue.push_back(inv.hash);
6723 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
6724 pfrom->id, pfrom->cleanSubVer,
6725 tx.GetHash().ToString(),
6726 mempool.mapTx.size());
6728 // Recursively process any orphan transactions that depended on this one
6729 set<NodeId> setMisbehaving;
6730 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
6732 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6733 if (itByPrev == mapOrphanTransactionsByPrev.end())
6735 for (set<uint256>::iterator mi = itByPrev->second.begin();
6736 mi != itByPrev->second.end();
6739 const uint256& orphanHash = *mi;
6740 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6741 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
6742 bool fMissingInputs2 = false;
6743 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6744 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6745 // anyone relaying LegitTxX banned)
6746 CValidationState stateDummy;
6749 if (setMisbehaving.count(fromPeer))
6751 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
6753 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
6754 RelayTransaction(orphanTx);
6755 vWorkQueue.push_back(orphanHash);
6756 vEraseQueue.push_back(orphanHash);
6758 else if (!fMissingInputs2)
6761 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6763 // Punish peer that gave us an invalid orphan tx
6764 Misbehaving(fromPeer, nDos);
6765 setMisbehaving.insert(fromPeer);
6766 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6768 // Has inputs but not accepted to mempool
6769 // Probably non-standard or insufficient fee/priority
6770 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
6771 vEraseQueue.push_back(orphanHash);
6772 assert(recentRejects);
6773 recentRejects->insert(orphanHash);
6775 mempool.check(pcoinsTip);
6779 BOOST_FOREACH(uint256 hash, vEraseQueue)
6780 EraseOrphanTx(hash);
6782 // TODO: currently, prohibit joinsplits from entering mapOrphans
6783 else if (fMissingInputs && tx.vjoinsplit.size() == 0)
6785 AddOrphanTx(tx, pfrom->GetId());
6787 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
6788 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6789 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
6791 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
6793 assert(recentRejects);
6794 recentRejects->insert(tx.GetHash());
6796 if (pfrom->fWhitelisted) {
6797 // Always relay transactions received from whitelisted peers, even
6798 // if they were already in the mempool or rejected from it due
6799 // to policy, allowing the node to function as a gateway for
6800 // nodes hidden behind it.
6802 // Never relay transactions that we would assign a non-zero DoS
6803 // score for, as we expect peers to do the same with us in that
6806 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6807 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6808 RelayTransaction(tx);
6810 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
6811 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
6816 if (state.IsInvalid(nDoS))
6818 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
6819 pfrom->id, pfrom->cleanSubVer,
6820 state.GetRejectReason());
6821 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6822 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6824 Misbehaving(pfrom->GetId(), nDoS);
6828 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6830 std::vector<CBlockHeader> headers;
6832 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6833 unsigned int nCount = ReadCompactSize(vRecv);
6834 if (nCount > MAX_HEADERS_RESULTS) {
6835 Misbehaving(pfrom->GetId(), 20);
6836 return error("headers message size = %u", nCount);
6838 headers.resize(nCount);
6839 for (unsigned int n = 0; n < nCount; n++) {
6840 vRecv >> headers[n];
6841 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6847 // Nothing interesting. Stop asking this peers for more headers.
6851 CBlockIndex *pindexLast = NULL;
6852 BOOST_FOREACH(const CBlockHeader& header, headers) {
6853 //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6854 //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
6856 CValidationState state;
6857 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6858 Misbehaving(pfrom->GetId(), 20);
6859 return error("non-continuous headers sequence");
6861 int32_t futureblock;
6862 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
6864 if (state.IsInvalid(nDoS) && futureblock == 0)
6866 if (nDoS > 0 && futureblock == 0)
6867 Misbehaving(pfrom->GetId(), nDoS/nDoS);
6868 return error("invalid header received");
6874 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
6876 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6877 // Headers message had its maximum size; the peer may have more headers.
6878 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6879 // from there instead.
6880 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->nHeight != pfrom->sendhdrsreq )
6882 pfrom->sendhdrsreq = (int32_t)pindexLast->nHeight;
6883 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
6884 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6891 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
6896 CInv inv(MSG_BLOCK, block.GetHash());
6897 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
6899 pfrom->AddInventoryKnown(inv);
6901 CValidationState state;
6902 // Process all blocks from whitelisted peers, even if not requested,
6903 // unless we're still syncing with the network.
6904 // Such an unrequested block may still be processed, subject to the
6905 // conditions in AcceptBlock().
6906 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
6907 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
6909 if (state.IsInvalid(nDoS)) {
6910 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
6911 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
6914 Misbehaving(pfrom->GetId(), nDoS);
6921 // This asymmetric behavior for inbound and outbound connections was introduced
6922 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
6923 // to users' AddrMan and later request them by sending getaddr messages.
6924 // Making nodes which are behind NAT and can only make outgoing connections ignore
6925 // the getaddr message mitigates the attack.
6926 else if ((strCommand == "getaddr") && (pfrom->fInbound))
6928 // Only send one GetAddr response per connection to reduce resource waste
6929 // and discourage addr stamping of INV announcements.
6930 if (pfrom->fSentAddr) {
6931 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6934 pfrom->fSentAddr = true;
6936 pfrom->vAddrToSend.clear();
6937 vector<CAddress> vAddr = addrman.GetAddr();
6938 BOOST_FOREACH(const CAddress &addr, vAddr)
6939 pfrom->PushAddress(addr);
6943 else if (strCommand == "mempool")
6945 LOCK2(cs_main, pfrom->cs_filter);
6947 std::vector<uint256> vtxid;
6948 mempool.queryHashes(vtxid);
6950 BOOST_FOREACH(uint256& hash, vtxid) {
6951 CInv inv(MSG_TX, hash);
6952 if (pfrom->pfilter) {
6954 bool fInMemPool = mempool.lookup(hash, tx);
6955 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
6956 if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue;
6958 vInv.push_back(inv);
6959 if (vInv.size() == MAX_INV_SZ) {
6960 pfrom->PushMessage("inv", vInv);
6964 if (vInv.size() > 0)
6965 pfrom->PushMessage("inv", vInv);
6969 else if (strCommand == "ping")
6971 if (pfrom->nVersion > BIP0031_VERSION)
6975 // Echo the message back with the nonce. This allows for two useful features:
6977 // 1) A remote node can quickly check if the connection is operational
6978 // 2) Remote nodes can measure the latency of the network thread. If this node
6979 // is overloaded it won't respond to pings quickly and the remote node can
6980 // avoid sending us more work, like chain download requests.
6982 // The nonce stops the remote getting confused between different pings: without
6983 // it, if the remote node sends a ping once per second and this node takes 5
6984 // seconds to respond to each, the 5th ping the remote sends would appear to
6985 // return very quickly.
6986 pfrom->PushMessage("pong", nonce);
6991 else if (strCommand == "pong")
6993 int64_t pingUsecEnd = nTimeReceived;
6995 size_t nAvail = vRecv.in_avail();
6996 bool bPingFinished = false;
6997 std::string sProblem;
6999 if (nAvail >= sizeof(nonce)) {
7002 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
7003 if (pfrom->nPingNonceSent != 0) {
7004 if (nonce == pfrom->nPingNonceSent) {
7005 // Matching pong received, this ping is no longer outstanding
7006 bPingFinished = true;
7007 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
7008 if (pingUsecTime > 0) {
7009 // Successful ping time measurement, replace previous
7010 pfrom->nPingUsecTime = pingUsecTime;
7011 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
7013 // This should never happen
7014 sProblem = "Timing mishap";
7017 // Nonce mismatches are normal when pings are overlapping
7018 sProblem = "Nonce mismatch";
7020 // This is most likely a bug in another implementation somewhere; cancel this ping
7021 bPingFinished = true;
7022 sProblem = "Nonce zero";
7026 sProblem = "Unsolicited pong without ping";
7029 // This is most likely a bug in another implementation somewhere; cancel this ping
7030 bPingFinished = true;
7031 sProblem = "Short payload";
7034 if (!(sProblem.empty())) {
7035 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
7039 pfrom->nPingNonceSent,
7043 if (bPingFinished) {
7044 pfrom->nPingNonceSent = 0;
7049 else if (fAlerts && strCommand == "alert")
7054 uint256 alertHash = alert.GetHash();
7055 if (pfrom->setKnown.count(alertHash) == 0)
7057 if (alert.ProcessAlert(Params().AlertKey()))
7060 pfrom->setKnown.insert(alertHash);
7063 BOOST_FOREACH(CNode* pnode, vNodes)
7064 alert.RelayTo(pnode);
7068 // Small DoS penalty so peers that send us lots of
7069 // duplicate/expired/invalid-signature/whatever alerts
7070 // eventually get banned.
7071 // This isn't a Misbehaving(100) (immediate ban) because the
7072 // peer might be an older or different implementation with
7073 // a different signature key, etc.
7074 Misbehaving(pfrom->GetId(), 10);
7079 else if (!(nLocalServices & NODE_BLOOM) &&
7080 (strCommand == "filterload" ||
7081 strCommand == "filteradd"))
7083 if (pfrom->nVersion >= NO_BLOOM_VERSION) {
7084 Misbehaving(pfrom->GetId(), 100);
7086 } else if (GetBoolArg("-enforcenodebloom", false)) {
7087 pfrom->fDisconnect = true;
7093 else if (strCommand == "filterload")
7095 CBloomFilter filter;
7098 if (!filter.IsWithinSizeConstraints())
7099 // There is no excuse for sending a too-large filter
7100 Misbehaving(pfrom->GetId(), 100);
7103 LOCK(pfrom->cs_filter);
7104 delete pfrom->pfilter;
7105 pfrom->pfilter = new CBloomFilter(filter);
7106 pfrom->pfilter->UpdateEmptyFull();
7108 pfrom->fRelayTxes = true;
7112 else if (strCommand == "filteradd")
7114 vector<unsigned char> vData;
7117 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
7118 // and thus, the maximum size any matched object can have) in a filteradd message
7119 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
7121 Misbehaving(pfrom->GetId(), 100);
7123 LOCK(pfrom->cs_filter);
7125 pfrom->pfilter->insert(vData);
7127 Misbehaving(pfrom->GetId(), 100);
7132 else if (strCommand == "filterclear")
7134 LOCK(pfrom->cs_filter);
7135 if (nLocalServices & NODE_BLOOM) {
7136 delete pfrom->pfilter;
7137 pfrom->pfilter = new CBloomFilter();
7139 pfrom->fRelayTxes = true;
7143 else if (strCommand == "reject")
7147 string strMsg; unsigned char ccode; string strReason;
7148 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
7151 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
7153 if (strMsg == "block" || strMsg == "tx")
7157 ss << ": hash " << hash.ToString();
7159 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
7160 } catch (const std::ios_base::failure&) {
7161 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
7162 LogPrint("net", "Unparseable reject message received\n");
7166 else if (strCommand == "notfound") {
7167 // We do not care about the NOTFOUND message, but logging an Unknown Command
7168 // message would be undesirable as we transmit it ourselves.
7172 // Ignore unknown commands for extensibility
7173 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
7181 // requires LOCK(cs_vRecvMsg)
7182 bool ProcessMessages(CNode* pfrom)
7185 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
7189 // (4) message start
7197 if (!pfrom->vRecvGetData.empty())
7198 ProcessGetData(pfrom);
7200 // this maintains the order of responses
7201 if (!pfrom->vRecvGetData.empty()) return fOk;
7203 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
7204 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
7205 // Don't bother if send buffer is too full to respond anyway
7206 if (pfrom->nSendSize >= SendBufferSize())
7210 CNetMessage& msg = *it;
7213 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
7214 // msg.hdr.nMessageSize, msg.vRecv.size(),
7215 // msg.complete() ? "Y" : "N");
7217 // end, if an incomplete message is found
7218 if (!msg.complete())
7221 // at this point, any failure means we can delete the current message
7224 // Scan for message start
7225 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
7226 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
7232 CMessageHeader& hdr = msg.hdr;
7233 if (!hdr.IsValid(Params().MessageStart()))
7235 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
7238 string strCommand = hdr.GetCommand();
7241 unsigned int nMessageSize = hdr.nMessageSize;
7244 CDataStream& vRecv = msg.vRecv;
7245 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
7246 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
7247 if (nChecksum != hdr.nChecksum)
7249 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
7250 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
7258 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
7259 boost::this_thread::interruption_point();
7261 catch (const std::ios_base::failure& e)
7263 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
7264 if (strstr(e.what(), "end of data"))
7266 // Allow exceptions from under-length message on vRecv
7267 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());
7269 else if (strstr(e.what(), "size too large"))
7271 // Allow exceptions from over-long size
7272 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
7276 //PrintExceptionContinue(&e, "ProcessMessages()");
7279 catch (const boost::thread_interrupted&) {
7282 catch (const std::exception& e) {
7283 PrintExceptionContinue(&e, "ProcessMessages()");
7285 PrintExceptionContinue(NULL, "ProcessMessages()");
7289 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
7294 // In case the connection got shut down, its receive buffer was wiped
7295 if (!pfrom->fDisconnect)
7296 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
7302 bool SendMessages(CNode* pto, bool fSendTrickle)
7304 const Consensus::Params& consensusParams = Params().GetConsensus();
7306 // Don't send anything until we get its version message
7307 if (pto->nVersion == 0)
7313 bool pingSend = false;
7314 if (pto->fPingQueued) {
7315 // RPC ping request by user
7318 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
7319 // Ping automatically sent as a latency probe & keepalive.
7324 while (nonce == 0) {
7325 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
7327 pto->fPingQueued = false;
7328 pto->nPingUsecStart = GetTimeMicros();
7329 if (pto->nVersion > BIP0031_VERSION) {
7330 pto->nPingNonceSent = nonce;
7331 pto->PushMessage("ping", nonce);
7333 // Peer is too old to support ping command with nonce, pong will never arrive.
7334 pto->nPingNonceSent = 0;
7335 pto->PushMessage("ping");
7339 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
7343 // Address refresh broadcast
7344 static int64_t nLastRebroadcast;
7345 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
7348 BOOST_FOREACH(CNode* pnode, vNodes)
7350 // Periodically clear addrKnown to allow refresh broadcasts
7351 if (nLastRebroadcast)
7352 pnode->addrKnown.reset();
7354 // Rebroadcast our address
7355 AdvertizeLocal(pnode);
7357 if (!vNodes.empty())
7358 nLastRebroadcast = GetTime();
7366 vector<CAddress> vAddr;
7367 vAddr.reserve(pto->vAddrToSend.size());
7368 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
7370 if (!pto->addrKnown.contains(addr.GetKey()))
7372 pto->addrKnown.insert(addr.GetKey());
7373 vAddr.push_back(addr);
7374 // receiver rejects addr messages larger than 1000
7375 if (vAddr.size() >= 1000)
7377 pto->PushMessage("addr", vAddr);
7382 pto->vAddrToSend.clear();
7384 pto->PushMessage("addr", vAddr);
7387 CNodeState &state = *State(pto->GetId());
7388 if (state.fShouldBan) {
7389 if (pto->fWhitelisted)
7390 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
7392 pto->fDisconnect = true;
7393 if (pto->addr.IsLocal())
7394 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
7397 CNode::Ban(pto->addr);
7400 state.fShouldBan = false;
7403 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
7404 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
7405 state.rejects.clear();
7408 if (pindexBestHeader == NULL)
7409 pindexBestHeader = chainActive.Tip();
7410 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.
7411 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
7412 // Only actively request headers from a single peer, unless we're close to today.
7413 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
7414 state.fSyncStarted = true;
7416 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
7417 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
7418 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
7422 // Resend wallet transactions that haven't gotten in a block yet
7423 // Except during reindex, importing and IBD, when old wallet
7424 // transactions become unconfirmed and spams other nodes.
7425 if (!fReindex && !fImporting && !IsInitialBlockDownload())
7427 GetMainSignals().Broadcast(nTimeBestReceived);
7431 // Message: inventory
7434 vector<CInv> vInvWait;
7436 LOCK(pto->cs_inventory);
7437 vInv.reserve(pto->vInventoryToSend.size());
7438 vInvWait.reserve(pto->vInventoryToSend.size());
7439 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
7441 if (pto->setInventoryKnown.count(inv))
7444 // trickle out tx inv to protect privacy
7445 if (inv.type == MSG_TX && !fSendTrickle)
7447 // 1/4 of tx invs blast to all immediately
7448 static uint256 hashSalt;
7449 if (hashSalt.IsNull())
7450 hashSalt = GetRandHash();
7451 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
7452 hashRand = Hash(BEGIN(hashRand), END(hashRand));
7453 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
7457 vInvWait.push_back(inv);
7462 // returns true if wasn't already contained in the set
7463 if (pto->setInventoryKnown.insert(inv).second)
7465 vInv.push_back(inv);
7466 if (vInv.size() >= 1000)
7468 pto->PushMessage("inv", vInv);
7473 pto->vInventoryToSend = vInvWait;
7476 pto->PushMessage("inv", vInv);
7478 // Detect whether we're stalling
7479 int64_t nNow = GetTimeMicros();
7480 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7481 // Stalling only triggers when the block download window cannot move. During normal steady state,
7482 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7483 // should only happen during initial block download.
7484 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
7485 pto->fDisconnect = true;
7487 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
7488 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7489 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7490 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
7491 // to unreasonably increase our timeout.
7492 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7493 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7494 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7495 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7496 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7497 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7498 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
7499 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
7500 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7501 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7502 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7504 if (queuedBlock.nTimeDisconnect < nNow) {
7505 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7506 pto->fDisconnect = true;
7511 // Message: getdata (blocks)
7513 static uint256 zero;
7514 vector<CInv> vGetData;
7515 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
7516 vector<CBlockIndex*> vToDownload;
7517 NodeId staller = -1;
7518 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7519 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7520 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
7521 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
7522 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
7523 pindex->nHeight, pto->id);
7525 if (state.nBlocksInFlight == 0 && staller != -1) {
7526 if (State(staller)->nStallingSince == 0) {
7527 State(staller)->nStallingSince = nNow;
7528 LogPrint("net", "Stall started peer=%d\n", staller);
7532 /*CBlockIndex *pindex;
7533 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
7535 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7536 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7537 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7538 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
7539 komodo_requestedcount++;
7540 if ( komodo_requestedcount > 16 )
7542 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7543 komodo_requestedcount = 0;
7548 // Message: getdata (non-blocks)
7550 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
7552 const CInv& inv = (*pto->mapAskFor.begin()).second;
7553 if (!AlreadyHave(inv))
7556 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
7557 vGetData.push_back(inv);
7558 if (vGetData.size() >= 1000)
7560 pto->PushMessage("getdata", vGetData);
7564 //If we're not going to ask, don't expect a response.
7565 pto->setAskFor.erase(inv.hash);
7567 pto->mapAskFor.erase(pto->mapAskFor.begin());
7569 if (!vGetData.empty())
7570 pto->PushMessage("getdata", vGetData);
7576 std::string CBlockFileInfo::ToString() const {
7577 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));
7582 static class CMainCleanup
7588 BlockMap::iterator it1 = mapBlockIndex.begin();
7589 for (; it1 != mapBlockIndex.end(); it1++)
7590 delete (*it1).second;
7591 mapBlockIndex.clear();
7593 // orphan transactions
7594 mapOrphanTransactions.clear();
7595 mapOrphanTransactionsByPrev.clear();
7597 } instance_of_cmaincleanup;
7599 extern "C" const char* getDataDir()
7601 return GetDataDir().string().c_str();
7605 // Set default values of new CMutableTransaction based on consensus rules at given height.
7606 CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7608 CMutableTransaction mtx;
7610 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7611 if (isOverwintered) {
7612 mtx.fOverwintered = true;
7613 mtx.nExpiryHeight = nHeight + expiryDelta;
7615 if (NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING)) {
7616 mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
7617 mtx.nVersion = SAPLING_TX_VERSION;
7619 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7620 mtx.nVersion = OVERWINTER_TX_VERSION;
7621 mtx.nExpiryHeight = std::min(
7623 static_cast<uint32_t>(consensusParams.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight - 1));