]> Git Repo - VerusCoin.git/blame - src/main.cpp
Updating CI config
[VerusCoin.git] / src / main.cpp
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
c5b390b6 3// Distributed under the MIT software license, see the accompanying
3a25a2b9
F
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
51ed9ec9 6#include "main.h"
319b1160 7
320f2cc7
SB
8#include "sodium.h"
9
51ed9ec9 10#include "addrman.h"
f35c6c4f 11#include "alert.h"
26c16d9d 12#include "arith_uint256.h"
20c3ac51 13#include "importcoin.h"
319b1160 14#include "chainparams.h"
eb5fff9e 15#include "checkpoints.h"
319b1160 16#include "checkqueue.h"
9e851450 17#include "consensus/upgrades.h"
da29ecbc 18#include "consensus/validation.h"
5b3bc971 19#include "deprecation.h"
edd309e5 20#include "init.h"
afd4b94b 21#include "merkleblock.h"
a6df7ab5 22#include "metrics.h"
20c3ac51 23#include "notarisationdb.h"
319b1160 24#include "net.h"
df852d2b 25#include "pow.h"
0cb91a8d 26#include "script/interpreter.h"
319b1160
GA
27#include "txdb.h"
28#include "txmempool.h"
ed6d0b5f 29#include "ui_interface.h"
937ba572 30#include "undo.h"
51ed9ec9 31#include "util.h"
217a5c92 32#include "utilmoneystr.h"
26c16d9d 33#include "validationinterface.h"
9ddb6ad0 34#include "wallet/asyncrpcoperation_sendmany.h"
06c19063 35#include "wallet/asyncrpcoperation_shieldcoinbase.h"
51ed9ec9 36
6c8e1cdf 37#include <cstring>
358ce266 38#include <sstream>
6c8e1cdf 39#include <unordered_map>
51ed9ec9
BD
40
41#include <boost/algorithm/string/replace.hpp>
42#include <boost/filesystem.hpp>
43#include <boost/filesystem/fstream.hpp>
36cba8f1 44#include <boost/math/distributions/poisson.hpp>
ad49c256 45#include <boost/thread.hpp>
7c68cc07 46#include <boost/static_assert.hpp>
0a61b0df 47
4dc5eb05 48using namespace std;
0a61b0df 49
9b59e3bd 50#if defined(NDEBUG)
7662d72b 51# error "Zcash cannot be compiled without assertions."
9b59e3bd
GM
52#endif
53
d27afb07 54
c5b390b6
MF
55/**
56 * Global state
57 */
0a61b0df 58
59CCriticalSection cs_main;
8dcf7f94 60extern uint8_t NOTARY_PUBKEY33[33];
99ba67a0 61extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC;
03e2210d 62int32_t KOMODO_NEWBLOCKS;
9464ac21 63int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block);
395f10cf 64void komodo_broadcast(CBlock *pblock,int32_t limit);
0a61b0df 65
145d5be8 66BlockMap mapBlockIndex;
4c6d41b8 67CChain chainActive;
ad6e6017 68CBlockIndex *pindexBestHeader = NULL;
51ed9ec9 69int64_t nTimeBestReceived = 0;
ff6a7af1
LD
70CWaitableCriticalSection csBestBlock;
71CConditionVariable cvBlockChange;
f9cae832 72int nScriptCheckThreads = 0;
1f015f6a 73bool fExperimentalMode = false;
66b02c93 74bool fImporting = false;
7fea4846 75bool fReindex = false;
2d1fa42e 76bool fTxIndex = false;
8b78a819
T
77bool fAddressIndex = false;
78bool fTimestampIndex = false;
79bool fSpentIndex = false;
f9ec3f0f 80bool fHavePruned = false;
81bool fPruneMode = false;
3da434a2 82bool fIsBareMultisigStd = true;
3fcfbc8a 83bool fCheckBlockIndex = false;
a8cdaf5c 84bool fCheckpointsEnabled = true;
d212ba32 85bool fCoinbaseEnforcedProtectionEnabled = true;
fc684ad8 86size_t nCoinCacheUsage = 5000 * 300;
f9ec3f0f 87uint64_t nPruneTarget = 0;
4d9c7fe6 88bool fAlerts = DEFAULT_ALERTS;
0a61b0df 89
9bb37bf0
JG
90unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA;
91
037b4f14 92/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
ba0625f2 93CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
13fc83c7
GA
94
95CTxMemPool mempool(::minRelayTxFee);
000dc551 96
c74332c6
GA
97struct COrphanTx {
98 CTransaction tx;
99 NodeId fromPeer;
100};
72b25b0f
CF
101map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
102map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
103void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
0a61b0df 104
9dcd524f
PW
105/**
106 * Returns true if there are nRequired or more blocks of minVersion or above
51aa2492 107 * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
9dcd524f 108 */
51aa2492 109static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
3fcfbc8a 110static void CheckBlockIndex();
9dcd524f 111
c5b390b6 112/** Constant stuff for coinbase transactions we create: */
7bf8b7c2 113CScript COINBASE_FLAGS;
0a61b0df 114
1a321777 115const string strMessageMagic = "Komodo Signed Message:\n";
2bc4fd60 116
caca6aa4
PW
117// Internal stuff
118namespace {
8d655683 119
6b29ccc9
B
120 struct CBlockIndexWorkComparator
121 {
3fcfbc8a 122 bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
6b29ccc9
B
123 // First sort by most total work, ...
124 if (pa->nChainWork > pb->nChainWork) return false;
125 if (pa->nChainWork < pb->nChainWork) return true;
8d655683 126
6b29ccc9
B
127 // ... then by earliest time received, ...
128 if (pa->nSequenceId < pb->nSequenceId) return false;
129 if (pa->nSequenceId > pb->nSequenceId) return true;
8d655683 130
6b29ccc9
B
131 // Use pointer address as tie breaker (should only happen with blocks
132 // loaded from disk, as those all have id 0).
133 if (pa < pb) return false;
134 if (pa > pb) return true;
8d655683 135
6b29ccc9
B
136 // Identical blocks.
137 return false;
138 }
139 };
8d655683 140
6b29ccc9 141 CBlockIndex *pindexBestInvalid;
8d655683 142
c5b390b6 143 /**
3fcfbc8a 144 * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
f9ec3f0f 145 * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
146 * missing the data for the block.
c5b390b6 147 */
e17bd583 148 set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
c5b390b6 149 /** Number of nodes with fSyncStarted. */
341735eb 150 int nSyncStarted = 0;
f9ec3f0f 151 /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
8d655683 152 * Pruned nodes may have entries where B is missing data.
153 */
341735eb 154 multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
8d655683 155
6b29ccc9 156 CCriticalSection cs_LastBlockFile;
ed6d1a2c 157 std::vector<CBlockFileInfo> vinfoBlockFile;
6b29ccc9 158 int nLastBlockFile = 0;
f9ec3f0f 159 /** Global flag to indicate we should check to see if there are
160 * block/undo files that should be deleted. Set on startup
161 * or if we allocate more file space when we're in prune mode
162 */
163 bool fCheckForPruning = false;
8d655683 164
c5b390b6
MF
165 /**
166 * Every received block is assigned a unique and increasing identifier, so we
167 * know which one to give priority in case of a fork.
168 */
6b29ccc9 169 CCriticalSection cs_nBlockSequenceId;
c5b390b6 170 /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
6b29ccc9 171 uint32_t nBlockSequenceId = 1;
8d655683 172
c5b390b6 173 /**
b05a89b2
LD
174 * Sources of received blocks, saved to be able to send them reject
175 * messages or ban them when processing happens afterwards. Protected by
176 * cs_main.
c5b390b6 177 */
6b29ccc9 178 map<uint256, NodeId> mapBlockSource;
8d655683 179
ec9b6c33
PT
180 /**
181 * Filter for transactions that were recently rejected by
182 * AcceptToMemoryPool. These are not rerequested until the chain tip
183 * changes, at which point the entire filter is reset. Protected by
184 * cs_main.
185 *
186 * Without this filter we'd be re-requesting txs from each of our peers,
187 * increasing bandwidth consumption considerably. For instance, with 100
188 * peers, half of which relay a tx we don't accept, that might be a 50x
189 * bandwidth increase. A flooding attacker attempting to roll-over the
190 * filter using minimum-sized, 60byte, transactions might manage to send
191 * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
192 * two minute window to send invs to us.
193 *
194 * Decreasing the false positive rate is fairly cheap, so we pick one in a
195 * million to make it highly unlikely for users to have issues with this
196 * filter.
197 *
198 * Memory used: 1.7MB
199 */
200 boost::scoped_ptr<CRollingBloomFilter> recentRejects;
201 uint256 hashRecentRejectsChainTip;
8d655683 202
c5b390b6 203 /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
6b29ccc9
B
204 struct QueuedBlock {
205 uint256 hash;
c5b390b6
MF
206 CBlockIndex *pindex; //! Optional.
207 int64_t nTime; //! Time of "getdata" request in microseconds.
91613034 208 bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
8ba7f842 209 int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
6b29ccc9
B
210 };
211 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
8d655683 212
91613034
PW
213 /** Number of blocks in flight with validated headers. */
214 int nQueuedValidatedHeaders = 0;
8d655683 215
c5b390b6 216 /** Number of preferable block download peers. */
b4ee0bdd 217 int nPreferredDownload = 0;
8d655683 218
c5b390b6 219 /** Dirty block index entries. */
51ce901a 220 set<CBlockIndex*> setDirtyBlockIndex;
8d655683 221
c5b390b6 222 /** Dirty block file entries. */
51ce901a 223 set<int> setDirtyFileInfo;
e10dcf27 224} // anon namespace
0a61b0df 225
501da250
EL
226//////////////////////////////////////////////////////////////////////////////
227//
228// Registration of network node signals.
229//
230
b2864d2f 231namespace {
8d655683 232
233 struct CBlockReject {
234 unsigned char chRejectCode;
235 string strRejectReason;
236 uint256 hashBlock;
237 };
238
239 /**
240 * Maintain validation-specific state about nodes, protected by cs_main, instead
241 * by CNode's own locks. This simplifies asynchronous operation, where
242 * processing of incoming data is done after the ProcessMessage call returns,
243 * and we're no longer holding the node's locks.
244 */
245 struct CNodeState {
246 //! The peer's address
247 CService address;
248 //! Whether we have a fully established connection.
249 bool fCurrentlyConnected;
250 //! Accumulated misbehaviour score for this peer.
251 int nMisbehavior;
252 //! Whether this peer should be disconnected and banned (unless whitelisted).
253 bool fShouldBan;
254 //! String name of this peer (debugging/logging purposes).
255 std::string name;
256 //! List of asynchronously-determined block rejections to notify this peer about.
257 std::vector<CBlockReject> rejects;
258 //! The best known block we know this peer has announced.
259 CBlockIndex *pindexBestKnownBlock;
260 //! The hash of the last unknown block this peer has announced.
261 uint256 hashLastUnknownBlock;
262 //! The last full block we both have.
263 CBlockIndex *pindexLastCommonBlock;
264 //! Whether we've started headers synchronization with this peer.
265 bool fSyncStarted;
266 //! Since when we're stalling block download progress (in microseconds), or 0.
267 int64_t nStallingSince;
268 list<QueuedBlock> vBlocksInFlight;
269 int nBlocksInFlight;
270 int nBlocksInFlightValidHeaders;
271 //! Whether we consider this a preferred download peer.
272 bool fPreferredDownload;
273
274 CNodeState() {
275 fCurrentlyConnected = false;
276 nMisbehavior = 0;
277 fShouldBan = false;
278 pindexBestKnownBlock = NULL;
279 hashLastUnknownBlock.SetNull();
280 pindexLastCommonBlock = NULL;
281 fSyncStarted = false;
282 nStallingSince = 0;
283 nBlocksInFlight = 0;
284 nBlocksInFlightValidHeaders = 0;
285 fPreferredDownload = false;
286 }
287 };
288
289 /** Map maintaining per-node state. Requires cs_main. */
290 map<NodeId, CNodeState> mapNodeState;
291
292 // Requires cs_main.
293 CNodeState *State(NodeId pnode) {
294 map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
295 if (it == mapNodeState.end())
296 return NULL;
297 return &it->second;
b2864d2f 298 }
8d655683 299
300 int GetHeight()
301 {
302 LOCK(cs_main);
303 return chainActive.Height();
9c273790 304 }
14aa6cc0 305
8d655683 306 void UpdatePreferredDownload(CNode* node, CNodeState* state)
307 {
308 nPreferredDownload -= state->fPreferredDownload;
309
310 // Whether this node should be marked as a preferred download node.
311 state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
312
313 nPreferredDownload += state->fPreferredDownload;
314 }
14aa6cc0 315
8d655683 316 // Returns time at which to timeout block request (nTime in microseconds)
317 int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
318 {
319 return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
f59d8f0b 320 }
8d655683 321
322 void InitializeNode(NodeId nodeid, const CNode *pnode) {
323 LOCK(cs_main);
324 CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
325 state.name = pnode->addrName;
326 state.address = pnode->addr;
327 }
328
329 void FinalizeNode(NodeId nodeid) {
330 LOCK(cs_main);
331 CNodeState *state = State(nodeid);
332
333 if (state->fSyncStarted)
334 nSyncStarted--;
335
336 if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
337 AddressCurrentlyConnected(state->address);
aa815647 338 }
8d655683 339
340 BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
341 mapBlocksInFlight.erase(entry.hash);
342 EraseOrphansFor(nodeid);
343 nPreferredDownload -= state->fPreferredDownload;
344
345 mapNodeState.erase(nodeid);
aa815647 346 }
8d655683 347
348 void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
0a0ec219 349 {
8d655683 350 /* int expired = pool.Expire(GetTime() - age);
351 if (expired != 0)
352 LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
353
354 std::vector<uint256> vNoSpendsRemaining;
355 pool.TrimToSize(limit, &vNoSpendsRemaining);
356 BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining)
357 pcoinsTip->Uncache(removed);*/
aa815647 358 }
8d655683 359
360 // Requires cs_main.
361 // Returns a bool indicating whether we requested this block.
362 bool MarkBlockAsReceived(const uint256& hash) {
363 map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
364 if (itInFlight != mapBlocksInFlight.end()) {
365 CNodeState *state = State(itInFlight->second.first);
366 nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
367 state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
368 state->vBlocksInFlight.erase(itInFlight->second.second);
369 state->nBlocksInFlight--;
370 state->nStallingSince = 0;
371 mapBlocksInFlight.erase(itInFlight);
372 return true;
373 }
374 return false;
341735eb 375 }
8d655683 376
377 // Requires cs_main.
378 void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
379 CNodeState *state = State(nodeid);
380 assert(state != NULL);
381
382 // Make sure it's not listed somewhere already.
383 MarkBlockAsReceived(hash);
384
385 int64_t nNow = GetTimeMicros();
386 QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
387 nQueuedValidatedHeaders += newentry.fValidatedHeaders;
388 list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
389 state->nBlocksInFlight++;
390 state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
391 mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
341735eb 392 }
8d655683 393
394 /** Check whether the last unknown block a peer advertized is not yet known. */
395 void ProcessBlockAvailability(NodeId nodeid) {
396 CNodeState *state = State(nodeid);
397 assert(state != NULL);
398
399 if (!state->hashLastUnknownBlock.IsNull()) {
400 BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
401 if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0)
402 {
403 if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
404 state->pindexBestKnownBlock = itOld->second;
405 state->hashLastUnknownBlock.SetNull();
406 }
407 }
341735eb 408 }
8d655683 409
410 /** Update tracking information about which blocks a peer is assumed to have. */
411 void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
412 CNodeState *state = State(nodeid);
413 assert(state != NULL);
414
415 /*ProcessBlockAvailability(nodeid);
416
417 BlockMap::iterator it = mapBlockIndex.find(hash);
418 if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
419 // An actually better block was announced.
420 if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
421 state->pindexBestKnownBlock = it->second;
422 } else*/
423 {
424 // An unknown block was announced; just assume that the latest one is the best one.
425 state->hashLastUnknownBlock = hash;
426 }
341735eb 427 }
8d655683 428
429 /** Find the last common ancestor two blocks have.
430 * Both pa and pb must be non-NULL. */
431 CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
432 if (pa->nHeight > pb->nHeight) {
433 pa = pa->GetAncestor(pb->nHeight);
434 } else if (pb->nHeight > pa->nHeight) {
435 pb = pb->GetAncestor(pa->nHeight);
436 }
437
438 while (pa != pb && pa && pb) {
439 pa = pa->pprev;
440 pb = pb->pprev;
441 }
442
443 // Eventually all chain branches meet at the genesis block.
444 assert(pa == pb);
445 return pa;
446 }
447
448 /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
449 * at most count entries. */
450 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
451 if (count == 0)
452 return;
453
454 vBlocks.reserve(vBlocks.size() + count);
455 CNodeState *state = State(nodeid);
456 assert(state != NULL);
457
458 // Make sure pindexBestKnownBlock is up to date, we'll need it.
459 ProcessBlockAvailability(nodeid);
460
461 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
462 // This peer has nothing interesting.
463 return;
464 }
465
466 if (state->pindexLastCommonBlock == NULL) {
467 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
468 // Guessing wrong in either direction is not a problem.
469 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
470 }
471
472 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
473 // of its current tip anymore. Go back enough to fix that.
474 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
475 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
476 return;
477
478 std::vector<CBlockIndex*> vToFetch;
479 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
480 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
481 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
482 // download that next block if the window were 1 larger.
483 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
484 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
485 NodeId waitingfor = -1;
486 while (pindexWalk->nHeight < nMaxHeight) {
487 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
488 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
489 // as iterating over ~100 CBlockIndex* entries anyway.
490 int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
491 vToFetch.resize(nToFetch);
492 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
493 vToFetch[nToFetch - 1] = pindexWalk;
494 for (unsigned int i = nToFetch - 1; i > 0; i--) {
495 vToFetch[i - 1] = vToFetch[i]->pprev;
34970223 496 }
8d655683 497
498 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
499 // are not yet downloaded and not in flight to vBlocks. In the meantime, update
500 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
501 // already part of our chain (and therefore don't need it even if pruned).
502 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
503 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
504 // We consider the chain that this peer is on invalid.
341735eb
PW
505 return;
506 }
8d655683 507 if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
508 if (pindex->nChainTx)
509 state->pindexLastCommonBlock = pindex;
510 } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
511 // The block is not already downloaded, and not yet in flight.
512 if (pindex->nHeight > nWindowEnd) {
513 // We reached the end of the window.
514 if (vBlocks.size() == 0 && waitingfor != nodeid) {
515 // We aren't able to fetch anything, but we would be if the download window was one larger.
516 nodeStaller = waitingfor;
517 }
518 return;
519 }
520 vBlocks.push_back(pindex);
521 if (vBlocks.size() == count) {
522 return;
523 }
524 } else if (waitingfor == -1) {
525 // This is the first already-in-flight block.
526 waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
341735eb 527 }
341735eb
PW
528 }
529 }
530 }
8d655683 531
e10dcf27 532} // anon namespace
b2864d2f
PW
533
534bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
535 LOCK(cs_main);
536 CNodeState *state = State(nodeid);
537 if (state == NULL)
538 return false;
539 stats.nMisbehavior = state->nMisbehavior;
aa815647 540 stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
ad6e6017
PW
541 stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
542 BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
543 if (queue.pindex)
544 stats.vHeightInFlight.push_back(queue.pindex->nHeight);
545 }
b2864d2f
PW
546 return true;
547}
548
501da250
EL
549void RegisterNodeSignals(CNodeSignals& nodeSignals)
550{
4c6d41b8 551 nodeSignals.GetHeight.connect(&GetHeight);
501da250
EL
552 nodeSignals.ProcessMessages.connect(&ProcessMessages);
553 nodeSignals.SendMessages.connect(&SendMessages);
b2864d2f
PW
554 nodeSignals.InitializeNode.connect(&InitializeNode);
555 nodeSignals.FinalizeNode.connect(&FinalizeNode);
501da250 556}
64c7ee7e 557
501da250
EL
558void UnregisterNodeSignals(CNodeSignals& nodeSignals)
559{
4c6d41b8 560 nodeSignals.GetHeight.disconnect(&GetHeight);
501da250
EL
561 nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
562 nodeSignals.SendMessages.disconnect(&SendMessages);
b2864d2f
PW
563 nodeSignals.InitializeNode.disconnect(&InitializeNode);
564 nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
501da250 565}
64c7ee7e 566
6db83db3 567CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
568{
70e7fba0 569 // Find the first block the caller has in the main chain
e4daecda 570 BOOST_FOREACH(const uint256& hash, locator.vHave) {
145d5be8 571 BlockMap::iterator mi = mapBlockIndex.find(hash);
e4d89f43 572 if (mi != mapBlockIndex.end())
70e7fba0
MH
573 {
574 CBlockIndex* pindex = (*mi).second;
43450135 575 if (pindex != 0 && chain.Contains(pindex))
70e7fba0 576 return pindex;
409c28a2 577 if (pindex != 0 && pindex->GetAncestor(chain.Height()) == chain.Tip()) {
89f20450
PW
578 return chain.Tip();
579 }
70e7fba0
MH
580 }
581 }
6db83db3 582 return chain.Genesis();
77339e5a
PW
583}
584
ae8bfd12 585CCoinsViewCache *pcoinsTip = NULL;
d979e6e3 586CBlockTreeDB *pblocktree = NULL;
b62d7030 587
588// Komodo globals
b62d7030 589
7637aa7f 590#define KOMODO_ZCASH
eab0d89c 591#include "komodo.h"
450cbb09 592
f1e1ea61 593UniValue komodo_snapshot(int top)
329d80d2 594{
9ef7fec1 595 LOCK(cs_main);
67d2e41b 596 int64_t total = -1;
92dc28a3 597 UniValue result(UniValue::VOBJ);
3eb535b8 598
cbce9f1f
DL
599 if (fAddressIndex) {
600 if ( pblocktree != 0 ) {
f1e1ea61 601 result = pblocktree->Snapshot(top);
cbce9f1f
DL
602 } else {
603 fprintf(stderr,"null pblocktree start with -addressindex=true\n");
604 }
605 } else {
606 fprintf(stderr,"getsnapshot requires -addressindex=true\n");
607 }
92dc28a3 608 return(result);
329d80d2 609}
610
0a61b0df 611//////////////////////////////////////////////////////////////////////////////
612//
613// mapOrphanTransactions
614//
615
72b25b0f 616bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
0a61b0df 617{
805344dc 618 uint256 hash = tx.GetHash();
0a61b0df 619 if (mapOrphanTransactions.count(hash))
77b99cf7 620 return false;
8d655683 621
77b99cf7
GA
622 // Ignore big transactions, to avoid a
623 // send-big-orphans memory exhaustion attack. If a peer has a legitimate
624 // large transaction with a missing parent then we assume
625 // it will rebroadcast it later, after the parent transaction(s)
626 // have been mined or received.
627 // 10,000 orphans, each of which is at most 5,000 bytes big is
628 // at most 500 megabytes of orphans:
e923e3ae 629 unsigned int sz = tx.GetSerializeSize(SER_NETWORK, tx.nVersion);
159bc481 630 if (sz > 5000)
77b99cf7 631 {
7d9d134b 632 LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
77b99cf7
GA
633 return false;
634 }
8d655683 635
c74332c6
GA
636 mapOrphanTransactions[hash].tx = tx;
637 mapOrphanTransactions[hash].fromPeer = peer;
223b6f1b 638 BOOST_FOREACH(const CTxIn& txin, tx.vin)
8d655683 639 mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
640
c74332c6
GA
641 LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
642 mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
77b99cf7 643 return true;
0a61b0df 644}
645
72b25b0f 646void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
0a61b0df 647{
c74332c6 648 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
89d91f6a 649 if (it == mapOrphanTransactions.end())
0a61b0df 650 return;
c74332c6 651 BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
0a61b0df 652 {
89d91f6a 653 map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
def2fdb4
GA
654 if (itPrev == mapOrphanTransactionsByPrev.end())
655 continue;
89d91f6a
WL
656 itPrev->second.erase(hash);
657 if (itPrev->second.empty())
658 mapOrphanTransactionsByPrev.erase(itPrev);
0a61b0df 659 }
89d91f6a 660 mapOrphanTransactions.erase(it);
0a61b0df 661}
662
c74332c6
GA
663void EraseOrphansFor(NodeId peer)
664{
665 int nErased = 0;
666 map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
667 while (iter != mapOrphanTransactions.end())
668 {
669 map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
670 if (maybeErase->second.fromPeer == peer)
671 {
805344dc 672 EraseOrphanTx(maybeErase->second.tx.GetHash());
c74332c6
GA
673 ++nErased;
674 }
675 }
676 if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
677}
678
679
72b25b0f 680unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
142e6041 681{
7bd9c3a3 682 unsigned int nEvicted = 0;
142e6041
GA
683 while (mapOrphanTransactions.size() > nMaxOrphans)
684 {
685 // Evict a random orphan:
f718aedd 686 uint256 randomhash = GetRandHash();
c74332c6 687 map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
142e6041
GA
688 if (it == mapOrphanTransactions.end())
689 it = mapOrphanTransactions.begin();
8d655683 690 EraseOrphanTx(it->first);
691 ++nEvicted;
142e6041
GA
692 }
693 return nEvicted;
694}
0a61b0df 695
696
072099d7 697bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight)
000dc551 698{
072099d7 699 bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
8d655683 700
072099d7
S
701 if (isOverwinter) {
702 // Overwinter standard rules apply
703 if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) {
704 reason = "overwinter-version";
705 return false;
706 }
707 } else {
708 // Sprout standard rules apply
709 if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) {
710 reason = "version";
711 return false;
712 }
980bfe6e 713 }
8d655683 714
05df3fc6 715 BOOST_FOREACH(const CTxIn& txin, tx.vin)
e679ec96 716 {
4d79098a
PT
717 // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
718 // keys. (remember the 520 byte limit on redeemScript size) That works
675bcd58 719 // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
4d79098a
PT
720 // bytes of scriptSig, which we round off to 1650 bytes for some minor
721 // future-proofing. That's also enough to spend a 20-of-20
722 // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
723 // considered standard)
724 if (txin.scriptSig.size() > 1650) {
980bfe6e 725 reason = "scriptsig-size";
922e8e29 726 return false;
980bfe6e
JG
727 }
728 if (!txin.scriptSig.IsPushOnly()) {
729 reason = "scriptsig-not-pushonly";
922e8e29 730 return false;
87fe71e1 731 }
e679ec96 732 }
8d655683 733
9632af31 734 unsigned int v=0,nDataOut = 0;
a7934247 735 txnouttype whichType;
9632af31 736 BOOST_FOREACH(const CTxOut& txout, tx.vout)
737 {
cc0f93da 738 if (!::IsStandard(txout.scriptPubKey, whichType))
739 {
7a82f2fc 740 reason = "scriptpubkey";
cc0f93da 741 fprintf(stderr,">>>>>>>>>>>>>>> vout.%d nDataout.%d\n",v,nDataOut);
922e8e29 742 return false;
980bfe6e 743 }
9632af31 744
a7934247 745 if (whichType == TX_NULL_DATA)
cc0f93da 746 {
a7934247 747 nDataOut++;
7a82f2fc 748 //fprintf(stderr,"is OP_RETURN\n");
cc0f93da 749 }
3da434a2
JG
750 else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
751 reason = "bare-multisig";
752 return false;
b72f0608 753 } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) {
980bfe6e 754 reason = "dust";
65ce2156 755 return false;
980bfe6e 756 }
9632af31 757 v++;
65ce2156 758 }
8d655683 759
a7934247
JG
760 // only one OP_RETURN txout is permitted
761 if (nDataOut > 1) {
b34e88a8 762 reason = "multi-op-return";
a7934247
JG
763 return false;
764 }
8d655683 765
e679ec96
GA
766 return true;
767}
768
14aa6cc0 769bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
912af0a6 770{
b5284a65 771 int32_t i;
05df3fc6
EL
772 if (tx.nLockTime == 0)
773 return true;
fb50dd55 774 if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
775 return true;
05df3fc6 776 BOOST_FOREACH(const CTxIn& txin, tx.vin)
69988609 777 {
420b712a 778 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)) )
69988609 779 {
780
781 }
782 else if (!txin.IsFinal())
14512c96 783 {
60aee10d 784 //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime);
05df3fc6 785 return false;
14512c96 786 }
69988609 787 }
05df3fc6
EL
788 return true;
789}
790
9bb37bf0
JG
791bool IsExpiredTx(const CTransaction &tx, int nBlockHeight)
792{
793 if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) {
794 return false;
795 }
796 return static_cast<uint32_t>(nBlockHeight) > tx.nExpiryHeight;
797}
798
a1d3c6fb 799bool CheckFinalTx(const CTransaction &tx, int flags)
75a4d512
PT
800{
801 AssertLockHeld(cs_main);
8d655683 802
a1d3c6fb
MF
803 // By convention a negative value for flags indicates that the
804 // current network-enforced consensus rules should be used. In
805 // a future soft-fork scenario that would mean checking which
806 // rules would be enforced for the next block and setting the
807 // appropriate flags. At the present time no soft-forks are
808 // scheduled, so no flags are set.
809 flags = std::max(flags, 0);
8d655683 810
a1d3c6fb
MF
811 // CheckFinalTx() uses chainActive.Height()+1 to evaluate
812 // nLockTime because when IsFinalTx() is called within
813 // CBlock::AcceptBlock(), the height of the block *being*
814 // evaluated is what is used. Thus if we want to know if a
815 // transaction can be part of the *next* block, we need to call
816 // IsFinalTx() with one more than chainActive.Height().
817 const int nBlockHeight = chainActive.Height() + 1;
8d655683 818
a1d3c6fb
MF
819 // Timestamps on the other hand don't get any special treatment,
820 // because we can't know what timestamp the next block will have,
821 // and there aren't timestamp applications where it matters.
822 // However this changes once median past time-locks are enforced:
823 const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
8d655683 824 ? chainActive.Tip()->GetMedianTimePast()
825 : GetAdjustedTime();
826
14aa6cc0 827 return IsFinalTx(tx, nBlockHeight, nBlockTime);
75a4d512
PT
828}
829
c5b390b6
MF
830/**
831 * Check transaction inputs to mitigate two
832 * potential denial-of-service attacks:
db954a65 833 *
c5b390b6
MF
834 * 1. scriptSigs with extra data stuffed into them,
835 * not consumed by scriptPubKey (or P2SH script)
836 * 2. P2SH scripts with a crazy number of expensive
837 * CHECKSIG/CHECKMULTISIG operations
838 */
be126699 839bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId)
e679ec96 840{
05df3fc6 841 if (tx.IsCoinBase())
575bdcde 842 return true; // Coinbases don't use vin normally
0cb91a8d
SS
843
844 if (tx.IsCoinImport())
845 return tx.vin[0].scriptSig.IsCoinImport();
846
05df3fc6 847 for (unsigned int i = 0; i < tx.vin.size(); i++)
e679ec96 848 {
05df3fc6 849 const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
8d655683 850
e679ec96 851 vector<vector<unsigned char> > vSolutions;
2a45a494
GA
852 txnouttype whichType;
853 // get the scriptPubKey corresponding to this input:
8d7849b6 854 const CScript& prevScript = prev.scriptPubKey;
2a45a494 855 if (!Solver(prevScript, whichType, vSolutions))
922e8e29 856 return false;
39f0d968 857 int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
c0a0a93d
JG
858 if (nArgsExpected < 0)
859 return false;
8d655683 860
39f0d968
GA
861 // Transactions with extra stuff in their scriptSigs are
862 // non-standard. Note that this EvalScript() call will
863 // be quick, because if there are any operations
7f3b4e95 864 // beside "push data" in the scriptSig
bd2b73bb 865 // IsStandardTx() will have already returned false
7f3b4e95 866 // and this method isn't called.
39f0d968 867 vector<vector<unsigned char> > stack;
be126699 868 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId))
39f0d968 869 return false;
8d655683 870
e679ec96
GA
871 if (whichType == TX_SCRIPTHASH)
872 {
922e8e29 873 if (stack.empty())
e679ec96 874 return false;
2a45a494 875 CScript subscript(stack.back().begin(), stack.back().end());
39f0d968
GA
876 vector<vector<unsigned char> > vSolutions2;
877 txnouttype whichType2;
7f3b4e95
GA
878 if (Solver(subscript, whichType2, vSolutions2))
879 {
880 int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
881 if (tmpExpected < 0)
882 return false;
883 nArgsExpected += tmpExpected;
884 }
885 else
886 {
887 // Any other Script with less than 15 sigops OK:
888 unsigned int sigops = subscript.GetSigOpCount(true);
889 // ... extra data left on the stack after execution is OK, too:
890 return (sigops <= MAX_P2SH_SIGOPS);
891 }
e679ec96 892 }
8d655683 893
c0a0a93d 894 if (stack.size() != (unsigned int)nArgsExpected)
39f0d968 895 return false;
e679ec96 896 }
8d655683 897
e679ec96
GA
898 return true;
899}
900
05df3fc6 901unsigned int GetLegacySigOpCount(const CTransaction& tx)
922e8e29 902{
7bd9c3a3 903 unsigned int nSigOps = 0;
05df3fc6 904 BOOST_FOREACH(const CTxIn& txin, tx.vin)
922e8e29
GA
905 {
906 nSigOps += txin.scriptSig.GetSigOpCount(false);
907 }
05df3fc6 908 BOOST_FOREACH(const CTxOut& txout, tx.vout)
922e8e29
GA
909 {
910 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
911 }
912 return nSigOps;
913}
0a61b0df 914
d0867acb 915unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
05df3fc6 916{
0cb91a8d 917 if (tx.IsCoinBase() || tx.IsCoinImport())
05df3fc6 918 return 0;
8d655683 919
05df3fc6
EL
920 unsigned int nSigOps = 0;
921 for (unsigned int i = 0; i < tx.vin.size(); i++)
922 {
923 const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
924 if (prevout.scriptPubKey.IsPayToScriptHash())
925 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
926 }
927 return nSigOps;
928}
0a61b0df 929
1414fc05 930/**
abb90a89
MT
931 * Ensure that a coinbase transaction is structured according to the consensus rules of the
932 * chain
1414fc05 933 */
abb90a89 934bool ContextualCheckCoinbaseTransaction(const CTransaction& tx, const int nHeight)
1414fc05 935{
abb90a89 936 // if time locks are on, ensure that this coin base is time locked exactly as it should be
20ab1c91 937 if (((uint64_t)(tx.GetValueOut()) >= ASSETCHAINS_TIMELOCKGTE) || (nHeight >= 31680) && komodo_ac_block_subsidy(nHeight) >= ASSETCHAINS_TIMELOCKGTE)
1414fc05 938 {
29bd53a1
MT
939 CScriptID scriptHash;
940
abb90a89 941 // to be valid, it must be a P2SH transaction and have an op_return in vout[1] that
29bd53a1
MT
942 // holds the full output script, which may include multisig, etc., but starts with
943 // the time lock verify of the correct time lock for this block height
a0dd01bc 944 if (tx.vout.size() == 2 &&
29bd53a1
MT
945 CScriptExt(tx.vout[0].scriptPubKey).IsPayToScriptHash(&scriptHash) &&
946 tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
947 tx.vout[1].scriptPubKey.data()[0] == OP_RETURN)
abb90a89 948 {
29bd53a1
MT
949 opcodetype op;
950 std::vector<uint8_t> opretData = std::vector<uint8_t>();
951 CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
952 if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
abb90a89 953 {
29bd53a1 954 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
abb90a89 955 {
29bd53a1
MT
956 int64_t unlocktime;
957 CScriptExt opretScript = CScriptExt(opretData.begin() + 1, opretData.end());
958
959 if (CScriptID(opretScript) == scriptHash &&
960 opretScript.IsCheckLockTimeVerify(&unlocktime) &&
961 komodo_block_unlocktime(nHeight) == unlocktime)
962 {
963 return(true);
964 }
abb90a89
MT
965 }
966 }
967 }
6b78e01d 968 return(false);
1414fc05 969 }
6b78e01d 970 return(true);
1414fc05
MT
971}
972
072099d7
S
973/**
974 * Check a transaction contextually against a set of consensus rules valid at a given block height.
8d655683 975 *
072099d7
S
976 * Notes:
977 * 1. AcceptToMemoryPool calls CheckTransaction and this function.
978 * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction)
979 * and ContextualCheckBlock (which calls this function).
980 */
981bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, const int nHeight, const int dosLevel)
982{
983 bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER);
984 bool isSprout = !isOverwinter;
8d655683 985
072099d7
S
986 // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond
987 if (isSprout && tx.fOverwintered) {
988 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter is not active yet"),
989 REJECT_INVALID, "tx-overwinter-not-active");
990 }
8d655683 991
072099d7
S
992 // If Overwinter rules apply:
993 if (isOverwinter) {
994 // Reject transactions with valid version but missing overwinter flag
995 if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) {
996 return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"),
8d655683 997 REJECT_INVALID, "tx-overwinter-flag-not-set");
072099d7 998 }
8d655683 999
072099d7
S
1000 // Reject transactions with invalid version
1001 if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) {
1002 return state.DoS(100, error("CheckTransaction(): overwinter version too high"),
8d655683 1003 REJECT_INVALID, "bad-tx-overwinter-version-too-high");
072099d7 1004 }
8d655683 1005
072099d7
S
1006 // Reject transactions intended for Sprout
1007 if (!tx.fOverwintered) {
1008 return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"),
8d655683 1009 REJECT_INVALID, "tx-overwinter-active");
072099d7 1010 }
8d655683 1011
9bb37bf0
JG
1012 // Check that all transactions are unexpired
1013 if (IsExpiredTx(tx, nHeight)) {
1014 return state.DoS(dosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired");
1015 }
072099d7 1016 }
0cb91a8d
SS
1017
1018 if (!(tx.IsMint() || tx.vjoinsplit.empty())) {
be126699
JG
1019 auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus());
1020 // Empty output script.
1021 CScript scriptCode;
1022 uint256 dataToBeSigned;
1023 try {
1024 dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
1025 } catch (std::logic_error ex) {
1026 return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
8d655683 1027 REJECT_INVALID, "error-computing-signature-hash");
be126699 1028 }
8d655683 1029
be126699 1030 BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32);
8d655683 1031
be126699
JG
1032 // We rely on libsodium to check that the signature is canonical.
1033 // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0
1034 if (crypto_sign_verify_detached(&tx.joinSplitSig[0],
1035 dataToBeSigned.begin(), 32,
1036 tx.joinSplitPubKey.begin()
1037 ) != 0) {
1038 return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"),
8d655683 1039 REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
be126699
JG
1040 }
1041 }
d121e75b 1042
65098812 1043 if (tx.IsCoinBase())
d121e75b 1044 {
abb90a89
MT
1045 if (!ContextualCheckCoinbaseTransaction(tx, nHeight))
1046 return state.DoS(100, error("CheckTransaction(): invalid script data for coinbase time lock"),
1047 REJECT_INVALID, "bad-txns-invalid-script-data-for-coinbase-time-lock");
d121e75b 1048 }
072099d7
S
1049 return true;
1050}
1051
6fb8d0c2
JG
1052bool CheckTransaction(const CTransaction& tx, CValidationState &state,
1053 libzcash::ProofVerifier& verifier)
948d4e6c 1054{
c2123afe 1055 static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n;
782e1a56 1056 if ( *(int32_t *)&array[0] == 0 )
c2123afe 1057 numbanned = komodo_bannedset(&indallvouts,array,(int32_t)(sizeof(array)/sizeof(*array)));
6d1d0330 1058 n = tx.vin.size();
782e1a56 1059 for (j=0; j<n; j++)
1060 {
c2123afe 1061 for (k=0; k<numbanned; k++)
782e1a56 1062 {
464fe491 1063 if ( tx.vin[j].prevout.hash == array[k] && (tx.vin[j].prevout.n == 1 || k >= indallvouts) )
782e1a56 1064 {
c40ec31d 1065 static uint32_t counter;
1066 if ( counter++ < 100 )
c2123afe 1067 printf("MEMPOOL: banned tx.%d being used at ht.%d vout.%d\n",k,(int32_t)chainActive.Tip()->nHeight,j);
782e1a56 1068 return(false);
1069 }
1070 }
1071 }
8d655683 1072 // Don't count coinbase transactions because mining skews the count
a6df7ab5
JG
1073 if (!tx.IsCoinBase()) {
1074 transactionsValidated.increment();
1075 }
8d655683 1076
948d4e6c
TH
1077 if (!CheckTransactionWithoutProofVerification(tx, state)) {
1078 return false;
1079 } else {
0cb91a8d 1080 // Ensure that zk-SNARKs v|| y
b7e4abd6 1081 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
bc59f537 1082 if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) {
b7e4abd6 1083 return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
8d655683 1084 REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
948d4e6c
TH
1085 }
1086 }
1087 return true;
1088 }
1089}
1090
1091bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidationState &state)
a790fa46 1092{
1093 // Basic checks that don't depend on any context
8d655683 1094
072099d7
S
1095 /**
1096 * Previously:
1097 * 1. The consensus rule below was:
1098 * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... }
1099 * which checked if tx.nVersion fell within the range:
1100 * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION
1101 * 2. The parser allowed tx.nVersion to be negative
1102 *
1103 * Now:
1104 * 1. The consensus rule checks to see if tx.Version falls within the range:
1105 * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION
1106 * 2. The previous consensus rule checked for negative values within the range:
1107 * INT32_MIN <= tx.nVersion < 0
1108 * This is unnecessary for Overwinter transactions since the parser now
1109 * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0,
1110 * and when Overwinter is not active ContextualCheckTransaction rejects
1111 * transactions with fOverwintered set. When fOverwintered is set,
1112 * this function and ContextualCheckTransaction will together check to
1113 * ensure tx.nVersion avoids the following ranges:
1114 * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION
1115 * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX
1116 */
1117 if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) {
7ac924cd 1118 return state.DoS(100, error("CheckTransaction(): version too low"),
cb124619 1119 REJECT_INVALID, "bad-txns-version-too-low");
7ac924cd 1120 }
072099d7
S
1121 else if (tx.fOverwintered) {
1122 if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) {
1123 return state.DoS(100, error("CheckTransaction(): overwinter version too low"),
8d655683 1124 REJECT_INVALID, "bad-tx-overwinter-version-too-low");
072099d7
S
1125 }
1126 if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) {
1127 return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
8d655683 1128 REJECT_INVALID, "bad-tx-version-group-id");
072099d7
S
1129 }
1130 if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
1131 return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
8d655683 1132 REJECT_INVALID, "bad-tx-expiry-height-too-high");
072099d7
S
1133 }
1134 }
8d655683 1135
69761d82 1136 // Transactions can contain empty `vin` and `vout` so long as
8675d94b 1137 // `vjoinsplit` is non-empty.
0cb91a8d 1138 // Migrations may also have empty `vin`
8675d94b 1139 if (tx.vin.empty() && tx.vjoinsplit.empty())
5262fde0 1140 return state.DoS(10, error("CheckTransaction(): vin empty"),
14e7ffcc 1141 REJECT_INVALID, "bad-txns-vin-empty");
8675d94b 1142 if (tx.vout.empty() && tx.vjoinsplit.empty())
5262fde0 1143 return state.DoS(10, error("CheckTransaction(): vout empty"),
14e7ffcc 1144 REJECT_INVALID, "bad-txns-vout-empty");
8d655683 1145
a790fa46 1146 // Size limits
74f15a73
SB
1147 BOOST_STATIC_ASSERT(MAX_BLOCK_SIZE > MAX_TX_SIZE); // sanity
1148 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_TX_SIZE)
5262fde0 1149 return state.DoS(100, error("CheckTransaction(): size limits failed"),
14e7ffcc 1150 REJECT_INVALID, "bad-txns-oversize");
8d655683 1151
a790fa46 1152 // Check for negative or overflow output values
a372168e 1153 CAmount nValueOut = 0;
36f9e6d6 1154 int32_t iscoinbase = tx.IsCoinBase();
05df3fc6 1155 BOOST_FOREACH(const CTxOut& txout, tx.vout)
a790fa46 1156 {
1157 if (txout.nValue < 0)
5262fde0 1158 return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
14e7ffcc 1159 REJECT_INVALID, "bad-txns-vout-negative");
a790fa46 1160 if (txout.nValue > MAX_MONEY)
4e038ef5 1161 {
1162 fprintf(stderr,"%.8f > max %.8f\n",(double)txout.nValue/COIN,(double)MAX_MONEY/COIN);
1163 return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),REJECT_INVALID, "bad-txns-vout-toolarge");
1164 }
471f1b83 1165 if ( ASSETCHAINS_PRIVATE != 0 )
36f9e6d6 1166 {
471f1b83 1167 fprintf(stderr,"private chain nValue %.8f iscoinbase.%d\n",(double)txout.nValue/COIN,iscoinbase);
3118a070 1168 if ( (txout.nValue > 0 && iscoinbase == 0) || tx.GetJoinSplitValueOut() > 0 )
471f1b83 1169 return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain");
36f9e6d6 1170 }
a790fa46 1171 nValueOut += txout.nValue;
1172 if (!MoneyRange(nValueOut))
5262fde0 1173 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
14e7ffcc 1174 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
a790fa46 1175 }
8d655683 1176
b7e4abd6
SB
1177 // Ensure that joinsplit values are well-formed
1178 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
69761d82 1179 {
626179f1 1180 if ( ASSETCHAINS_PUBLIC != 0 )
1181 {
1182 return state.DoS(100, error("CheckTransaction(): this is a public chain, no privacy allowed"),
1183 REJECT_INVALID, "bad-txns-acprivacy-chain");
1184 }
b7e4abd6
SB
1185 if (joinsplit.vpub_old < 0) {
1186 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old negative"),
69761d82 1187 REJECT_INVALID, "bad-txns-vpub_old-negative");
6ad4db22 1188 }
8d655683 1189
b7e4abd6
SB
1190 if (joinsplit.vpub_new < 0) {
1191 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new negative"),
69761d82 1192 REJECT_INVALID, "bad-txns-vpub_new-negative");
6ad4db22 1193 }
8d655683 1194
b7e4abd6
SB
1195 if (joinsplit.vpub_old > MAX_MONEY) {
1196 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_old too high"),
69761d82 1197 REJECT_INVALID, "bad-txns-vpub_old-toolarge");
6ad4db22 1198 }
8d655683 1199
b7e4abd6
SB
1200 if (joinsplit.vpub_new > MAX_MONEY) {
1201 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new too high"),
69761d82 1202 REJECT_INVALID, "bad-txns-vpub_new-toolarge");
6ad4db22 1203 }
8d655683 1204
b7e4abd6
SB
1205 if (joinsplit.vpub_new != 0 && joinsplit.vpub_old != 0) {
1206 return state.DoS(100, error("CheckTransaction(): joinsplit.vpub_new and joinsplit.vpub_old both nonzero"),
6ad4db22
TH
1207 REJECT_INVALID, "bad-txns-vpubs-both-nonzero");
1208 }
8d655683 1209
d7eeb745 1210 nValueOut += joinsplit.vpub_old;
6ad4db22 1211 if (!MoneyRange(nValueOut)) {
69761d82
SB
1212 return state.DoS(100, error("CheckTransaction(): txout total out of range"),
1213 REJECT_INVALID, "bad-txns-txouttotal-toolarge");
6ad4db22 1214 }
69761d82 1215 }
8d655683 1216
d7eeb745
SB
1217 // Ensure input values do not exceed MAX_MONEY
1218 // We have not resolved the txin values at this stage,
1219 // but we do know what the joinsplits claim to add
1220 // to the value pool.
1221 {
1222 CAmount nValueIn = 0;
1223 for (std::vector<JSDescription>::const_iterator it(tx.vjoinsplit.begin()); it != tx.vjoinsplit.end(); ++it)
1224 {
1225 nValueIn += it->vpub_new;
8d655683 1226
d7eeb745
SB
1227 if (!MoneyRange(it->vpub_new) || !MoneyRange(nValueIn)) {
1228 return state.DoS(100, error("CheckTransaction(): txin total out of range"),
1229 REJECT_INVALID, "bad-txns-txintotal-toolarge");
1230 }
1231 }
1232 }
8d655683 1233
1234
33208fb5
MC
1235 // Check for duplicate inputs
1236 set<COutPoint> vInOutPoints;
05df3fc6 1237 BOOST_FOREACH(const CTxIn& txin, tx.vin)
33208fb5
MC
1238 {
1239 if (vInOutPoints.count(txin.prevout))
5262fde0 1240 return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
14e7ffcc 1241 REJECT_INVALID, "bad-txns-inputs-duplicate");
33208fb5
MC
1242 vInOutPoints.insert(txin.prevout);
1243 }
8d655683 1244
b7e4abd6 1245 // Check for duplicate joinsplit nullifiers in this transaction
bfeaf004 1246 set<uint256> vJoinSplitNullifiers;
b7e4abd6 1247 BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit)
69761d82 1248 {
cc01120a 1249 BOOST_FOREACH(const uint256& nf, joinsplit.nullifiers)
69761d82 1250 {
cc01120a 1251 if (vJoinSplitNullifiers.count(nf))
bfeaf004 1252 return state.DoS(100, error("CheckTransaction(): duplicate nullifiers"),
8d655683 1253 REJECT_INVALID, "bad-joinsplits-nullifiers-duplicate");
1254
cc01120a 1255 vJoinSplitNullifiers.insert(nf);
69761d82
SB
1256 }
1257 }
8d655683 1258
0cb91a8d 1259 if (tx.IsMint())
a790fa46 1260 {
b7e4abd6 1261 // There should be no joinsplits in a coinbase transaction
8675d94b 1262 if (tx.vjoinsplit.size() > 0)
b7e4abd6
SB
1263 return state.DoS(100, error("CheckTransaction(): coinbase has joinsplits"),
1264 REJECT_INVALID, "bad-cb-has-joinsplits");
8d655683 1265
05df3fc6 1266 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
5262fde0 1267 return state.DoS(100, error("CheckTransaction(): coinbase script size"),
14e7ffcc 1268 REJECT_INVALID, "bad-cb-length");
a790fa46 1269 }
1270 else
1271 {
05df3fc6 1272 BOOST_FOREACH(const CTxIn& txin, tx.vin)
8d655683 1273 if (txin.prevout.IsNull())
1274 return state.DoS(10, error("CheckTransaction(): prevout is null"),
1275 REJECT_INVALID, "bad-txns-prevout-null");
a790fa46 1276 }
8d655683 1277
a790fa46 1278 return true;
1279}
1280
a372168e 1281CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
76970091 1282{
f24b36ca 1283 extern int32_t KOMODO_ON_DEMAND;
2a72d459
LD
1284 {
1285 LOCK(mempool.cs);
805344dc 1286 uint256 hash = tx.GetHash();
2a72d459 1287 double dPriorityDelta = 0;
a372168e 1288 CAmount nFeeDelta = 0;
2a72d459
LD
1289 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
1290 if (dPriorityDelta > 0 || nFeeDelta > 0)
1291 return 0;
1292 }
8d655683 1293
a372168e 1294 CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
8d655683 1295
76970091
JG
1296 if (fAllowFree)
1297 {
87cce04c
MC
1298 // There is a free transaction area in blocks created by most miners,
1299 // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
16b3ff66
GA
1300 // to be considered to fall into this category. We don't want to encourage sending
1301 // multiple transactions instead of one big transaction to avoid fees.
b33d1f5e 1302 if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
87cce04c 1303 nMinFee = 0;
76970091 1304 }
8d655683 1305
76970091
JG
1306 if (!MoneyRange(nMinFee))
1307 nMinFee = MAX_MONEY;
1308 return nMinFee;
1309}
1310
450cbb09 1311
3fef7c32 1312bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee)
0a61b0df 1313{
e07c943c 1314 AssertLockHeld(cs_main);
0a61b0df 1315 if (pfMissingInputs)
1316 *pfMissingInputs = false;
9000990c 1317
be126699
JG
1318 int nextBlockHeight = chainActive.Height() + 1;
1319 auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
9000990c 1320
da6d9391
S
1321 // Node operator can choose to reject tx by number of transparent inputs
1322 static_assert(std::numeric_limits<size_t>::max() >= std::numeric_limits<int64_t>::max(), "size_t too small");
1323 size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0);
1324 if (limit > 0) {
1325 size_t n = tx.vin.size();
1326 if (n > limit) {
1327 LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit );
1328 return false;
1329 }
1330 }
9000990c 1331
6fb8d0c2 1332 auto verifier = libzcash::ProofVerifier::Strict();
86131275 1333 if ( komodo_validate_interest(tx,chainActive.LastTip()->nHeight+1,chainActive.LastTip()->GetMedianTimePast() + 777,0) < 0 )
e7fa1876 1334 {
66294e69 1335 //fprintf(stderr,"AcceptToMemoryPool komodo_validate_interest failure\n");
e7fa1876 1336 return error("AcceptToMemoryPool: komodo_validate_interest failed");
14aa6cc0 1337 }
6fb8d0c2 1338 if (!CheckTransaction(tx, state, verifier))
c7a1d234 1339 {
1340
4f1ee565 1341 return error("AcceptToMemoryPool: CheckTransaction failed");
c7a1d234 1342 }
072099d7
S
1343 // DoS level set to 10 to be more forgiving.
1344 // Check transaction contextually against the set of consensus rules which apply in the next block to be mined.
c7a1d234 1345 if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10))
1346 {
072099d7 1347 return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
68c266b2 1348 }
9000990c 1349
0a61b0df 1350 // Coinbase is only valid in a block, not as a loose transaction
d01903e7 1351 if (tx.IsCoinBase())
9eb44c75 1352 {
1353 fprintf(stderr,"AcceptToMemoryPool coinbase as individual tx\n");
1354 return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),REJECT_INVALID, "coinbase");
1355 }
d9ace8ab 1356 // Rather not work on nonstandard transactions (unless -testnet/-regtest)
980bfe6e 1357 string reason;
072099d7 1358 if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight))
9eb44c75 1359 {
9000990c 1360 fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str());
9eb44c75 1361 return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason);
1362 }
0ea28bae
PT
1363 // Only accept nLockTime-using transactions that can be mined in the next
1364 // block; we don't want our mempool filled up with transactions that can't
1365 // be mined yet.
a1d3c6fb 1366 if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
9eb44c75 1367 {
9e8b81f6 1368 //fprintf(stderr,"AcceptToMemoryPool reject non-final\n");
a1d3c6fb 1369 return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
9eb44c75 1370 }
450cbb09 1371 // is it already in the memory pool?
805344dc 1372 uint256 hash = tx.GetHash();
319b1160 1373 if (pool.exists(hash))
ff2d88cc 1374 {
99fb7ab3 1375 //fprintf(stderr,"already in mempool\n");
0cb91a8d 1376 return state.Invalid(false, REJECT_DUPLICATE, "already in mempool");
ff2d88cc 1377 }
9000990c 1378
0a61b0df 1379 // Check for conflicts with in-memory transactions
319b1160 1380 {
9000990c 1381 LOCK(pool.cs); // protect pool.mapNextTx
1382 for (unsigned int i = 0; i < tx.vin.size(); i++)
0a61b0df 1383 {
9000990c 1384 COutPoint outpoint = tx.vin[i].prevout;
1385 if (pool.mapNextTx.count(outpoint))
d66877af 1386 {
d6eb511b 1387 //static uint32_t counter;
9000990c 1388 // Disable replacement feature for now
1389 //if ( counter++ < 100 )
d6eb511b 1390 //fprintf(stderr,"Disable replacement feature for now\n");
d66877af
SB
1391 return false;
1392 }
0a61b0df 1393 }
9000990c 1394 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit)
1395 {
1396 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers)
d66877af 1397 {
9000990c 1398 if (pool.mapNullifiers.count(nf))
1399 {
1400 fprintf(stderr,"pool.mapNullifiers.count\n");
1401 return false;
1402 }
d66877af
SB
1403 }
1404 }
1405 }
8d655683 1406
0a61b0df 1407 {
4afc0b54 1408 CCoinsView dummy;
7c70438d 1409 CCoinsViewCache view(&dummy);
355ca565 1410 int64_t interest;
a372168e 1411 CAmount nValueIn = 0;
4afc0b54 1412 {
9000990c 1413 LOCK(pool.cs);
1414 CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1415 view.SetBackend(viewMemPool);
1416
1417 // do we already have it?
1418 if (view.HaveCoins(hash))
1419 {
46d1074a 1420 //fprintf(stderr,"view.HaveCoins(hash) error\n");
0cb91a8d 1421 return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
450cbb09 1422 }
9000990c 1423
3c760413 1424 if (tx.IsCoinImport())
9000990c 1425 {
3c760413
SS
1426 // Inverse of normal case; if input exists, it's been spent
1427 if (ExistsImportTombstone(tx, view))
1428 return state.Invalid(false, REJECT_DUPLICATE, "import tombstone exists");
9000990c 1429 }
3c760413 1430 else
9000990c 1431 {
0cb91a8d
SS
1432 // do all inputs exist?
1433 // Note that this does not check for the presence of actual outputs (see the next check for that),
1434 // and only helps with filling in pfMissingInputs (to determine missing vs spent).
1435 BOOST_FOREACH(const CTxIn txin, tx.vin)
9000990c 1436 {
0cb91a8d
SS
1437 if (!view.HaveCoins(txin.prevout.hash))
1438 {
1439 if (pfMissingInputs)
1440 *pfMissingInputs = true;
1441 //fprintf(stderr,"missing inputs\n");
1442 return false;
1443 }
1444 }
1445
1446 // are the actual inputs available?
1447 if (!view.HaveInputs(tx))
1448 {
1449 //fprintf(stderr,"accept failure.1\n");
1450 return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent");
9000990c 1451 }
9000990c 1452 }
1453 // are the joinsplit's requirements met?
1454 if (!view.HaveJoinSplitRequirements(tx))
1455 {
60aee10d 1456 //fprintf(stderr,"accept failure.2\n");
9000990c 1457 return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met");
1458 }
1459
1460 // Bring the best block into scope
1461 view.GetBestBlock();
1462
86131275 1463 nValueIn = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime);
f595c2e0 1464 if ( 0 && interest != 0 )
4a4e912b 1465 fprintf(stderr,"add interest %.8f\n",(double)interest/COIN);
9000990c 1466 // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
1467 view.SetBackend(dummy);
4afc0b54 1468 }
9000990c 1469
922e8e29 1470 // Check for non-standard pay-to-script-hash in inputs
be126699 1471 if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId))
9000990c 1472 return error("AcceptToMemoryPool: reject nonstandard transaction input");
1473
9ee09dc6
PT
1474 // Check that the transaction doesn't have an excessive number of
1475 // sigops, making it impossible to mine. Since the coinbase transaction
23f34359 1476 // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
9ee09dc6
PT
1477 // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
1478 // merely non-standard transaction.
1479 unsigned int nSigOps = GetLegacySigOpCount(tx);
1480 nSigOps += GetP2SHSigOpCount(tx, view);
23f34359 1481 if (nSigOps > MAX_STANDARD_TX_SIGOPS)
68c266b2 1482 {
1483 fprintf(stderr,"accept failure.4\n");
1484 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");
1485 }
8d655683 1486
a372168e
MF
1487 CAmount nValueOut = tx.GetValueOut();
1488 CAmount nFees = nValueIn-nValueOut;
4d707d51 1489 double dPriority = view.GetPriority(tx, chainActive.Height());
9000990c 1490
a4b25180
SD
1491 // Keep track of transactions that spend a coinbase, which we re-scan
1492 // during reorgs to ensure COINBASE_MATURITY is still met.
1493 bool fSpendsCoinbase = false;
0cb91a8d
SS
1494 if (!tx.IsCoinImport()) {
1495 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
1496 const CCoins *coins = view.AccessCoins(txin.prevout.hash);
1497 if (coins->IsCoinBase()) {
1498 fSpendsCoinbase = true;
1499 break;
1500 }
a4b25180
SD
1501 }
1502 }
9000990c 1503
34a64fe0
JG
1504 // Grab the branch ID we expect this transaction to commit to. We don't
1505 // yet know if it does, but if the entry gets added to the mempool, then
1506 // it has passed ContextualCheckInputs and therefore this is correct.
1507 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
9000990c 1508
34a64fe0 1509 CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId);
4d707d51 1510 unsigned int nSize = entry.GetTxSize();
9000990c 1511
9ddb6ad0
S
1512 // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany.
1513 if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) {
1514 // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits.
1515 } else {
1516 // Don't accept it if it can't get into a block
1517 CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1518 if (fLimitFree && nFees < txMinFee)
68c266b2 1519 {
ad4ca5c5 1520 //fprintf(stderr,"accept failure.5\n");
68c266b2 1521 return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee");
1522 }
9ddb6ad0 1523 }
9000990c 1524
1c52aad5 1525 // Require that free transactions have sufficient priority to be mined in the next block.
a5150a15 1526 if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
68c266b2 1527 fprintf(stderr,"accept failure.6\n");
1c52aad5
PW
1528 return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
1529 }
9000990c 1530
bf7835c2 1531 // Continuously rate-limit free (really, very-low-fee) transactions
88abf703 1532 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
b49f1398 1533 // be annoying or make others' transactions take longer to confirm.
13fc83c7 1534 if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
97ee01ad 1535 {
98e84aae 1536 static CCriticalSection csFreeLimiter;
5de8b54c 1537 static double dFreeCount;
98e84aae
WL
1538 static int64_t nLastTime;
1539 int64_t nNow = GetTime();
9000990c 1540
98e84aae 1541 LOCK(csFreeLimiter);
9000990c 1542
98e84aae
WL
1543 // Use an exponentially decaying ~10-minute window:
1544 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
1545 nLastTime = nNow;
1546 // -limitfreerelay unit is thousand-bytes-per-minute
1547 // At default rate it would take over a month to fill 1GB
1548 if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
68c266b2 1549 {
1550 fprintf(stderr,"accept failure.7\n");
3fef7c32 1551 return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
68c266b2 1552 }
319b1160 1553 LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
98e84aae 1554 dFreeCount += nSize;
97ee01ad 1555 }
9000990c 1556
b310d585 1557 if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19 )
68c266b2 1558 {
1559 fprintf(stderr,"accept failure.8\n");
1560 return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1561 }
9000990c 1562
8d7849b6
GA
1563 // Check against previous transactions
1564 // This is done last to help prevent CPU exhaustion denial-of-service attacks.
6514771a 1565 PrecomputedTransactionData txdata(tx);
be126699 1566 if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
8d7849b6 1567 {
60aee10d 1568 //fprintf(stderr,"accept failure.9\n");
bf7835c2 1569 return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
8d7849b6 1570 }
9000990c 1571
7c041b3b
PT
1572 // Check again against just the consensus-critical mandatory script
1573 // verification flags, in case of bugs in the standard flags that cause
1574 // transactions to pass as valid when they're actually invalid. For
1575 // instance the STRICTENC flag was incorrectly allowing certain
1576 // CHECKSIG NOT scripts to pass, even though they were invalid.
1577 //
1578 // There is a similar check in CreateNewBlock() to prevent creating
1579 // invalid blocks, however allowing such transactions into the mempool
1580 // can be exploited as a DoS attack.
0cb91a8d 1581 // XXX: is this neccesary for CryptoConditions?
be126699 1582 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
7c041b3b 1583 {
68c266b2 1584 fprintf(stderr,"accept failure.10\n");
4f1ee565 1585 return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
7c041b3b 1586 }
9000990c 1587
cd057bfd 1588 // Store transaction in memory
f24b36ca 1589 if ( komodo_is_notarytx(tx) == 0 )
1590 KOMODO_ON_DEMAND++;
b649e039 1591 pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
8b78a819
T
1592
1593 // Add memory address index
1594 if (fAddressIndex) {
1595 pool.addAddressIndex(entry, view);
1596 }
1597
1598 // Add memory spent index
1599 if (fSpentIndex) {
1600 pool.addSpentIndex(entry, view);
1601 }
d640a3ce 1602 }
9000990c 1603
0d27dad8 1604 SyncWithWallets(tx, NULL);
9000990c 1605
cd057bfd 1606 return true;
d640a3ce
TH
1607}
1608
8b78a819
T
1609bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1610{
1611 if (!fTimestampIndex)
1612 return error("Timestamp index not enabled");
1613
1614 if (!pblocktree->ReadTimestampIndex(high, low, fActiveOnly, hashes))
1615 return error("Unable to get hashes for timestamps");
1616
1617 return true;
1618}
1619
1620bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
1621{
1622 if (!fSpentIndex)
1623 return false;
1624
1625 if (mempool.getSpentIndex(key, value))
1626 return true;
1627
1628 if (!pblocktree->ReadSpentIndex(key, value))
1629 return false;
1630
1631 return true;
1632}
1633
1634bool GetAddressIndex(uint160 addressHash, int type,
1635 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
1636{
1637 if (!fAddressIndex)
1638 return error("address index not enabled");
1639
1640 if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex, start, end))
1641 return error("unable to get txids for address");
1642
1643 return true;
1644}
1645
1646bool GetAddressUnspent(uint160 addressHash, int type,
1647 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1648{
1649 if (!fAddressIndex)
1650 return error("address index not enabled");
1651
1652 if (!pblocktree->ReadAddressUnspentIndex(addressHash, type, unspentOutputs))
1653 return error("unable to get txids for address");
1654
1655 return true;
1656}
1657
21f17b88 1658bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock)
1659{
f7522720 1660 // need a GetTransaction without lock so the validation code for assets can run without deadlock
21f17b88 1661 {
2a6a442a 1662 //fprintf(stderr,"check mempool\n");
63a24829 1663 if (mempool.lookup(hash, txOut))
1664 {
2a6a442a 1665 //fprintf(stderr,"found in mempool\n");
63a24829 1666 return true;
1667 }
21f17b88 1668 }
2a6a442a 1669 //fprintf(stderr,"check disk\n");
21f17b88 1670
1671 if (fTxIndex) {
1672 CDiskTxPos postx;
2a6a442a 1673 //fprintf(stderr,"ReadTxIndex\n");
21f17b88 1674 if (pblocktree->ReadTxIndex(hash, postx)) {
2a6a442a 1675 //fprintf(stderr,"OpenBlockFile\n");
21f17b88 1676 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1677 if (file.IsNull())
1678 return error("%s: OpenBlockFile failed", __func__);
1679 CBlockHeader header;
2a6a442a 1680 //fprintf(stderr,"seek and read\n");
21f17b88 1681 try {
1682 file >> header;
1683 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1684 file >> txOut;
1685 } catch (const std::exception& e) {
1686 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
1687 }
1688 hashBlock = header.GetHash();
1689 if (txOut.GetHash() != hash)
1690 return error("%s: txid mismatch", __func__);
2a6a442a 1691 //fprintf(stderr,"found on disk\n");
21f17b88 1692 return true;
1693 }
1694 }
2a6a442a 1695 //fprintf(stderr,"not found\n");
21f17b88 1696 return false;
1697}
1698
c5b390b6 1699/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
450cbb09 1700bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
c73ba23e 1701{
450cbb09 1702 CBlockIndex *pindexSlow = NULL;
8d655683 1703
01878c9c 1704 LOCK(cs_main);
8d655683 1705
01878c9c 1706 if (mempool.lookup(hash, txOut))
c73ba23e 1707 {
01878c9c
AM
1708 return true;
1709 }
8d655683 1710
01878c9c
AM
1711 if (fTxIndex) {
1712 CDiskTxPos postx;
1713 if (pblocktree->ReadTxIndex(hash, postx)) {
1714 CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1715 if (file.IsNull())
1716 return error("%s: OpenBlockFile failed", __func__);
1717 CBlockHeader header;
1718 try {
1719 file >> header;
1720 fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1721 file >> txOut;
1722 } catch (const std::exception& e) {
1723 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2d1fa42e 1724 }
01878c9c 1725 hashBlock = header.GetHash();
805344dc 1726 if (txOut.GetHash() != hash)
01878c9c
AM
1727 return error("%s: txid mismatch", __func__);
1728 return true;
2d1fa42e 1729 }
01878c9c 1730 }
8d655683 1731
01878c9c
AM
1732 if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
1733 int nHeight = -1;
1734 {
1735 CCoinsViewCache &view = *pcoinsTip;
1736 const CCoins* coins = view.AccessCoins(hash);
1737 if (coins)
1738 nHeight = coins->nHeight;
c73ba23e 1739 }
01878c9c
AM
1740 if (nHeight > 0)
1741 pindexSlow = chainActive[nHeight];
c73ba23e 1742 }
8d655683 1743
450cbb09
PW
1744 if (pindexSlow) {
1745 CBlock block;
b8add6a4 1746 if (ReadBlockFromDisk(block, pindexSlow,1)) {
450cbb09 1747 BOOST_FOREACH(const CTransaction &tx, block.vtx) {
805344dc 1748 if (tx.GetHash() == hash) {
450cbb09
PW
1749 txOut = tx;
1750 hashBlock = pindexSlow->GetBlockHash();
1751 return true;
1752 }
1753 }
1754 }
1755 }
8d655683 1756
450cbb09
PW
1757 return false;
1758}
0a61b0df 1759
352f8081 1760/*char *komodo_getspendscript(uint256 hash,int32_t n)
8d655683 1761 {
1762 CTransaction tx; uint256 hashBlock;
1763 if ( !GetTransaction(hash,tx,hashBlock,true) )
1764 {
1765 printf("null GetTransaction\n");
1766 return(0);
1767 }
1768 if ( n >= 0 && n < tx.vout.size() )
1769 return((char *)tx.vout[n].scriptPubKey.ToString().c_str());
1770 else printf("getspendscript illegal n.%d\n",n);
1771 return(0);
1772 }*/
0a61b0df 1773
1774
1775//////////////////////////////////////////////////////////////////////////////
1776//
1777// CBlock and CBlockIndex
1778//
1779
e6973430 1780bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
226f8219
EL
1781{
1782 // Open history file to append
eee030f6 1783 CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
fef24cab 1784 if (fileout.IsNull())
5262fde0 1785 return error("WriteBlockToDisk: OpenBlockFile failed");
8d655683 1786
226f8219
EL
1787 // Write index header
1788 unsigned int nSize = fileout.GetSerializeSize(block);
e6973430 1789 fileout << FLATDATA(messageStart) << nSize;
8d655683 1790
226f8219 1791 // Write block
a8738238 1792 long fileOutPos = ftell(fileout.Get());
226f8219 1793 if (fileOutPos < 0)
5262fde0 1794 return error("WriteBlockToDisk: ftell failed");
226f8219
EL
1795 pos.nPos = (unsigned int)fileOutPos;
1796 fileout << block;
8d655683 1797
226f8219
EL
1798 return true;
1799}
1800
b8add6a4 1801bool ReadBlockFromDisk(int32_t height,CBlock& block, const CDiskBlockPos& pos,bool checkPOW)
80313994 1802{
f2dd868d 1803 uint8_t pubkey33[33];
80313994 1804 block.SetNull();
8d655683 1805
80313994 1806 // Open history file to read
eee030f6 1807 CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
fef24cab 1808 if (filein.IsNull())
81a77e92 1809 {
681589a5 1810 //fprintf(stderr,"readblockfromdisk err A\n");
4342e69b 1811 return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
81a77e92 1812 }
8d655683 1813
80313994
EL
1814 // Read block
1815 try {
1816 filein >> block;
1817 }
27df4123 1818 catch (const std::exception& e) {
81a77e92 1819 fprintf(stderr,"readblockfromdisk err B\n");
f5791c6a 1820 return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
80313994 1821 }
80313994 1822 // Check the header
02290a3f 1823 if ( 0 && checkPOW != 0 )
e4b3ad62 1824 {
b8add6a4 1825 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
1f722359 1826 if (!(CheckEquihashSolution(&block, Params()) && CheckProofOfWork(block, pubkey33, height, Params().GetConsensus())))
b8add6a4 1827 {
1828 int32_t i; for (i=0; i<33; i++)
1829 fprintf(stderr,"%02x",pubkey33[i]);
1830 fprintf(stderr," warning unexpected diff at ht.%d\n",height);
1831
1832 return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
1833 }
e4b3ad62 1834 }
80313994
EL
1835 return true;
1836}
1837
b8add6a4 1838bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW)
0a61b0df 1839{
446ad3a7 1840 if ( pindex == 0 )
1841 return false;
b8add6a4 1842 if (!ReadBlockFromDisk(pindex->nHeight,block, pindex->GetBlockPos(),checkPOW))
0a61b0df 1843 return false;
7db120d5 1844 if (block.GetHash() != pindex->GetBlockHash())
f5791c6a 1845 return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
8d655683 1846 pindex->ToString(), pindex->GetBlockPos().ToString());
0a61b0df 1847 return true;
1848}
1849
314350e6 1850//uint64_t komodo_moneysupply(int32_t height);
7c130297 1851extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
48d800c2 1852extern uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS];
7a4c01c9 1853extern uint32_t ASSETCHAINS_MAGIC;
48d800c2 1854extern uint64_t ASSETCHAINS_STAKED,ASSETCHAINS_LINEAR,ASSETCHAINS_COMMISSION,ASSETCHAINS_SUPPLY;
36f9e6d6 1855extern uint8_t ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE;
5203fc4b 1856
935bd0a4 1857CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
0a61b0df 1858{
53a94b28 1859 int32_t numhalvings,i; uint64_t numerator; CAmount nSubsidy = 3 * COIN;
9a2f3a40 1860 if ( ASSETCHAINS_SYMBOL[0] == 0 )
7a4c01c9 1861 {
9a2f3a40 1862 if ( nHeight == 1 )
7a4c01c9 1863 return(100000000 * COIN); // ICO allocation
314350e6 1864 else if ( nHeight < KOMODO_ENDOFERA ) //komodo_moneysupply(nHeight) < MAX_MONEY )
9a2f3a40 1865 return(3 * COIN);
1866 else return(0);
1867 }
1868 else
1869 {
1f722359 1870 return(komodo_ac_block_subsidy(nHeight));
7a4c01c9 1871 }
8d655683 1872 /*
1873 // Mining slow start
1874 // The subsidy is ramped up linearly, skipping the middle payout of
1875 // MAX_SUBSIDY/2 to keep the monetary curve consistent with no slow start.
1876 if (nHeight < consensusParams.nSubsidySlowStartInterval / 2) {
1877 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
1878 nSubsidy *= nHeight;
1879 return nSubsidy;
1880 } else if (nHeight < consensusParams.nSubsidySlowStartInterval) {
1881 nSubsidy /= consensusParams.nSubsidySlowStartInterval;
1882 nSubsidy *= (nHeight+1);
1883 return nSubsidy;
1884 }
1885
1886 assert(nHeight > consensusParams.SubsidySlowStartShift());
1887 int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;*/
c5a9d2ca 1888 // Force block reward to zero when right shift is undefined.
5203fc4b 1889 //int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
1890 //if (halvings >= 64)
1891 // return 0;
8d655683 1892
45e3deea 1893 // Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.
5203fc4b 1894 //nSubsidy >>= halvings;
36647d52 1895 //return nSubsidy;
0a61b0df 1896}
1897
0a61b0df 1898bool IsInitialBlockDownload()
1899{
e1e3f309 1900 const CChainParams& chainParams = Params();
55a1db4f 1901 LOCK(cs_main);
a8cdaf5c 1902 if (fImporting || fReindex)
8e157f52 1903 {
03491950 1904 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
a8cdaf5c 1905 return true;
8e157f52 1906 }
a8cdaf5c 1907 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
8e157f52 1908 {
03491950 1909 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload\n");
0a61b0df 1910 return true;
8e157f52 1911 }
9ec75c5e
RDP
1912 static bool lockIBDState = false;
1913 if (lockIBDState)
cb237ef8 1914 {
03491950 1915 //fprintf(stderr,"lockIBDState true %d < %d\n",chainActive.Height(),pindexBestHeader->nHeight - 10);
9ec75c5e 1916 return false;
cb237ef8 1917 }
03491950 1918 bool state; CBlockIndex *ptr = chainActive.Tip();
1919 if ( ptr == 0 )
1920 ptr = pindexBestHeader;
1dcfdab7 1921 else if ( pindexBestHeader != 0 && pindexBestHeader->nHeight > ptr->nHeight )
1922 ptr = pindexBestHeader;
1931844a 1923 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
8d655683 1924 state = ((chainActive.Height() < ptr->nHeight - 24*60) ||
1925 ptr->GetBlockTime() < (GetTime() - chainParams.MaxTipAge()));
1931844a 1926 //else state = (chainActive.Height() < ptr->nHeight - 24*60);
b11963b5 1927 //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()));
9ec75c5e 1928 if (!state)
8e157f52 1929 {
9ec75c5e 1930 lockIBDState = true;
8e157f52 1931 }
9ec75c5e 1932 return state;
0a61b0df 1933}
1934
0ba20651
MT
1935// determine if we are in sync with the best chain
1936bool IsInSync()
1937{
1938 const CChainParams& chainParams = Params();
1939 LOCK(cs_main);
1940 if (fImporting || fReindex)
1941 {
1942 //fprintf(stderr,"IsInitialBlockDownload: fImporting %d || %d fReindex\n",(int32_t)fImporting,(int32_t)fReindex);
1943 return false;
1944 }
1945 if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
1946 {
1947 //fprintf(stderr,"IsInitialBlockDownload: checkpoint -> initialdownload\n");
1948 return false;
1949 }
1950 CBlockIndex *ptr = chainActive.Tip();
1951 if ( !ptr )
1952 return false;
1953 else if ( pindexBestHeader != 0 && (pindexBestHeader->nHeight - 1) > ptr->nHeight )
1954 return false;
1955
1956 return true;
1957}
1958
b8585384 1959bool fLargeWorkForkFound = false;
f65e7092 1960bool fLargeWorkInvalidChainFound = false;
b8585384
MC
1961CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
1962
1963void CheckForkWarningConditions()
1964{
e07c943c 1965 AssertLockHeld(cs_main);
55ed3f14
MC
1966 // Before we get past initial download, we cannot reliably alert about forks
1967 // (we assume we don't get stuck on a fork before the last checkpoint)
1968 if (IsInitialBlockDownload())
1969 return;
8d655683 1970
d4388ed5 1971 // If our best fork is no longer within 288 blocks (+/- 12 hours if no one mines it)
b8585384 1972 // of our head, drop it
d4388ed5 1973 if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 288)
b8585384 1974 pindexBestForkTip = NULL;
8d655683 1975
86131275 1976 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.LastTip()->nChainWork + (GetBlockProof(*chainActive.LastTip()) * 6)))
b8585384 1977 {
730b1ed1 1978 if (!fLargeWorkForkFound && pindexBestForkBase)
f89faa25 1979 {
e01a7939 1980 std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
8d655683 1981 pindexBestForkBase->phashBlock->ToString() + std::string("'");
e01a7939 1982 CAlert::Notify(warning, true);
f89faa25 1983 }
730b1ed1 1984 if (pindexBestForkTip && pindexBestForkBase)
f65e7092 1985 {
30c1db1c 1986 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__,
8d655683 1987 pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
1988 pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
f65e7092
MC
1989 fLargeWorkForkFound = true;
1990 }
1991 else
1992 {
57c074e1
TH
1993 std::string warning = std::string("Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.");
1994 LogPrintf("%s: %s\n", warning.c_str(), __func__);
1995 CAlert::Notify(warning, true);
f65e7092
MC
1996 fLargeWorkInvalidChainFound = true;
1997 }
1998 }
1999 else
2000 {
b8585384 2001 fLargeWorkForkFound = false;
f65e7092
MC
2002 fLargeWorkInvalidChainFound = false;
2003 }
b8585384
MC
2004}
2005
2006void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
2007{
e07c943c 2008 AssertLockHeld(cs_main);
b8585384
MC
2009 // If we are on a fork that is sufficiently large, set a warning flag
2010 CBlockIndex* pfork = pindexNewForkTip;
86131275 2011 CBlockIndex* plonger = chainActive.LastTip();
b8585384
MC
2012 while (pfork && pfork != plonger)
2013 {
2014 while (plonger && plonger->nHeight > pfork->nHeight)
2015 plonger = plonger->pprev;
2016 if (pfork == plonger)
2017 break;
2018 pfork = pfork->pprev;
2019 }
8d655683 2020
7e6d23b1 2021 // We define a condition where we should warn the user about as a fork of at least 7 blocks
4e3ac9b0 2022 // with a tip within 72 blocks (+/- 3 hours if no one mines it) of ours
b8585384
MC
2023 // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
2024 // hash rate operating on the fork.
2025 // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
2026 // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
2027 // the 7-block condition and from this always have the most-likely-to-cause-warning fork
2028 if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
8d655683 2029 pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
2030 chainActive.Height() - pindexNewForkTip->nHeight < 72)
b8585384
MC
2031 {
2032 pindexBestForkTip = pindexNewForkTip;
2033 pindexBestForkBase = pfork;
2034 }
8d655683 2035
b8585384
MC
2036 CheckForkWarningConditions();
2037}
2038
f59d8f0b 2039// Requires cs_main.
75f51f2a
PW
2040void Misbehaving(NodeId pnode, int howmuch)
2041{
2042 if (howmuch == 0)
2043 return;
8d655683 2044
75f51f2a
PW
2045 CNodeState *state = State(pnode);
2046 if (state == NULL)
2047 return;
8d655683 2048
75f51f2a 2049 state->nMisbehavior += howmuch;
42bdb117 2050 int banscore = GetArg("-banscore", 101);
dc942e6f 2051 if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
75f51f2a 2052 {
30c1db1c 2053 LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
75f51f2a
PW
2054 state->fShouldBan = true;
2055 } else
30c1db1c 2056 LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
75f51f2a
PW
2057}
2058
64c7ee7e 2059void static InvalidChainFound(CBlockIndex* pindexNew)
0a61b0df 2060{
85eb2cef 2061 if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
85eb2cef 2062 pindexBestInvalid = pindexNew;
8d655683 2063
30c1db1c 2064 LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
8d655683 2065 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
2066 log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
2067 pindexNew->GetBlockTime()));
86131275 2068 CBlockIndex *tip = chainActive.LastTip();
4a374102 2069 assert (tip);
30c1db1c 2070 LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
8d655683 2071 tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
2072 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
b8585384 2073 CheckForkWarningConditions();
0a61b0df 2074}
2075
75f51f2a
PW
2076void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
2077 int nDoS = 0;
2078 if (state.IsInvalid(nDoS)) {
2079 std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
2080 if (it != mapBlockSource.end() && State(it->second)) {
307f7d48 2081 CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
75f51f2a
PW
2082 State(it->second)->rejects.push_back(reject);
2083 if (nDoS > 0)
2084 Misbehaving(it->second, nDoS);
857c61df 2085 }
75f51f2a
PW
2086 }
2087 if (!state.CorruptionPossible()) {
2088 pindex->nStatus |= BLOCK_FAILED_VALID;
51ce901a 2089 setDirtyBlockIndex.insert(pindex);
e17bd583 2090 setBlockIndexCandidates.erase(pindex);
75f51f2a
PW
2091 InvalidChainFound(pindex);
2092 }
857c61df
PW
2093}
2094
8cb98d91 2095void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight)
450cbb09 2096{
0cb91a8d 2097 if (!tx.IsMint()) // mark inputs spent
021f8bc6 2098 {
ab15b2ec 2099 txundo.vprevout.reserve(tx.vin.size());
f28aec01 2100 BOOST_FOREACH(const CTxIn &txin, tx.vin) {
c444c620 2101 CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
2102 unsigned nPos = txin.prevout.n;
8d655683 2103
c444c620 2104 if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
2105 assert(false);
2106 // mark an outpoint spent, and construct undo information
2107 txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
2108 coins->Spend(nPos);
2109 if (coins->vout.size() == 0) {
2110 CTxInUndo& undo = txundo.vprevout.back();
2111 undo.nHeight = coins->nHeight;
2112 undo.fCoinBase = coins->fCoinBase;
2113 undo.nVersion = coins->nVersion;
2114 }
450cbb09
PW
2115 }
2116 }
021f8bc6 2117 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { // spend nullifiers
cc01120a
SB
2118 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
2119 inputs.SetNullifier(nf, true);
d66877af
SB
2120 }
2121 }
021f8bc6 2122 inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
3c760413
SS
2123
2124 // Unorthodox state
2125 if (tx.IsCoinImport()) {
2126 // add a tombstone for the burnTx
2127 AddImportTombstone(tx, inputs, nHeight);
2128 }
2129
450cbb09
PW
2130}
2131
8cb98d91 2132void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
d7621ccf 2133{
2134 CTxUndo txundo;
8cb98d91 2135 UpdateCoins(tx, inputs, txundo, nHeight);
d7621ccf 2136}
2137
307f7d48 2138bool CScriptCheck::operator()() {
2800ce73 2139 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
0cb91a8d
SS
2140 ServerTransactionSignatureChecker checker(ptxTo, nIn, amount, cacheStore, *txdata);
2141 if (!VerifyScript(scriptSig, scriptPubKey, nFlags, checker, consensusBranchId, &error)) {
805344dc 2142 return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
307f7d48 2143 }
2800ce73
PW
2144 return true;
2145}
2146
e079f010 2147int GetSpendHeight(const CCoinsViewCache& inputs)
0a61b0df 2148{
e079f010
JT
2149 LOCK(cs_main);
2150 CBlockIndex* pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2151 return pindexPrev->nHeight + 1;
2152}
f9cae832 2153
e079f010 2154namespace Consensus {
8d655683 2155 bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams)
2156 {
13c51f20
PW
2157 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
2158 // for an attacker to attempt to split the network.
05df3fc6 2159 if (!inputs.HaveInputs(tx))
805344dc 2160 return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
8d655683 2161
b7e4abd6 2162 // are the JoinSplit's requirements met?
ee964faf 2163 if (!inputs.HaveJoinSplitRequirements(tx))
805344dc 2164 return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString()));
8d655683 2165
a372168e
MF
2166 CAmount nValueIn = 0;
2167 CAmount nFees = 0;
05df3fc6 2168 for (unsigned int i = 0; i < tx.vin.size(); i++)
0a61b0df 2169 {
05df3fc6 2170 const COutPoint &prevout = tx.vin[i].prevout;
629d75fa
PW
2171 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2172 assert(coins);
6c8e1cdf 2173
629d75fa 2174 if (coins->IsCoinBase()) {
e079f010
JT
2175 // Ensure that coinbases are matured
2176 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2177 return state.Invalid(
8d655683 2178 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
2179 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
e079f010 2180 }
e980a26d 2181
68334c8d 2182 // ensure that output of coinbases are not still time locked
2183 uint64_t unlockTime = komodo_block_unlocktime(coins->nHeight);
2184 if (nSpendHeight < unlockTime && coins->TotalTxValue() >= ASSETCHAINS_TIMELOCKGTE) {
e980a26d 2185 return state.Invalid(
2186 error("CheckInputs(): tried to spend coinbase that is timelocked until block %d", unlockTime),
2187 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2188 }
8d655683 2189
1d38795f 2190 // Ensure that coinbases cannot be spent to transparent outputs
c0dde76d 2191 // Disabled on regtest
d212ba32
SB
2192 if (fCoinbaseEnforcedProtectionEnabled &&
2193 consensusParams.fCoinbaseMustBeProtected &&
6c8e1cdf 2194 !tx.vout.empty() &&
74329e19 2195 (strcmp(ASSETCHAINS_SYMBOL, "VRSC") != 0 || (nSpendHeight >= 12800 && coins->nHeight >= 12800))) {
358ce266 2196 return state.Invalid(
8d655683 2197 error("CheckInputs(): tried to spend coinbase with transparent outputs"),
2198 REJECT_INVALID, "bad-txns-coinbase-spend-has-transparent-outputs");
1d38795f 2199 }
450cbb09 2200 }
8d655683 2201
4add41a2 2202 // Check for negative or overflow input values
629d75fa 2203 nValueIn += coins->vout[prevout.n].nValue;
782120ca 2204#ifdef KOMODO_ENABLE_INTEREST
86131275 2205 if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight >= 60000 )
782120ca 2206 {
98f68225 2207 if ( coins->vout[prevout.n].nValue >= 10*COIN )
782120ca 2208 {
2209 int64_t interest; int32_t txheight; uint32_t locktime;
c60397dd 2210 if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 )
407de87c 2211 {
86131275 2212 //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);
407de87c 2213 nValueIn += interest;
2214 }
782120ca 2215 }
2216 }
2217#endif
629d75fa 2218 if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
5262fde0 2219 return state.DoS(100, error("CheckInputs(): txin values out of range"),
14e7ffcc 2220 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
8d655683 2221
4add41a2 2222 }
8d655683 2223
942bc467 2224 nValueIn += tx.GetJoinSplitValueIn();
f512cf7c
SB
2225 if (!MoneyRange(nValueIn))
2226 return state.DoS(100, error("CheckInputs(): vpub_old values out of range"),
2227 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
8d655683 2228
0733c1bd 2229 if (nValueIn < tx.GetValueOut())
60aee10d 2230 {
2da1debd 2231 fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str());
2c0218f0 2232 return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f",
407de87c 2233 tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout");
60aee10d 2234 }
450cbb09 2235 // Tally transaction fees
a372168e 2236 CAmount nTxFee = nValueIn - tx.GetValueOut();
2c0218f0 2237 if (nTxFee < 0)
805344dc 2238 return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
14e7ffcc 2239 REJECT_INVALID, "bad-txns-fee-negative");
450cbb09 2240 nFees += nTxFee;
2c0218f0 2241 if (!MoneyRange(nFees))
5262fde0 2242 return state.DoS(100, error("CheckInputs(): nFees out of range"),
14e7ffcc 2243 REJECT_INVALID, "bad-txns-fee-outofrange");
8d655683 2244 return true;
2245 }
e079f010
JT
2246}// namespace Consensus
2247
d55e5e77 2248bool ContextualCheckInputs(
8d655683 2249 const CTransaction& tx,
2250 CValidationState &state,
2251 const CCoinsViewCache &inputs,
2252 bool fScriptChecks,
2253 unsigned int flags,
2254 bool cacheStore,
2255 PrecomputedTransactionData& txdata,
2256 const Consensus::Params& consensusParams,
2257 uint32_t consensusBranchId,
2258 std::vector<CScriptCheck> *pvChecks)
e079f010 2259{
0cb91a8d 2260 if (!tx.IsMint())
e079f010 2261 {
30006a2e
JG
2262 if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) {
2263 return false;
2264 }
8d655683 2265
e079f010
JT
2266 if (pvChecks)
2267 pvChecks->reserve(tx.vin.size());
8d655683 2268
4add41a2
GA
2269 // The first loop above does all the inexpensive checks.
2270 // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
2271 // Helps prevent CPU exhaustion attacks.
8d655683 2272
450cbb09 2273 // Skip ECDSA signature verification when connecting blocks
729b1806 2274 // before the last block chain checkpoint. This is safe because block merkle hashes are
450cbb09 2275 // still computed and checked, and any change will be caught at the next checkpoint.
1d70f4bd 2276 if (fScriptChecks) {
05df3fc6
EL
2277 for (unsigned int i = 0; i < tx.vin.size(); i++) {
2278 const COutPoint &prevout = tx.vin[i].prevout;
629d75fa
PW
2279 const CCoins* coins = inputs.AccessCoins(prevout.hash);
2280 assert(coins);
8d655683 2281
b14bd4df 2282 // Verify signature
be126699 2283 CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata);
f9cae832
PW
2284 if (pvChecks) {
2285 pvChecks->push_back(CScriptCheck());
2286 check.swap(pvChecks->back());
97e7901a 2287 } else if (!check()) {
f80cffa2
PT
2288 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
2289 // Check whether the failure was caused by a
2290 // non-mandatory script verification check, such as
2291 // non-standard DER encodings or non-null dummy
2292 // arguments; if so, don't trigger DoS protection to
2293 // avoid splitting the network between upgraded and
2294 // non-upgraded nodes.
838e7a29 2295 CScriptCheck check2(*coins, tx, i,
8d655683 2296 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata);
838e7a29 2297 if (check2())
307f7d48 2298 return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
97e7901a 2299 }
f80cffa2
PT
2300 // Failures of other flags indicate a transaction that is
2301 // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
2302 // such nodes as they are not following the protocol. That
2303 // said during an upgrade careful thought should be taken
2304 // as to the correct behavior - we may want to continue
2305 // peering with non-upgraded nodes even after a soft-fork
2306 // super-majority vote has passed.
307f7d48 2307 return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
97e7901a 2308 }
2a45a494 2309 }
0a61b0df 2310 }
0a61b0df 2311 }
0cb91a8d
SS
2312
2313 if (tx.IsCoinImport())
2314 {
2315 ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
2316 return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
2317 }
2318
0a61b0df 2319 return true;
2320}
2321
945f015d 2322
2323/*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)
8d655683 2324 {
2325 if (!NonContextualCheckInputs(tx, state, inputs, fScriptChecks, flags, cacheStore, consensusParams, pvChecks)) {
2326 fprintf(stderr,"ContextualCheckInputs failure.0\n");
2327 return false;
2328 }
2329
2330 if (!tx.IsCoinBase())
2331 {
2332 // While checking, GetBestBlock() refers to the parent block.
2333 // This is also true for mempool checks.
2334 CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
2335 int nSpendHeight = pindexPrev->nHeight + 1;
2336 for (unsigned int i = 0; i < tx.vin.size(); i++)
2337 {
2338 const COutPoint &prevout = tx.vin[i].prevout;
2339 const CCoins *coins = inputs.AccessCoins(prevout.hash);
2340 // Assertion is okay because NonContextualCheckInputs ensures the inputs
2341 // are available.
2342 assert(coins);
2343
2344 // If prev is coinbase, check that it's matured
2345 if (coins->IsCoinBase()) {
2346 if ( ASSETCHAINS_SYMBOL[0] == 0 )
2347 COINBASE_MATURITY = _COINBASE_MATURITY;
2348 if (nSpendHeight - coins->nHeight < COINBASE_MATURITY) {
2349 fprintf(stderr,"ContextualCheckInputs failure.1 i.%d of %d\n",i,(int32_t)tx.vin.size());
2350
2351 return state.Invalid(
2352 error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
2353 }
2354 }
2355 }
2356 }
2357
2358 return true;
2359 }*/
89f3cd11 2360
8d655683 2361namespace {
2362
2363 bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
2c901fd8 2364 {
8d655683 2365 // Open history file to append
2366 CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
2367 if (fileout.IsNull())
2368 return error("%s: OpenUndoFile failed", __func__);
2369
2370 // Write index header
2371 unsigned int nSize = fileout.GetSerializeSize(blockundo);
2372 fileout << FLATDATA(messageStart) << nSize;
2373
2374 // Write undo data
2375 long fileOutPos = ftell(fileout.Get());
2376 if (fileOutPos < 0)
2377 return error("%s: ftell failed", __func__);
2378 pos.nPos = (unsigned int)fileOutPos;
2379 fileout << blockundo;
2380
2381 // calculate & write checksum
2382 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2383 hasher << hashBlock;
2384 hasher << blockundo;
2385 fileout << hasher.GetHash();
2386
2387 return true;
2c901fd8 2388 }
8d655683 2389
2390 bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
2391 {
2392 // Open history file to read
2393 CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
2394 if (filein.IsNull())
2395 return error("%s: OpenBlockFile failed", __func__);
2396
2397 // Read block
2398 uint256 hashChecksum;
2399 try {
2400 filein >> blockundo;
2401 filein >> hashChecksum;
2c901fd8 2402 }
8d655683 2403 catch (const std::exception& e) {
2404 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2405 }
8d655683 2406 // Verify checksum
2407 CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
2408 hasher << hashBlock;
2409 hasher << blockundo;
2410 if (hashChecksum != hasher.GetHash())
2411 return error("%s: Checksum mismatch", __func__);
2412
2413 return true;
2c901fd8 2414 }
8d655683 2415
2416 /** Abort with a message */
2417 bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
2418 {
2419 strMiscWarning = strMessage;
2420 LogPrintf("*** %s\n", strMessage);
2421 uiInterface.ThreadSafeMessageBox(
2422 userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
2423 "", CClientUIInterface::MSG_ERROR);
2424 StartShutdown();
2425 return false;
87fb3108 2426 }
8d655683 2427
2428 bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
2429 {
2430 AbortNode(strMessage, userMessage);
2431 return state.Error(strMessage);
87fb3108 2432 }
8d655683 2433
87fb3108 2434} // anon namespace
0a61b0df 2435
eb1c2cd3
DK
2436/**
2437 * Apply the undo operation of a CTxInUndo to the given chain state.
2438 * @param undo The undo object.
2439 * @param view The coins view to which to apply the changes.
2440 * @param out The out point that corresponds to the tx input.
2441 * @return True on success.
2442 */
2443static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
2444{
2445 bool fClean = true;
8d655683 2446
eb1c2cd3
DK
2447 CCoinsModifier coins = view.ModifyCoins(out.hash);
2448 if (undo.nHeight != 0) {
2449 // undo data contains height: this is the last output of the prevout tx being spent
2450 if (!coins->IsPruned())
2451 fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
2452 coins->Clear();
2453 coins->fCoinBase = undo.fCoinBase;
2454 coins->nHeight = undo.nHeight;
2455 coins->nVersion = undo.nVersion;
2456 } else {
2457 if (coins->IsPruned())
2458 fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
2459 }
2460 if (coins->IsAvailable(out.n))
2461 fClean = fClean && error("%s: undo data overwriting existing output", __func__);
2462 if (coins->vout.size() < out.n+1)
2463 coins->vout.resize(out.n+1);
2464 coins->vout[out.n] = undo.txout;
8d655683 2465
eb1c2cd3
DK
2466 return fClean;
2467}
2468
84964112
SS
2469
2470void ConnectNotarisations(const CBlock &block, int height)
2471{
2472 // Record Notarisations
2473 NotarisationsInBlock notarisations = ScanBlockNotarisations(block, height);
2474 if (notarisations.size() > 0) {
2475 CLevelDBBatch batch;
2476 batch.Write(block.GetHash(), notarisations);
2477 WriteBackNotarisations(notarisations, batch);
2478 pnotarisations->WriteBatch(batch, true);
2479 LogPrintf("ConnectBlock: wrote %i block notarisations in block: %s\n",
2480 notarisations.size(), block.GetHash().GetHex().data());
2481 }
2482}
2483
2484
2485void DisconnectNotarisations(const CBlock &block)
2486{
2487 // Delete from notarisations cache
2488 NotarisationsInBlock nibs;
2489 if (GetBlockNotarisations(block.GetHash(), nibs)) {
2490 CLevelDBBatch batch;
2491 batch.Erase(block.GetHash());
2492 EraseBackNotarisations(nibs, batch);
2493 pnotarisations->WriteBatch(batch, true);
2494 LogPrintf("DisconnectTip: deleted %i block notarisations in block: %s\n",
2495 nibs.size(), block.GetHash().GetHex().data());
2496 }
2497}
2498
2499
5c363ed6 2500bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
0a61b0df 2501{
84674082 2502 assert(pindex->GetBlockHash() == view.GetBestBlock());
8d655683 2503
2cbd71da
PW
2504 if (pfClean)
2505 *pfClean = false;
8d655683 2506
2cbd71da 2507 bool fClean = true;
4355e769 2508 komodo_disconnect(pindex,block);
450cbb09 2509 CBlockUndo blockUndo;
8539361e
PW
2510 CDiskBlockPos pos = pindex->GetUndoPos();
2511 if (pos.IsNull())
5262fde0 2512 return error("DisconnectBlock(): no undo data available");
e035c6a7 2513 if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
5262fde0 2514 return error("DisconnectBlock(): failure reading undo data");
8d655683 2515
5c363ed6 2516 if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
5262fde0 2517 return error("DisconnectBlock(): block and undo data inconsistent");
8b78a819
T
2518 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2519 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2520 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
450cbb09
PW
2521
2522 // undo transactions in reverse order
5c363ed6
EL
2523 for (int i = block.vtx.size() - 1; i >= 0; i--) {
2524 const CTransaction &tx = block.vtx[i];
805344dc 2525 uint256 hash = tx.GetHash();
8b78a819 2526 if (fAddressIndex) {
450cbb09 2527
8b78a819
T
2528 for (unsigned int k = tx.vout.size(); k-- > 0;) {
2529 const CTxOut &out = tx.vout[k];
2530
2531 if (out.scriptPubKey.IsPayToScriptHash()) {
2532 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
2533
2534 // undo receiving activity
2535 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2536
2537 // undo unspent index
2538 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2539
fa7bf712 2540 }
2541 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
8b78a819
T
2542 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
2543
2544 // undo receiving activity
2545 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2546
2547 // undo unspent index
2548 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), hash, k), CAddressUnspentValue()));
2549
fa7bf712 2550 }
2551 else if (out.scriptPubKey.IsPayToPublicKey()) {
2552 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
2553
2554 // undo receiving activity
31e2a04e 2555 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
fa7bf712 2556
2557 // undo unspent index
31e2a04e 2558 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
fa7bf712 2559
7f190223 2560 }
2561 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
2562 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
2563
2564 // undo receiving activity
2565 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, k, false), out.nValue));
2566
2567 // undo unspent index
2568 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), hash, k), CAddressUnspentValue()));
2569
fa7bf712 2570 }
2571 else {
8b78a819
T
2572 continue;
2573 }
450cbb09 2574
8b78a819 2575 }
c7a3aca6 2576
f28aec01 2577 }
450cbb09 2578
170e02de 2579 // Check that all outputs are available and match the outputs in the block itself
eb1c2cd3 2580 // exactly.
f28aec01 2581 {
8d655683 2582 CCoinsModifier outs = view.ModifyCoins(hash);
2583 outs->ClearUnspendable();
2584
2585 CCoins outsBlock(tx, pindex->nHeight);
2586 // The CCoins serialization does not serialize negative numbers.
2587 // No network rules currently depend on the version here, so an inconsistency is harmless
2588 // but it must be corrected before txout nversion ever influences a network rule.
2589 if (outsBlock.nVersion < 0)
2590 outs->nVersion = outsBlock.nVersion;
2591 if (*outs != outsBlock)
2592 fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
2593
2594 // remove outputs
2595 outs->Clear();
f28aec01 2596 }
8d655683 2597
bfeaf004 2598 // unspend nullifiers
b7e4abd6 2599 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
cc01120a
SB
2600 BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
2601 view.SetNullifier(nf, false);
d66877af
SB
2602 }
2603 }
8d655683 2604
450cbb09 2605 // restore inputs
0cb91a8d 2606 if (!tx.IsMint()) {
450cbb09 2607 const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2cbd71da 2608 if (txundo.vprevout.size() != tx.vin.size())
5262fde0 2609 return error("DisconnectBlock(): transaction and undo data inconsistent");
450cbb09
PW
2610 for (unsigned int j = tx.vin.size(); j-- > 0;) {
2611 const COutPoint &out = tx.vin[j].prevout;
2612 const CTxInUndo &undo = txundo.vprevout[j];
eb1c2cd3
DK
2613 if (!ApplyTxInUndo(undo, view, out))
2614 fClean = false;
8b78a819
T
2615
2616 const CTxIn input = tx.vin[j];
2617
2618 if (fSpentIndex) {
2619 // undo and delete the spent index
2620 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
2621 }
2622
2623 if (fAddressIndex) {
2624 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2625 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2626 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
2627
2628 // undo spending activity
2629 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2630
2631 // restore unspent index
2632 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2633
2634
fa7bf712 2635 }
2636 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
8b78a819
T
2637 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
2638
2639 // undo spending activity
2640 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2641
2642 // restore unspent index
2643 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2644
fa7bf712 2645 }
2646 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
2647 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34);
2648
2649 // undo spending activity
dc276bd0 2650 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
fa7bf712 2651
2652 // restore unspent index
dc276bd0 2653 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
fa7bf712 2654
7f190223 2655 }
2656 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2657 vector<unsigned char> hashBytes(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end());
2658
2659 // undo spending activity
2660 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, hash, j, true), prevout.nValue * -1));
2661
2662 // restore unspent index
2663 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue(prevout.nValue, prevout.scriptPubKey, undo.nHeight)));
2664
fa7bf712 2665 }
2666 else {
8b78a819
T
2667 continue;
2668 }
2669 }
450cbb09
PW
2670 }
2671 }
3c760413
SS
2672 else if (tx.IsCoinImport())
2673 {
2674 RemoveImportTombstone(tx, view);
2675 }
450cbb09 2676 }
69c67b51 2677
a8ac403d
SB
2678 // set the old best anchor back
2679 view.PopAnchor(blockUndo.old_tree_root);
8d655683 2680
450cbb09 2681 // move best block pointer to prevout block
84674082 2682 view.SetBestBlock(pindex->pprev->GetBlockHash());
8d655683 2683
2cbd71da
PW
2684 if (pfClean) {
2685 *pfClean = fClean;
2686 return true;
2cbd71da 2687 }
eb1c2cd3 2688
8b78a819
T
2689 if (fAddressIndex) {
2690 if (!pblocktree->EraseAddressIndex(addressIndex)) {
2691 return AbortNode(state, "Failed to delete address index");
2692 }
2693 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
2694 return AbortNode(state, "Failed to write address unspent index");
2695 }
2696 }
69c67b51 2697
eb1c2cd3 2698 return fClean;
0a61b0df 2699}
2700
1eb57879 2701void static FlushBlockFile(bool fFinalize = false)
44d40f26
PW
2702{
2703 LOCK(cs_LastBlockFile);
8d655683 2704
a8a4b967 2705 CDiskBlockPos posOld(nLastBlockFile, 0);
8d655683 2706
44d40f26 2707 FILE *fileOld = OpenBlockFile(posOld);
b19388dd 2708 if (fileOld) {
1eb57879 2709 if (fFinalize)
ed6d1a2c 2710 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
b19388dd
PK
2711 FileCommit(fileOld);
2712 fclose(fileOld);
2713 }
8d655683 2714
44d40f26 2715 fileOld = OpenUndoFile(posOld);
b19388dd 2716 if (fileOld) {
1eb57879 2717 if (fFinalize)
ed6d1a2c 2718 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
b19388dd
PK
2719 FileCommit(fileOld);
2720 fclose(fileOld);
2721 }
44d40f26
PW
2722}
2723
ef3988ca 2724bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
5382bcf8 2725
f9cae832
PW
2726static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
2727
21eb5ada 2728void ThreadScriptCheck() {
7662d72b 2729 RenameThread("zcash-scriptch");
f9cae832 2730 scriptcheckqueue.Thread();
f9cae832
PW
2731}
2732
36cba8f1
GA
2733//
2734// Called periodically asynchronously; alerts if it smells like
2735// we're being fed a bad chain (blocks being generated much
2736// too slowly or too quickly).
2737//
fce474c9
GA
2738void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
2739 int64_t nPowTargetSpacing)
36cba8f1 2740{
fce474c9 2741 if (bestHeader == NULL || initialDownloadCheck()) return;
8d655683 2742
36cba8f1
GA
2743 static int64_t lastAlertTime = 0;
2744 int64_t now = GetAdjustedTime();
2745 if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
8d655683 2746
36cba8f1
GA
2747 const int SPAN_HOURS=4;
2748 const int SPAN_SECONDS=SPAN_HOURS*60*60;
2749 int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
8d655683 2750
36cba8f1 2751 boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
8d655683 2752
36cba8f1
GA
2753 std::string strWarning;
2754 int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
8d655683 2755
36cba8f1 2756 LOCK(cs);
fce474c9
GA
2757 const CBlockIndex* i = bestHeader;
2758 int nBlocks = 0;
2759 while (i->GetBlockTime() >= startTime) {
2760 ++nBlocks;
2761 i = i->pprev;
c938fb1f 2762 if (i == NULL) return; // Ran out of chain, we must not be fully synced
fce474c9 2763 }
8d655683 2764
36cba8f1
GA
2765 // How likely is it to find that many by chance?
2766 double p = boost::math::pdf(poisson, nBlocks);
8d655683 2767
36cba8f1
GA
2768 LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
2769 LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
8d655683 2770
36cba8f1
GA
2771 // Aim for one false-positive about every fifty years of normal running:
2772 const int FIFTY_YEARS = 50*365*24*60*60;
2773 double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
8d655683 2774
68334c8d 2775 if (bestHeader->nHeight > BLOCKS_EXPECTED)
36cba8f1 2776 {
68334c8d 2777 if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
2778 {
2779 // Many fewer blocks than expected: alert!
2780 strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
2781 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
2782 }
2783 else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
2784 {
2785 // Many more blocks than expected: alert!
2786 strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
2787 nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
2788 }
36cba8f1
GA
2789 }
2790 if (!strWarning.empty())
2791 {
2792 strMiscWarning = strWarning;
2793 CAlert::Notify(strWarning, true);
2794 lastAlertTime = now;
2795 }
2796}
2797
20c3ac51 2798
d70bc52e
PW
2799static int64_t nTimeVerify = 0;
2800static int64_t nTimeConnect = 0;
2801static int64_t nTimeIndex = 0;
2802static int64_t nTimeCallbacks = 0;
2803static int64_t nTimeTotal = 0;
2804
96f9009e 2805bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW)
0a61b0df 2806{
4e382177 2807 const CChainParams& chainparams = Params();
6d2fc290 2808 if ( KOMODO_STOPAT != 0 && pindex->nHeight > KOMODO_STOPAT )
2809 return(false);
e0440cc3 2810 //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->nHeight);
b39a07dc 2811 AssertLockHeld(cs_main);
bfa832c7
PW
2812 bool fExpensiveChecks = true;
2813 if (fCheckpointsEnabled) {
2814 CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints());
2815 if (pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex) {
2816 // This block is an ancestor of a checkpoint: disable script checks
2817 fExpensiveChecks = false;
2818 }
2819 }
6fb8d0c2
JG
2820 auto verifier = libzcash::ProofVerifier::Strict();
2821 auto disabledVerifier = libzcash::ProofVerifier::Disabled();
9f6cb8f0 2822 int32_t futureblock;
6fb8d0c2 2823 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
9840ae39 2824 if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck) || futureblock != 0 )
cdb2a22f 2825 {
4342e69b 2826 //fprintf(stderr,"checkblock failure in connectblock futureblock.%d\n",futureblock);
0a61b0df 2827 return false;
cdb2a22f 2828 }
8d655683 2829
450cbb09 2830 // verify that the view's current state corresponds to the previous block
4f152496 2831 uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
e3b04fea 2832 if ( hashPrevBlock != view.GetBestBlock() )
2833 {
2834 fprintf(stderr,"ConnectBlock(): hashPrevBlock != view.GetBestBlock()\n");
2835 return state.DoS(1, error("ConnectBlock(): hashPrevBlock != view.GetBestBlock()"),
2836 REJECT_INVALID, "hashPrevBlock-not-bestblock");
2837 }
84674082 2838 assert(hashPrevBlock == view.GetBestBlock());
8d655683 2839
8301ff50
PW
2840 // Special case for the genesis block, skipping connection of its transactions
2841 // (its coinbase is unspendable)
4e382177 2842 if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
6a7acc29 2843 if (!fJustCheck) {
1b178a7f 2844 view.SetBestBlock(pindex->GetBlockHash());
6a7acc29
JG
2845 // Before the genesis block, there was an empty tree
2846 ZCIncrementalMerkleTree tree;
2847 pindex->hashAnchor = tree.root();
0bc1e2c4
JG
2848 // The genesis block contained no JoinSplits
2849 pindex->hashAnchorEnd = pindex->hashAnchor;
6a7acc29 2850 }
8301ff50
PW
2851 return true;
2852 }
8d655683 2853
a8cdaf5c 2854 bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
f8b5c164 2855 //if ( KOMODO_TESTNET_EXPIRATION != 0 && pindex->nHeight > KOMODO_TESTNET_EXPIRATION ) // "testnet"
2856 // return(false);
a206b0ea
PW
2857 // Do not allow blocks that contain transactions which 'overwrite' older transactions,
2858 // unless those are already completely spent.
b3be1ef5 2859 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
805344dc 2860 const CCoins* coins = view.AccessCoins(tx.GetHash());
b3be1ef5
SB
2861 if (coins && !coins->IsPruned())
2862 return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
2863 REJECT_INVALID, "bad-txns-BIP30");
450cbb09 2864 }
8d655683 2865
de609b8c 2866 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
8d655683 2867
de609b8c 2868 // DERSIG (BIP66) is also always enforced, but does not have a flag.
8d655683 2869
8adf48dc 2870 CBlockUndo blockundo;
8d655683 2871
c66eb36d 2872 if ( ASSETCHAINS_CC != 0 )
2873 {
163b0aa7 2874 if ( scriptcheckqueue.IsIdle() == 0 )
c66eb36d 2875 {
2876 fprintf(stderr,"scriptcheckqueue isnt idle\n");
2877 sleep(1);
2878 }
2879 }
6fb8d0c2 2880 CCheckQueueControl<CScriptCheck> control(fExpensiveChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
8d655683 2881
d70bc52e 2882 int64_t nTimeStart = GetTimeMicros();
a372168e 2883 CAmount nFees = 0;
8a28bb6d 2884 int nInputs = 0;
355ca565 2885 int64_t interest,sum = 0;
7bd9c3a3 2886 unsigned int nSigOps = 0;
f3ae51dc 2887 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
2d1fa42e 2888 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
f3ae51dc 2889 vPos.reserve(block.vtx.size());
ab15b2ec 2890 blockundo.vtxundo.reserve(block.vtx.size() - 1);
8b78a819
T
2891 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2892 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2893 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
a8ac403d
SB
2894 // Construct the incremental merkle tree at the current
2895 // block position,
2896 auto old_tree_root = view.GetBestAnchor();
b6961fc1 2897 // saving the top anchor in the block index as we go.
6a7acc29
JG
2898 if (!fJustCheck) {
2899 pindex->hashAnchor = old_tree_root;
2900 }
434f3284 2901 ZCIncrementalMerkleTree tree;
a8ac403d
SB
2902 // This should never fail: we should always be able to get the root
2903 // that is on the tip of our chain
2904 assert(view.GetAnchorAt(old_tree_root, tree));
8d655683 2905
a8ac403d
SB
2906 {
2907 // Consistency check: the root of the tree we're given should
2908 // match what we asked for.
434f3284 2909 assert(tree.root() == old_tree_root);
a8ac403d 2910 }
8d655683 2911
be126699
JG
2912 // Grab the consensus branch ID for the block's height
2913 auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus());
8d655683 2914
6514771a
PW
2915 std::vector<PrecomputedTransactionData> txdata;
2916 txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
f3ae51dc 2917 for (unsigned int i = 0; i < block.vtx.size(); i++)
0a61b0df 2918 {
f3ae51dc 2919 const CTransaction &tx = block.vtx[i];
8b78a819 2920 const uint256 txhash = tx.GetHash();
8a28bb6d 2921 nInputs += tx.vin.size();
05df3fc6 2922 nSigOps += GetLegacySigOpCount(tx);
137d0685 2923 if (nSigOps > MAX_BLOCK_SIGOPS)
5262fde0 2924 return state.DoS(100, error("ConnectBlock(): too many sigops"),
14e7ffcc 2925 REJECT_INVALID, "bad-blk-sigops");
8d655683 2926 //fprintf(stderr,"ht.%d vout0 t%u\n",pindex->nHeight,tx.nLockTime);
0cb91a8d 2927 if (!tx.IsMint())
8d7849b6 2928 {
05df3fc6 2929 if (!view.HaveInputs(tx))
a9bad5a3 2930 {
5262fde0 2931 return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
14e7ffcc 2932 REJECT_INVALID, "bad-txns-inputs-missingorspent");
a9bad5a3 2933 }
b7e4abd6 2934 // are the JoinSplit's requirements met?
ee964faf 2935 if (!view.HaveJoinSplitRequirements(tx))
b7e4abd6
SB
2936 return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"),
2937 REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met");
8b78a819
T
2938 if (fAddressIndex || fSpentIndex)
2939 {
2940 for (size_t j = 0; j < tx.vin.size(); j++) {
2941
2942 const CTxIn input = tx.vin[j];
2943 const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
2944 uint160 hashBytes;
2945 int addressType;
2946
2947 if (prevout.scriptPubKey.IsPayToScriptHash()) {
2948 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22));
2949 addressType = 2;
fa7bf712 2950 }
2951 else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
8b78a819
T
2952 hashBytes = uint160(vector <unsigned char>(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23));
2953 addressType = 1;
fa7bf712 2954 }
2955 else if (prevout.scriptPubKey.IsPayToPublicKey()) {
31e2a04e 2956 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin()+1, prevout.scriptPubKey.begin()+34));
dc276bd0 2957 addressType = 1;
fa7bf712 2958 }
7f190223 2959 else if (prevout.scriptPubKey.IsPayToCryptoCondition()) {
2960 hashBytes = Hash160(vector <unsigned char>(prevout.scriptPubKey.begin(), prevout.scriptPubKey.end()));
2961 addressType = 1;
2962 }
fa7bf712 2963 else {
8b78a819
T
2964 hashBytes.SetNull();
2965 addressType = 0;
2966 }
2967
2968 if (fAddressIndex && addressType > 0) {
2969 // record spending activity
2970 addressIndex.push_back(make_pair(CAddressIndexKey(addressType, hashBytes, pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
2971
2972 // remove address from unspent index
2973 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(addressType, hashBytes, input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
2974 }
2975
2976 if (fSpentIndex) {
2977 // add the spent index to determine the txid and input that spent an output
2978 // and to find the amount and address from an input
2979 spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight, prevout.nValue, addressType, hashBytes)));
2980 }
2981 }
a8ac403d 2982
8b78a819 2983 }
b3be1ef5
SB
2984 // Add in sigops done by pay-to-script-hash inputs;
2985 // this is to prevent a "rogue miner" from creating
2986 // an incredibly-expensive-to-validate block.
2987 nSigOps += GetP2SHSigOpCount(tx, view);
2988 if (nSigOps > MAX_BLOCK_SIGOPS)
2989 return state.DoS(100, error("ConnectBlock(): too many sigops"),
2990 REJECT_INVALID, "bad-blk-sigops");
f762d449 2991 }
8d655683 2992
6514771a 2993 txdata.emplace_back(tx);
8d655683 2994
f762d449
PW
2995 if (!tx.IsCoinBase())
2996 {
86131275 2997 nFees += view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime) - tx.GetValueOut();
355ca565 2998 sum += interest;
8d655683 2999
f9cae832 3000 std::vector<CScriptCheck> vChecks;
be126699 3001 if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
40634605 3002 return false;
f9cae832 3003 control.Add(vChecks);
8d7849b6 3004 }
8b78a819
T
3005
3006 if (fAddressIndex) {
3007 for (unsigned int k = 0; k < tx.vout.size(); k++) {
3008 const CTxOut &out = tx.vout[k];
ba31c2f4 3009//fprintf(stderr,"add %d vouts\n",(int32_t)tx.vout.size());
8b78a819
T
3010 if (out.scriptPubKey.IsPayToScriptHash()) {
3011 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
3012
3013 // record receiving activity
3014 addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3015
3016 // record unspent output
3017 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3018
fa7bf712 3019 }
3020 else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
8b78a819
T
3021 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
3022
3023 // record receiving activity
3024 addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3025
3026 // record unspent output
3027 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3028
fa7bf712 3029 }
3030 else if (out.scriptPubKey.IsPayToPublicKey()) {
3031 vector<unsigned char> hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34);
3032
3033 // record receiving activity
dc276bd0 3034 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
fa7bf712 3035
3036 // record unspent output
dc276bd0 3037 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
fa7bf712 3038
7f190223 3039 }
3040 else if (out.scriptPubKey.IsPayToCryptoCondition()) {
3041 vector<unsigned char> hashBytes(out.scriptPubKey.begin(), out.scriptPubKey.end());
3042
3043 // record receiving activity
3044 addressIndex.push_back(make_pair(CAddressIndexKey(1, Hash160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
3045
3046 // record unspent output
3047 addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, Hash160(hashBytes), txhash, k), CAddressUnspentValue(out.nValue, out.scriptPubKey, pindex->nHeight)));
3048
fa7bf712 3049 }
3050 else {
8b78a819
T
3051 continue;
3052 }
3053
3054 }
3055 }
3056
314350e6 3057 //if ( ASSETCHAINS_SYMBOL[0] == 0 )
3058 // komodo_earned_interest(pindex->nHeight,sum);
ab15b2ec
PW
3059 CTxUndo undoDummy;
3060 if (i > 0) {
3061 blockundo.vtxundo.push_back(CTxUndo());
3062 }
8cb98d91 3063 UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
8d655683 3064
b7e4abd6 3065 BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
4bc00dc1
DH
3066 BOOST_FOREACH(const uint256 &note_commitment, joinsplit.commitments) {
3067 // Insert the note commitments into our temporary tree.
8d655683 3068
4bc00dc1 3069 tree.append(note_commitment);
a8ac403d
SB
3070 }
3071 }
8d655683 3072
805344dc 3073 vPos.push_back(std::make_pair(tx.GetHash(), pos));
2d1fa42e 3074 pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
0a61b0df 3075 }
7702587d 3076
a8ac403d 3077 view.PushAnchor(tree);
0bc1e2c4
JG
3078 if (!fJustCheck) {
3079 pindex->hashAnchorEnd = tree.root();
3080 }
a8ac403d 3081 blockundo.old_tree_root = old_tree_root;
8d655683 3082
d70bc52e
PW
3083 int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
3084 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);
8d655683 3085
6b30b27c 3086 CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()) + sum;
18443f69 3087 if ( ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 )
de4a435c 3088 {
3089 uint64_t checktoshis;
18443f69 3090 if ( (checktoshis= komodo_commission((CBlock *)&block)) != 0 )
de4a435c 3091 {
3092 if ( block.vtx[0].vout.size() == 2 && block.vtx[0].vout[1].nValue == checktoshis )
b7dc5699 3093 blockReward += checktoshis;
2808b68f 3094 else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size());
de4a435c 3095 }
3096 }
3d3a117b
MT
3097 if (ASSETCHAINS_SYMBOL[0] != 0 && pindex->nHeight == 1 && block.vtx[0].GetValueOut() != blockReward)
3098 {
3099 return state.DoS(100, error("ConnectBlock(): coinbase for block 1 pays wrong amount (actual=%d vs correct=%d)", block.vtx[0].GetValueOut(), blockReward),
3100 REJECT_INVALID, "bad-cb-amount");
3101 }
cf7f4402 3102 if ( block.vtx[0].GetValueOut() > blockReward+1 )
0b652b66 3103 {
ea124428 3104 if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward )
0b652b66 3105 {
3106 return state.DoS(100,
8d655683 3107 error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
3108 block.vtx[0].GetValueOut(), blockReward),
3109 REJECT_INVALID, "bad-cb-amount");
4d068367 3110 } else if ( IS_KOMODO_NOTARY != 0 )
cf7f4402 3111 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));
0b652b66 3112 }
f9cae832 3113 if (!control.Wait())
ef3988ca 3114 return state.DoS(100, false);
d70bc52e
PW
3115 int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
3116 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);
8d655683 3117
3cd01fdf
LD
3118 if (fJustCheck)
3119 return true;
8d655683 3120
5382bcf8 3121 // Write undo information to disk
942b33a1 3122 if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
5382bcf8 3123 {
857c61df
PW
3124 if (pindex->GetUndoPos().IsNull()) {
3125 CDiskBlockPos pos;
ef3988ca 3126 if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
5262fde0 3127 return error("ConnectBlock(): FindUndoPos failed");
e6973430 3128 if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
27afcd89 3129 return AbortNode(state, "Failed to write undo data");
8d655683 3130
857c61df
PW
3131 // update nUndoPos in block index
3132 pindex->nUndoPos = pos.nPos;
3133 pindex->nStatus |= BLOCK_HAVE_UNDO;
3134 }
8d655683 3135
828940b1 3136 // Now that all consensus rules have been validated, set nCachedBranchId.
9e851450
JG
3137 // Move this if BLOCK_VALID_CONSENSUS is ever altered.
3138 static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS,
8d655683 3139 "nCachedBranchId must be set after all consensus rules have been validated.");
9e851450
JG
3140 if (IsActivationHeightForAnyUpgrade(pindex->nHeight, Params().GetConsensus())) {
3141 pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE;
828940b1 3142 pindex->nCachedBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus());
9e851450 3143 } else if (pindex->pprev) {
828940b1 3144 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
9e851450 3145 }
8d655683 3146
942b33a1 3147 pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
51ce901a 3148 setDirtyBlockIndex.insert(pindex);
0a61b0df 3149 }
84638476 3150
84964112 3151 ConnectNotarisations(block, pindex->nHeight);
8d655683 3152
2d1fa42e 3153 if (fTxIndex)
ef3988ca 3154 if (!pblocktree->WriteTxIndex(vPos))
27afcd89 3155 return AbortNode(state, "Failed to write transaction index");
8b78a819
T
3156 if (fAddressIndex) {
3157 if (!pblocktree->WriteAddressIndex(addressIndex)) {
3158 return AbortNode(state, "Failed to write address index");
3159 }
3160
3161 if (!pblocktree->UpdateAddressUnspentIndex(addressUnspentIndex)) {
3162 return AbortNode(state, "Failed to write address unspent index");
3163 }
3164 }
3165
3166 if (fSpentIndex)
3167 if (!pblocktree->UpdateSpentIndex(spentIndex))
3168 return AbortNode(state, "Failed to write transaction index");
3169
3170 if (fTimestampIndex) {
3171 unsigned int logicalTS = pindex->nTime;
3172 unsigned int prevLogicalTS = 0;
3173
3174 // retrieve logical timestamp of the previous block
3175 if (pindex->pprev)
3176 if (!pblocktree->ReadTimestampBlockIndex(pindex->pprev->GetBlockHash(), prevLogicalTS))
3177 LogPrintf("%s: Failed to read previous block's logical timestamp\n", __func__);
3178
3179 if (logicalTS <= prevLogicalTS) {
3180 logicalTS = prevLogicalTS + 1;
3181 LogPrintf("%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->nTime, prevLogicalTS, logicalTS);
3182 }
3183
3184 if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(logicalTS, pindex->GetBlockHash())))
3185 return AbortNode(state, "Failed to write timestamp index");
3186
3187 if (!pblocktree->WriteTimestampBlockIndex(CTimestampBlockIndexKey(pindex->GetBlockHash()), CTimestampBlockIndexValue(logicalTS)))
3188 return AbortNode(state, "Failed to write blockhash index");
3189 }
2d1fa42e 3190
729b1806 3191 // add this block to the view's block chain
c9d1a81c 3192 view.SetBestBlock(pindex->GetBlockHash());
8d655683 3193
d70bc52e
PW
3194 int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
3195 LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
8d655683 3196
202e0194
PW
3197 // Watch for changes to the previous coinbase transaction.
3198 static uint256 hashPrevBestCoinBase;
26c16d9d 3199 GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
805344dc 3200 hashPrevBestCoinBase = block.vtx[0].GetHash();
8d655683 3201
d70bc52e
PW
3202 int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
3203 LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
a0344f90 3204
0f42af4c 3205 //FlushStateToDisk();
651989c7 3206 komodo_connectblock(pindex,*(CBlock *)&block);
0a61b0df 3207 return true;
3208}
3209
a2069500 3210enum FlushStateMode {
f9ec3f0f 3211 FLUSH_STATE_NONE,
a2069500
PW
3212 FLUSH_STATE_IF_NEEDED,
3213 FLUSH_STATE_PERIODIC,
3214 FLUSH_STATE_ALWAYS
3215};
3216
51ce901a
PW
3217/**
3218 * Update the on-disk chain state.
f9ec3f0f 3219 * The caches and indexes are flushed depending on the mode we're called with
3220 * if they're too large, if it's been a while since the last write,
3221 * or always and in all cases if we're in prune mode and are deleting files.
51ce901a 3222 */
a2069500 3223bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
f9ec3f0f 3224 LOCK2(cs_main, cs_LastBlockFile);
75f51f2a 3225 static int64_t nLastWrite = 0;
67708acf
PW
3226 static int64_t nLastFlush = 0;
3227 static int64_t nLastSetChain = 0;
f9ec3f0f 3228 std::set<int> setFilesToPrune;
3229 bool fFlushForPrune = false;
e4134579 3230 try {
8d655683 3231 if (fPruneMode && fCheckForPruning && !fReindex) {
3232 FindFilesToPrune(setFilesToPrune);
3233 fCheckForPruning = false;
3234 if (!setFilesToPrune.empty()) {
3235 fFlushForPrune = true;
3236 if (!fHavePruned) {
3237 pblocktree->WriteFlag("prunedblockfiles", true);
3238 fHavePruned = true;
3239 }
f9ec3f0f 3240 }
3241 }
8d655683 3242 int64_t nNow = GetTimeMicros();
3243 // Avoid writing/flushing immediately after startup.
3244 if (nLastWrite == 0) {
3245 nLastWrite = nNow;
3246 }
3247 if (nLastFlush == 0) {
3248 nLastFlush = nNow;
3249 }
3250 if (nLastSetChain == 0) {
3251 nLastSetChain = nNow;
3252 }
3253 size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
3254 // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
3255 bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
3256 // The cache is over the limit, we have to write now.
3257 bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
3258 // 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.
3259 bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
3260 // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
3261 bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
3262 // Combine all conditions that result in a full cache flush.
3263 bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
3264 // Write blocks and block index to disk.
3265 if (fDoFullFlush || fPeriodicWrite) {
3266 // Depend on nMinDiskSpace to ensure we can write block index
3267 if (!CheckDiskSpace(0))
3268 return state.Error("out of disk space");
3269 // First make sure all block and undo data is flushed to disk.
3270 FlushBlockFile();
3271 // Then update all block file information (which may refer to block and undo files).
3272 {
3273 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
3274 vFiles.reserve(setDirtyFileInfo.size());
3275 for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
3276 vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
3277 setDirtyFileInfo.erase(it++);
3278 }
3279 std::vector<const CBlockIndex*> vBlocks;
3280 vBlocks.reserve(setDirtyBlockIndex.size());
3281 for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
3282 vBlocks.push_back(*it);
3283 setDirtyBlockIndex.erase(it++);
3284 }
3285 if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
3286 return AbortNode(state, "Files to write to block index database");
3287 }
51ce901a 3288 }
8d655683 3289 // Finally remove any pruned files
3290 if (fFlushForPrune)
3291 UnlinkPrunedFiles(setFilesToPrune);
3292 nLastWrite = nNow;
3293 }
3294 // Flush best chain related state. This can only be done if the blocks / block index write was also done.
3295 if (fDoFullFlush) {
3296 // Typical CCoins structures on disk are around 128 bytes in size.
3297 // Pushing a new one to the database can cause it to be written
3298 // twice (once in the log, and once in the tables). This is already
3299 // an overestimation, as most will delete an existing entry or
3300 // overwrite one. Still, use a conservative safety factor of 2.
3301 if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
3302 return state.Error("out of disk space");
3303 // Flush the chainstate (which may refer to block index entries).
3304 if (!pcoinsTip->Flush())
3305 return AbortNode(state, "Failed to write to coin database");
3306 nLastFlush = nNow;
3307 }
3308 if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
3309 // Update best block in wallet (so we can detect restored wallets).
3310 GetMainSignals().SetBestChain(chainActive.GetLocator());
3311 nLastSetChain = nNow;
51ce901a 3312 }
e4134579 3313 } catch (const std::runtime_error& e) {
27afcd89 3314 return AbortNode(state, std::string("System error while flushing: ") + e.what());
e4134579 3315 }
0ec16f35
PW
3316 return true;
3317}
450cbb09 3318
51ce901a
PW
3319void FlushStateToDisk() {
3320 CValidationState state;
a2069500 3321 FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
51ce901a
PW
3322}
3323
f9ec3f0f 3324void PruneAndFlush() {
3325 CValidationState state;
3326 fCheckForPruning = true;
3327 FlushStateToDisk(state, FLUSH_STATE_NONE);
3328}
3329
c5b390b6 3330/** Update chainActive and related internal data structures. */
0ec16f35 3331void static UpdateTip(CBlockIndex *pindexNew) {
11982d36 3332 const CChainParams& chainParams = Params();
4c6d41b8 3333 chainActive.SetTip(pindexNew);
8d655683 3334
0a61b0df 3335 // New best block
0a61b0df 3336 nTimeBestReceived = GetTime();
319b1160 3337 mempool.AddTransactionsUpdated(1);
03e2210d 3338 KOMODO_NEWBLOCKS++;
7246f7f3
JDL
3339 double progress;
3340 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
86131275 3341 progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip());
7246f7f3 3342 } else {
3bd2c3bd
DL
3343 int32_t longestchain = komodo_longestchain();
3344 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0;
7246f7f3
JDL
3345 }
3346
b0ae7941 3347 LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
86131275 3348 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
3349 log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.LastTip()->nChainTx,
3350 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()), progress,
7246f7f3 3351 pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
8d655683 3352
ff6a7af1 3353 cvBlockChange.notify_all();
8d655683 3354
2a919e39 3355 // Check the version of the last 100 blocks to see if we need to upgrade:
dbca89b7
GA
3356 static bool fWarned = false;
3357 if (!IsInitialBlockDownload() && !fWarned)
2a919e39
GA
3358 {
3359 int nUpgraded = 0;
4c6d41b8 3360 const CBlockIndex* pindex = chainActive.Tip();
2a919e39
GA
3361 for (int i = 0; i < 100 && pindex != NULL; i++)
3362 {
3363 if (pindex->nVersion > CBlock::CURRENT_VERSION)
3364 ++nUpgraded;
3365 pindex = pindex->pprev;
3366 }
3367 if (nUpgraded > 0)
30c1db1c 3368 LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION);
2a919e39 3369 if (nUpgraded > 100/2)
dbca89b7 3370 {
07cf4264 3371 // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user:
7e6d23b1 3372 strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
dbca89b7
GA
3373 CAlert::Notify(strMiscWarning, true);
3374 fWarned = true;
3375 }
2a919e39 3376 }
75f51f2a 3377}
2a919e39 3378
34a64fe0
JG
3379/**
3380 * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and
3381 * mempool.removeWithoutBranchId after this, with cs_main held.
3382 */
89f20450 3383bool static DisconnectTip(CValidationState &state, bool fBare = false) {
75f51f2a
PW
3384 CBlockIndex *pindexDelete = chainActive.Tip();
3385 assert(pindexDelete);
75f51f2a
PW
3386 // Read block from disk.
3387 CBlock block;
b8add6a4 3388 if (!ReadBlockFromDisk(block, pindexDelete,1))
27afcd89 3389 return AbortNode(state, "Failed to read block");
75f51f2a 3390 // Apply the block atomically to the chain state.
a8ac403d 3391 uint256 anchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
75f51f2a 3392 int64_t nStart = GetTimeMicros();
d237f62c 3393 {
7c70438d 3394 CCoinsViewCache view(pcoinsTip);
75f51f2a 3395 if (!DisconnectBlock(block, state, pindexDelete, view))
5262fde0 3396 return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
75f51f2a 3397 assert(view.Flush());
84964112 3398 DisconnectNotarisations(block);
d237f62c 3399 }
d70bc52e 3400 LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
a8ac403d 3401 uint256 anchorAfterDisconnect = pcoinsTip->GetBestAnchor();
75f51f2a 3402 // Write the chain state to disk, if necessary.
a2069500 3403 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
75f51f2a 3404 return false;
8d655683 3405
89f20450 3406 if (!fBare) {
ec872d3a
MT
3407 // resurrect mempool transactions from the disconnected block.
3408 for (int i = 0; i < block.vtx.size(); i++)
3409 {
89f20450 3410 // ignore validation errors in resurrected transactions
ec872d3a 3411 CTransaction &tx = block.vtx[i];
89f20450
PW
3412 list<CTransaction> removed;
3413 CValidationState stateDummy;
ce379cf7 3414 // don't keep staking or invalid transactions
0ba20651 3415 if (tx.IsCoinBase() || ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (komodo_isPoS((CBlock *)&block) != 0))) || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
ce379cf7 3416 {
89f20450 3417 mempool.remove(tx, removed, true);
ce379cf7 3418 }
89f20450
PW
3419 }
3420 if (anchorBeforeDisconnect != anchorAfterDisconnect) {
3421 // The anchor may not change between block disconnects,
3422 // in which case we don't want to evict from the mempool yet!
3423 mempool.removeWithAnchor(anchorBeforeDisconnect);
3424 }
89f20450 3425 }
8d655683 3426
75f51f2a
PW
3427 // Update chainActive and related variables.
3428 UpdateTip(pindexDelete->pprev);
de42390f
JG
3429 // Get the current commitment tree
3430 ZCIncrementalMerkleTree newTree;
5034d1c1 3431
de42390f 3432 assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), newTree));
5034d1c1 3433
93a18a36
GA
3434 // Let wallets know transactions went from 1-confirmed to
3435 // 0-confirmed or conflicted:
ce379cf7
MT
3436 for (int i = 0; i < block.vtx.size(); i++)
3437 {
3438 CTransaction &tx = block.vtx[i];
3ef36c2f 3439 if ((i == (block.vtx.size() - 1)) && (block.IsVerusPOSBlock() || (komodo_isPoS((CBlock *)&block) != 0)))
ce379cf7
MT
3440 {
3441 EraseFromWallets(tx.GetHash());
3442 }
3443 else
3444 {
3445 SyncWithWallets(tx, NULL);
3446 }
93a18a36 3447 }
5034d1c1 3448
de42390f 3449 GetMainSignals().ChainTip(pindexDelete, &block, newTree, false);
75f51f2a 3450 return true;
0ec16f35 3451}
d237f62c 3452
d70bc52e
PW
3453static int64_t nTimeReadFromDisk = 0;
3454static int64_t nTimeConnectTotal = 0;
3455static int64_t nTimeFlush = 0;
3456static int64_t nTimeChainState = 0;
3457static int64_t nTimePostConnect = 0;
3458
db954a65 3459/**
c5b390b6
MF
3460 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
3461 * corresponding to pindexNew, to bypass loading it again from disk.
34a64fe0 3462 * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held.
c5b390b6 3463 */
92bb6f2f 3464bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
76374710 3465
75f51f2a 3466 assert(pindexNew->pprev == chainActive.Tip());
75f51f2a 3467 // Read block from disk.
d70bc52e 3468 int64_t nTime1 = GetTimeMicros();
75f51f2a 3469 CBlock block;
92bb6f2f 3470 if (!pblock) {
b8add6a4 3471 if (!ReadBlockFromDisk(block, pindexNew,1))
27afcd89 3472 return AbortNode(state, "Failed to read block");
92bb6f2f
PW
3473 pblock = &block;
3474 }
de42390f
JG
3475 // Get the current commitment tree
3476 ZCIncrementalMerkleTree oldTree;
3477 assert(pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), oldTree));
75f51f2a 3478 // Apply the block atomically to the chain state.
d70bc52e
PW
3479 int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3480 int64_t nTime3;
3481 LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
0a61b0df 3482 {
7c70438d 3483 CCoinsViewCache view(pcoinsTip);
96f9009e 3484 bool rv = ConnectBlock(*pblock, state, pindexNew, view, false, true);
26c16d9d 3485 GetMainSignals().BlockChecked(*pblock, state);
24e88964 3486 if (!rv) {
75f51f2a
PW
3487 if (state.IsInvalid())
3488 InvalidBlockFound(pindexNew, state);
5262fde0 3489 return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
7851033d 3490 }
2af5a650 3491 mapBlockSource.erase(pindexNew->GetBlockHash());
d70bc52e
PW
3492 nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3493 LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
75f51f2a 3494 assert(view.Flush());
0a61b0df 3495 }
d70bc52e
PW
3496 int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3497 LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
75f51f2a 3498 // Write the chain state to disk, if necessary.
a2069500 3499 if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
75f51f2a 3500 return false;
d70bc52e
PW
3501 int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3502 LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
75f51f2a 3503 // Remove conflicting transactions from the mempool.
93a18a36 3504 list<CTransaction> txConflicted;
b649e039 3505 mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
8d655683 3506
9bb37bf0
JG
3507 // Remove transactions that expire at new block height from mempool
3508 mempool.removeExpired(pindexNew->nHeight);
8d655683 3509
75f51f2a 3510 // Update chainActive & related variables.
880b2931 3511 UpdateTip(pindexNew);
93a18a36
GA
3512 // Tell wallet about transactions that went from mempool
3513 // to conflicted:
3514 BOOST_FOREACH(const CTransaction &tx, txConflicted) {
d38da59b 3515 SyncWithWallets(tx, NULL);
93a18a36
GA
3516 }
3517 // ... and about transactions that got confirmed:
92bb6f2f
PW
3518 BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
3519 SyncWithWallets(tx, pblock);
93a18a36 3520 }
769e031c 3521 // Update cached incremental witnesses
e0440cc3 3522 //fprintf(stderr,"chaintip true\n");
de42390f 3523 GetMainSignals().ChainTip(pindexNew, pblock, oldTree, true);
8d655683 3524
5b3bc971 3525 EnforceNodeDeprecation(pindexNew->nHeight);
8d655683 3526
d70bc52e
PW
3527 int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3528 LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3529 LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
c3d91e3b 3530 if ( KOMODO_LONGESTCHAIN != 0 && pindexNew->nHeight >= KOMODO_LONGESTCHAIN )
99ba67a0 3531 KOMODO_INSYNC = 1;
3532 else KOMODO_INSYNC = 0;
6dcd15b5 3533 //fprintf(stderr,"connect.%d insync.%d\n",(int32_t)pindexNew->nHeight,KOMODO_INSYNC);
99ba67a0 3534 if ( ASSETCHAINS_SYMBOL[0] == 0 && KOMODO_INSYNC != 0 )
395f10cf 3535 komodo_broadcast(pblock,8);
0a61b0df 3536 return true;
3537}
3538
c5b390b6
MF
3539/**
3540 * Return the tip of the chain with the most work in it, that isn't
3541 * known to be invalid (it's however far from certain to be valid).
3542 */
77339e5a 3543static CBlockIndex* FindMostWorkChain() {
75f51f2a 3544 do {
77339e5a 3545 CBlockIndex *pindexNew = NULL;
8d655683 3546
75f51f2a
PW
3547 // Find the best candidate header.
3548 {
e17bd583
PW
3549 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3550 if (it == setBlockIndexCandidates.rend())
77339e5a 3551 return NULL;
75f51f2a
PW
3552 pindexNew = *it;
3553 }
8d655683 3554
75f51f2a
PW
3555 // Check whether all blocks on the path between the currently active chain and the candidate are valid.
3556 // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
3557 CBlockIndex *pindexTest = pindexNew;
3558 bool fInvalidAncestor = false;
3559 while (pindexTest && !chainActive.Contains(pindexTest)) {
341735eb 3560 assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
8d655683 3561
f9ec3f0f 3562 // Pruned nodes may have entries in setBlockIndexCandidates for
3563 // which block files have been deleted. Remove those as candidates
3564 // for the most work chain if we come across them; we can't switch
3565 // to a chain unless we have all the non-active-chain parent blocks.
3566 bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
3567 bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
3568 if (fFailedChain || fMissingData) {
3569 // Candidate chain is not usable (either invalid or missing data)
3570 if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
942b33a1
PW
3571 pindexBestInvalid = pindexNew;
3572 CBlockIndex *pindexFailed = pindexNew;
f9ec3f0f 3573 // Remove the entire chain from the set.
75f51f2a 3574 while (pindexTest != pindexFailed) {
f9ec3f0f 3575 if (fFailedChain) {
3576 pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
3577 } else if (fMissingData) {
3578 // If we're missing data, then add back to mapBlocksUnlinked,
3579 // so that if the block arrives in the future we can try adding
3580 // to setBlockIndexCandidates again.
3581 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
3582 }
e17bd583 3583 setBlockIndexCandidates.erase(pindexFailed);
75f51f2a
PW
3584 pindexFailed = pindexFailed->pprev;
3585 }
e17bd583 3586 setBlockIndexCandidates.erase(pindexTest);
75f51f2a
PW
3587 fInvalidAncestor = true;
3588 break;
ef3988ca 3589 }
75f51f2a 3590 pindexTest = pindexTest->pprev;
0a61b0df 3591 }
77339e5a
PW
3592 if (!fInvalidAncestor)
3593 return pindexNew;
75f51f2a 3594 } while(true);
75f51f2a 3595}
0a61b0df 3596
c5b390b6 3597/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
cca48f69 3598static void PruneBlockIndexCandidates() {
3599 // Note that we can't delete the current block itself, as we may need to return to it later in case a
3600 // reorganization to a better block fails.
3601 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
86131275 3602 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.LastTip())) {
cca48f69 3603 setBlockIndexCandidates.erase(it++);
3604 }
34559c7c
PW
3605 // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
3606 assert(!setBlockIndexCandidates.empty());
cca48f69 3607}
3608
c5b390b6
MF
3609/**
3610 * Try to make some progress towards making pindexMostWork the active block.
3611 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
3612 */
92bb6f2f 3613static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
4e0eed88 3614 AssertLockHeld(cs_main);
202e0194 3615 bool fInvalidFound = false;
b33bd7a3
DK
3616 const CBlockIndex *pindexOldTip = chainActive.Tip();
3617 const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
1f722359 3618
57e6ecda
JG
3619 // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks.
3620 // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain,
3621 // then pindexFork will be null, and we would need to remove the entire chain including
3622 // our genesis block. In practice this (probably) won't happen because of checks elsewhere.
3623 auto reorgLength = pindexOldTip ? pindexOldTip->nHeight - (pindexFork ? pindexFork->nHeight : -1) : 0;
3624 static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance");
3625 if (reorgLength > MAX_REORG_LENGTH) {
3626 auto msg = strprintf(_(
8d655683 3627 "A block chain reorganization has been detected that would roll back %d blocks! "
3628 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
3629 ), reorgLength, MAX_REORG_LENGTH) + "\n\n" +
3630 _("Reorganization details") + ":\n" +
3631 "- " + strprintf(_("Current tip: %s, height %d, work %s"),
3632 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" +
3633 "- " + strprintf(_("New tip: %s, height %d, work %s"),
3634 pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" +
5794aafc 3635 "- " + strprintf(_("Fork point: %s %s, height %d"),
a17a8c52 3636 ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" +
8d655683 3637 _("Please help, human!");
57e6ecda
JG
3638 LogPrintf("*** %s\n", msg);
3639 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
3640 StartShutdown();
3641 return false;
3642 }
8d655683 3643
4e0eed88 3644 // Disconnect active blocks which are no longer in the best chain.
fe5cef05 3645 bool fBlocksDisconnected = false;
4e0eed88
PW
3646 while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
3647 if (!DisconnectTip(state))
3648 return false;
fe5cef05 3649 fBlocksDisconnected = true;
4e0eed88 3650 }
8abcd819 3651 if ( KOMODO_REWIND != 0 )
8985164d 3652 {
2ca62c87 3653 CBlockIndex *tipindex;
86131275 3654 fprintf(stderr,">>>>>>>>>>> rewind start ht.%d -> KOMODO_REWIND.%d\n",chainActive.LastTip()->nHeight,KOMODO_REWIND);
3655 while ( KOMODO_REWIND > 0 && (tipindex= chainActive.LastTip()) != 0 && tipindex->nHeight > KOMODO_REWIND )
297a4978 3656 {
cef5ad03 3657 fBlocksDisconnected = true;
2ca62c87 3658 fprintf(stderr,"%d ",(int32_t)tipindex->nHeight);
3659 InvalidateBlock(state,tipindex);
310bb0a1 3660 if ( !DisconnectTip(state) )
45142781 3661 break;
67d2b8b9 3662 }
fd836de7 3663 fprintf(stderr,"reached rewind.%d, best to do: ./komodo-cli -ac_name=%s stop\n",KOMODO_REWIND,ASSETCHAINS_SYMBOL);
5c888905 3664 sleep(20);
91165f19 3665 fprintf(stderr,"resuming normal operations\n");
d8be8b2e 3666 KOMODO_REWIND = 0;
cef5ad03 3667 //return(true);
d8be8b2e 3668 }
4e0eed88
PW
3669 // Build list of new blocks to connect.
3670 std::vector<CBlockIndex*> vpindexToConnect;
afc32c5e
PW
3671 bool fContinue = true;
3672 int nHeight = pindexFork ? pindexFork->nHeight : -1;
3673 while (fContinue && nHeight != pindexMostWork->nHeight) {
5aa165d5
MC
3674 // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
3675 // a few blocks along the way.
3676 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
3677 vpindexToConnect.clear();
3678 vpindexToConnect.reserve(nTargetHeight - nHeight);
3679 CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
3680 while (pindexIter && pindexIter->nHeight != nHeight) {
3681 vpindexToConnect.push_back(pindexIter);
3682 pindexIter = pindexIter->pprev;
3683 }
3684 nHeight = nTargetHeight;
8d655683 3685
5aa165d5
MC
3686 // Connect new blocks.
3687 BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
3688 if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
3689 if (state.IsInvalid()) {
3690 // The block violates a consensus rule.
3691 if (!state.CorruptionPossible())
3692 InvalidChainFound(vpindexToConnect.back());
3693 state = CValidationState();
3694 fInvalidFound = true;
3695 fContinue = false;
3696 break;
3697 } else {
3698 // A system error occurred (disk space, database error, ...).
3699 return false;
3700 }
4e0eed88 3701 } else {
5aa165d5
MC
3702 PruneBlockIndexCandidates();
3703 if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
3704 // We're in a better position than we were. Return temporarily to release the lock.
3705 fContinue = false;
3706 break;
3707 }
75f51f2a
PW
3708 }
3709 }
231b3999 3710 }
8d655683 3711
fe5cef05 3712 if (fBlocksDisconnected) {
233c9eb6 3713 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
afc32c5e 3714 }
34a64fe0 3715 mempool.removeWithoutBranchId(
8d655683 3716 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
fe5cef05 3717 mempool.check(pcoinsTip);
8d655683 3718
202e0194
PW
3719 // Callbacks/notifications for a new best chain.
3720 if (fInvalidFound)
3721 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
3722 else
3723 CheckForkWarningConditions();
8d655683 3724
0a61b0df 3725 return true;
3726}
0a61b0df 3727
c5b390b6
MF
3728/**
3729 * Make the best chain active, in multiple steps. The result is either failure
3730 * or an activated best chain. pblock is either NULL or a pointer to a block
3731 * that is already loaded (to avoid loading it again from disk).
3732 */
92bb6f2f 3733bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
202e0194
PW
3734 CBlockIndex *pindexNewTip = NULL;
3735 CBlockIndex *pindexMostWork = NULL;
11982d36 3736 const CChainParams& chainParams = Params();
4e0eed88
PW
3737 do {
3738 boost::this_thread::interruption_point();
8d655683 3739
202e0194
PW
3740 bool fInitialDownload;
3741 {
3742 LOCK(cs_main);
3743 pindexMostWork = FindMostWorkChain();
8d655683 3744
202e0194
PW
3745 // Whether we have anything to do at all.
3746 if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
3747 return true;
8d655683 3748
92bb6f2f 3749 if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
9083591a 3750 return false;
202e0194
PW
3751 pindexNewTip = chainActive.Tip();
3752 fInitialDownload = IsInitialBlockDownload();
3753 }
3754 // When we reach this point, we switched to a new tip (stored in pindexNewTip).
8d655683 3755
202e0194
PW
3756 // Notifications/callbacks that can run without cs_main
3757 if (!fInitialDownload) {
3758 uint256 hashNewTip = pindexNewTip->GetBlockHash();
3759 // Relay inventory, but don't relay old inventory during initial block download.
a8cdaf5c
CF
3760 int nBlockEstimate = 0;
3761 if (fCheckpointsEnabled)
3762 nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
f9ec3f0f 3763 // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
3764 // in a stalled download if the block file is pruned before the request.
3765 if (nLocalServices & NODE_NETWORK) {
4dc5eb05
PK
3766 LOCK(cs_vNodes);
3767 BOOST_FOREACH(CNode* pnode, vNodes)
8d655683 3768 if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
3769 pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
202e0194 3770 }
51ce901a 3771 // Notify external listeners about the new tip.
6a793d9c 3772 GetMainSignals().UpdatedBlockTip(pindexNewTip);
c7b6117d 3773 uiInterface.NotifyBlockTip(hashNewTip);
b11963b5 3774 } //else fprintf(stderr,"initial download skips propagation\n");
202e0194 3775 } while(pindexMostWork != chainActive.Tip());
3fcfbc8a 3776 CheckBlockIndex();
8d655683 3777
51ce901a 3778 // Write changes periodically to disk, after relay.
a2069500 3779 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
51ce901a
PW
3780 return false;
3781 }
8d655683 3782
4e0eed88
PW
3783 return true;
3784}
942b33a1 3785
9b0a8d31
PW
3786bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
3787 AssertLockHeld(cs_main);
8d655683 3788
9b0a8d31
PW
3789 // Mark the block itself as invalid.
3790 pindex->nStatus |= BLOCK_FAILED_VALID;
0dd06b25 3791 setDirtyBlockIndex.insert(pindex);
9b0a8d31 3792 setBlockIndexCandidates.erase(pindex);
8d655683 3793
9b0a8d31
PW
3794 while (chainActive.Contains(pindex)) {
3795 CBlockIndex *pindexWalk = chainActive.Tip();
3796 pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
0dd06b25 3797 setDirtyBlockIndex.insert(pindexWalk);
9b0a8d31
PW
3798 setBlockIndexCandidates.erase(pindexWalk);
3799 // ActivateBestChain considers blocks already in chainActive
3800 // unconditionally valid already, so force disconnect away from it.
3801 if (!DisconnectTip(state)) {
233c9eb6 3802 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
34a64fe0 3803 mempool.removeWithoutBranchId(
8d655683 3804 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
9b0a8d31
PW
3805 return false;
3806 }
3807 }
ea5f02cb 3808 //LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
8d655683 3809
9b0a8d31 3810 // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
b05a89b2 3811 // add it again.
9b0a8d31 3812 BlockMap::iterator it = mapBlockIndex.begin();
e6528c64 3813 while (it != mapBlockIndex.end() && it->second != 0 ) {
cd3d67cf 3814 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
a9af4158 3815 setBlockIndexCandidates.insert(it->second);
9b0a8d31
PW
3816 }
3817 it++;
3818 }
8d655683 3819
9b0a8d31 3820 InvalidChainFound(pindex);
233c9eb6 3821 mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
34a64fe0 3822 mempool.removeWithoutBranchId(
8d655683 3823 CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus()));
9b0a8d31
PW
3824 return true;
3825}
3826
3827bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
3828 AssertLockHeld(cs_main);
8d655683 3829
9b0a8d31 3830 int nHeight = pindex->nHeight;
8d655683 3831
9b0a8d31
PW
3832 // Remove the invalidity flag from this block and all its descendants.
3833 BlockMap::iterator it = mapBlockIndex.begin();
3834 while (it != mapBlockIndex.end()) {
3835 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
3836 it->second->nStatus &= ~BLOCK_FAILED_MASK;
0dd06b25 3837 setDirtyBlockIndex.insert(it->second);
9b0a8d31
PW
3838 if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
3839 setBlockIndexCandidates.insert(it->second);
3840 }
3841 if (it->second == pindexBestInvalid) {
3842 // Reset invalid block marker if it was pointing to one of those.
3843 pindexBestInvalid = NULL;
3844 }
3845 }
3846 it++;
3847 }
8d655683 3848
9b0a8d31
PW
3849 // Remove the invalidity flag from all ancestors too.
3850 while (pindex != NULL) {
0dd06b25
PW
3851 if (pindex->nStatus & BLOCK_FAILED_MASK) {
3852 pindex->nStatus &= ~BLOCK_FAILED_MASK;
3853 setDirtyBlockIndex.insert(pindex);
9b0a8d31
PW
3854 }
3855 pindex = pindex->pprev;
3856 }
3857 return true;
3858}
3859
341735eb 3860CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
0a61b0df 3861{
3862 // Check for duplicate
1959997a 3863 uint256 hash = block.GetHash();
145d5be8 3864 BlockMap::iterator it = mapBlockIndex.find(hash);
b8513092 3865 BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
942b33a1 3866 if (it != mapBlockIndex.end())
fd835d94 3867 {
64b45b71 3868 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
66dd02d2 3869 {
3870 // 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
3871 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
7732dbc2 3872 return it->second;
66dd02d2 3873 }
b8513092 3874 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
3875 {
f190f354 3876 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
b8513092 3877 return(0); // return here to avoid the state of pindex->nHeight not set and pprev NULL
3878 }
fd835d94 3879 }
0a61b0df 3880 // Construct new block index object
1959997a 3881 CBlockIndex* pindexNew = new CBlockIndex(block);
94c8bfb2 3882 assert(pindexNew);
341735eb
PW
3883 // We assign the sequence id to blocks only when the full data is available,
3884 // to avoid miners withholding blocks but broadcasting headers, to get a
3885 // competitive advantage.
3886 pindexNew->nSequenceId = 0;
145d5be8 3887 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
0a61b0df 3888 pindexNew->phashBlock = &((*mi).first);
0a61b0df 3889 if (miPrev != mapBlockIndex.end())
3890 {
b92dfb1e 3891 if ( (pindexNew->pprev= (*miPrev).second) != 0 )
3892 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
8dcf7f3f 3893 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
c9a09183 3894 pindexNew->BuildSkip();
0a61b0df 3895 }
092b58d1 3896 pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
942b33a1 3897 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
341735eb
PW
3898 if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
3899 pindexBestHeader = pindexNew;
8d655683 3900
51ce901a 3901 setDirtyBlockIndex.insert(pindexNew);
66dd02d2 3902 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
9cdde30c 3903 mi->second = pindexNew;
942b33a1
PW
3904 return pindexNew;
3905}
3906
c5b390b6 3907/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
942b33a1
PW
3908bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
3909{
3910 pindexNew->nTx = block.vtx.size();
341735eb 3911 pindexNew->nChainTx = 0;
ad6a36ad
JG
3912 CAmount sproutValue = 0;
3913 for (auto tx : block.vtx) {
3914 for (auto js : tx.vjoinsplit) {
3915 sproutValue += js.vpub_old;
3916 sproutValue -= js.vpub_new;
3917 }
3918 }
3919 pindexNew->nSproutValue = sproutValue;
3920 pindexNew->nChainSproutValue = boost::none;
857c61df
PW
3921 pindexNew->nFile = pos.nFile;
3922 pindexNew->nDataPos = pos.nPos;
5382bcf8 3923 pindexNew->nUndoPos = 0;
942b33a1 3924 pindexNew->nStatus |= BLOCK_HAVE_DATA;
341735eb 3925 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
51ce901a 3926 setDirtyBlockIndex.insert(pindexNew);
8d655683 3927
341735eb
PW
3928 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
3929 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
3930 deque<CBlockIndex*> queue;
3931 queue.push_back(pindexNew);
8d655683 3932
341735eb
PW
3933 // Recursively process any descendant blocks that now may be eligible to be connected.
3934 while (!queue.empty()) {
3935 CBlockIndex *pindex = queue.front();
3936 queue.pop_front();
3937 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
ad6a36ad
JG
3938 if (pindex->pprev) {
3939 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
3940 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
3941 } else {
3942 pindex->nChainSproutValue = boost::none;
3943 }
3944 } else {
3945 pindex->nChainSproutValue = pindex->nSproutValue;
3946 }
c1ecee8f
SD
3947 {
3948 LOCK(cs_nBlockSequenceId);
3949 pindex->nSequenceId = nBlockSequenceId++;
3950 }
3fcfbc8a
PW
3951 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
3952 setBlockIndexCandidates.insert(pindex);
3953 }
341735eb
PW
3954 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
3955 while (range.first != range.second) {
3956 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3957 queue.push_back(it->second);
3958 range.first++;
3959 mapBlocksUnlinked.erase(it);
3960 }
341735eb
PW
3961 }
3962 } else {
3963 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
3964 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
3965 }
341735eb 3966 }
8d655683 3967
18e72167 3968 return true;
0a61b0df 3969}
3970
51ed9ec9 3971bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
5382bcf8 3972{
5382bcf8 3973 LOCK(cs_LastBlockFile);
8d655683 3974
ed6d1a2c
PW
3975 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
3976 if (vinfoBlockFile.size() <= nFile) {
3977 vinfoBlockFile.resize(nFile + 1);
3978 }
8d655683 3979
ed6d1a2c
PW
3980 if (!fKnown) {
3981 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
ed6d1a2c
PW
3982 nFile++;
3983 if (vinfoBlockFile.size() <= nFile) {
3984 vinfoBlockFile.resize(nFile + 1);
3985 }
7fea4846 3986 }
ed6d1a2c
PW
3987 pos.nFile = nFile;
3988 pos.nPos = vinfoBlockFile[nFile].nSize;
5382bcf8 3989 }
8d655683 3990
4e895b08
PW
3991 if (nFile != nLastBlockFile) {
3992 if (!fKnown) {
3993 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
3994 }
3995 FlushBlockFile(!fKnown);
3996 nLastBlockFile = nFile;
3997 }
8d655683 3998
ed6d1a2c 3999 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
bb6acff0
CF
4000 if (fKnown)
4001 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
4002 else
4003 vinfoBlockFile[nFile].nSize += nAddSize;
8d655683 4004
7fea4846
PW
4005 if (!fKnown) {
4006 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
ed6d1a2c 4007 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
7fea4846 4008 if (nNewChunks > nOldChunks) {
f9ec3f0f 4009 if (fPruneMode)
4010 fCheckForPruning = true;
fa45c26a
PK
4011 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
4012 FILE *file = OpenBlockFile(pos);
4013 if (file) {
881a85a2 4014 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
fa45c26a
PK
4015 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
4016 fclose(file);
4017 }
7fea4846 4018 }
fa45c26a 4019 else
c117d9e9 4020 return state.Error("out of disk space");
bba89aa8 4021 }
bba89aa8 4022 }
8d655683 4023
51ce901a 4024 setDirtyFileInfo.insert(nFile);
5382bcf8
PW
4025 return true;
4026}
4027
ef3988ca 4028bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
5382bcf8
PW
4029{
4030 pos.nFile = nFile;
8d655683 4031
5382bcf8 4032 LOCK(cs_LastBlockFile);
8d655683 4033
bba89aa8 4034 unsigned int nNewSize;
ed6d1a2c
PW
4035 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
4036 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
51ce901a 4037 setDirtyFileInfo.insert(nFile);
8d655683 4038
bba89aa8
PW
4039 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4040 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
4041 if (nNewChunks > nOldChunks) {
f9ec3f0f 4042 if (fPruneMode)
4043 fCheckForPruning = true;
fa45c26a
PK
4044 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
4045 FILE *file = OpenUndoFile(pos);
4046 if (file) {
881a85a2 4047 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
fa45c26a
PK
4048 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
4049 fclose(file);
4050 }
bba89aa8 4051 }
fa45c26a 4052 else
c117d9e9 4053 return state.Error("out of disk space");
5382bcf8 4054 }
8d655683 4055
5382bcf8
PW
4056 return true;
4057}
4058
9f6cb8f0 4059bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
0a61b0df 4060{
d7426190 4061 // Check timestamp
e40b78e9 4062 if ( 0 )
c0dbb034 4063 {
4064 uint256 hash; int32_t i;
4065 hash = blockhdr.GetHash();
92266e99 4066 for (i=31; i>=0; i--)
c0dbb034 4067 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4068 fprintf(stderr," <- CheckBlockHeader\n");
86131275 4069 if ( chainActive.LastTip() != 0 )
807949f4 4070 {
86131275 4071 hash = chainActive.LastTip()->GetBlockHash();
807949f4 4072 for (i=31; i>=0; i--)
4073 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
4074 fprintf(stderr," <- chainTip\n");
4075 }
c0dbb034 4076 }
9f6cb8f0 4077 *futureblockp = 0;
5dde7075 4078 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
8999ab66 4079 {
82b4714b 4080 CBlockIndex *tipindex;
4f61808f 4081 //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
599c2c5f 4082 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 )
5d9f1119 4083 {
2fea1c97 4084 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
5d9f1119 4085 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
4086 sleep(1);
2fea1c97 4087 //fprintf(stderr,"now its valid\n");
5d9f1119 4088 }
4089 else
4090 {
9f6cb8f0 4091 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
4092 *futureblockp = 1;
992ae6c5 4093 //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime());
5d9f1119 4094 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
4095 }
8999ab66 4096 }
80f4cdcf 4097 // Check block version
5d173d2a 4098 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
edddf5f0 4099 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
f2dd868d 4100
f2dd868d 4101 // Check Equihash solution is valid
dc4124de 4102 if ( fCheckPOW )
4103 {
4104 if ( !CheckEquihashSolution(&blockhdr, Params()) )
4105 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
b8add6a4 4106 }
f2dd868d 4107 // Check proof of work matches claimed amount
ec06a2e3 4108 /*komodo_index2pubkey33(pubkey33,pindex,height);
3ad8d247 4109 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
8d655683 4110 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
f4573470
PW
4111 return true;
4112}
4113
ce5dd547 4114int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
18443f69 4115int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
b8add6a4 4116
9f6cb8f0 4117bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
6fb8d0c2
JG
4118 libzcash::ProofVerifier& verifier,
4119 bool fCheckPOW, bool fCheckMerkleRoot)
0a61b0df 4120{
e5d9a702 4121 uint8_t pubkey33[33]; uint256 hash;
341735eb 4122 // These are checks that are independent of context.
18dd6a3b 4123 hash = block.GetHash();
af58b81e 4124 // Check that the header is valid (particularly PoW). This is mostly redundant with the call in AcceptBlockHeader.
9f6cb8f0 4125 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
3283cb53 4126 {
9840ae39 4127 if ( *futureblockp == 0 )
e8314e82 4128 {
4129 LogPrintf("CheckBlock header error");
9840ae39 4130 return false;
e8314e82 4131 }
3283cb53 4132 }
18443f69 4133 if ( fCheckPOW )
4134 {
1f722359 4135 //if ( !CheckEquihashSolution(&block, Params()) )
18443f69 4136 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
4137 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
1f722359 4138 if ( !CheckProofOfWork(block,pubkey33,height,Params().GetConsensus()) )
d3358987 4139 {
560da193 4140 int32_t z; for (z=31; z>=0; z--)
e5d9a702 4141 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
80afe35b 4142 fprintf(stderr," failed hash ht.%d\n",height);
8fbee929 4143 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
d3358987 4144 }
3acce042 4145 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
18443f69 4146 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
4147 }
341735eb
PW
4148 // Check the merkle root.
4149 if (fCheckMerkleRoot) {
4150 bool mutated;
4151 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
4152 if (block.hashMerkleRoot != hashMerkleRoot2)
b8add6a4 4153 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
341735eb 4154 REJECT_INVALID, "bad-txnmrklroot", true);
8d655683 4155
341735eb
PW
4156 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
4157 // of transactions in a block without affecting the merkle root of a block,
4158 // while still invalidating it.
4159 if (mutated)
b8add6a4 4160 return state.DoS(100, error("CheckBlock: duplicate transaction"),
341735eb
PW
4161 REJECT_INVALID, "bad-txns-duplicate", true);
4162 }
8d655683 4163
341735eb
PW
4164 // All potential-corruption validation must be done before we do any
4165 // transaction validation, as otherwise we may mark the header as invalid
4166 // because we receive the wrong transactions for it.
8d655683 4167
0a61b0df 4168 // Size limits
38991ffa 4169 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
b8add6a4 4170 return state.DoS(100, error("CheckBlock: size limits failed"),
14e7ffcc 4171 REJECT_INVALID, "bad-blk-length");
8d655683 4172
0a61b0df 4173 // First transaction must be coinbase, the rest must not be
38991ffa 4174 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
b8add6a4 4175 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
14e7ffcc 4176 REJECT_INVALID, "bad-cb-missing");
d121e75b 4177
38991ffa
EL
4178 for (unsigned int i = 1; i < block.vtx.size(); i++)
4179 if (block.vtx[i].IsCoinBase())
b8add6a4 4180 return state.DoS(100, error("CheckBlock: more than one coinbase"),
14e7ffcc 4181 REJECT_INVALID, "bad-cb-multiple");
8d655683 4182
0a61b0df 4183 // Check transactions
6613483b 4184 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
a5fc9157 4185 {
4186 CValidationState stateDummy;
66291844 4187 //fprintf(stderr,"put block's tx into mempool\n");
a5fc9157 4188 for (int i = 0; i < block.vtx.size(); i++)
4189 {
0b34402a 4190 const CTransaction &tx = block.vtx[i];
a5fc9157 4191 if (tx.IsCoinBase() != 0 )
4192 continue;
4193 else if ( ASSETCHAINS_STAKED != 0 && (i == (block.vtx.size() - 1)) && komodo_isPoS((CBlock *)&block) != 0 )
4194 continue;
4195 AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL);
4196 }
66291844 4197 //fprintf(stderr,"done putting block's tx into mempool\n");
a5fc9157 4198 }
38991ffa 4199 BOOST_FOREACH(const CTransaction& tx, block.vtx)
837b94ee 4200 {
f8a07170 4201 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
8d655683 4202 return error("CheckBlock: komodo_validate_interest failed");
6fb8d0c2 4203 if (!CheckTransaction(tx, state, verifier))
b8add6a4 4204 return error("CheckBlock: CheckTransaction failed");
837b94ee 4205 }
7bd9c3a3 4206 unsigned int nSigOps = 0;
38991ffa 4207 BOOST_FOREACH(const CTransaction& tx, block.vtx)
e679ec96 4208 {
05df3fc6 4209 nSigOps += GetLegacySigOpCount(tx);
e679ec96
GA
4210 }
4211 if (nSigOps > MAX_BLOCK_SIGOPS)
b8add6a4 4212 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
14e7ffcc 4213 REJECT_INVALID, "bad-blk-sigops", true);
b1e74295 4214 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
e699e13d 4215 {
1a26c3fa 4216 //static uint32_t counter;
4217 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
41427baa 4218 // fprintf(stderr,"check deposit rejection\n");
e8314e82 4219 LogPrintf("CheckBlockHeader komodo_check_deposit error");
59642d51 4220 return(false);
e699e13d 4221 }
0a61b0df 4222 return true;
4223}
4224
a48f2d6d
LD
4225bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
4226{
11982d36
CF
4227 const CChainParams& chainParams = Params();
4228 const Consensus::Params& consensusParams = chainParams.GetConsensus();
a48f2d6d 4229 uint256 hash = block.GetHash();
4e382177 4230 if (hash == consensusParams.hashGenesisBlock)
a48f2d6d 4231 return true;
8d655683 4232
a48f2d6d 4233 assert(pindexPrev);
8d655683 4234
a48f2d6d 4235 int nHeight = pindexPrev->nHeight+1;
1f722359 4236
a48f2d6d 4237 // Check proof of work
8f95f7e1 4238 if ( (ASSETCHAINS_SYMBOL[0] != 0 || nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
5645d111 4239 {
39267c35 4240 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) <<
4241 " for block #" << nHeight << endl;
5262fde0 4242 return state.DoS(100, error("%s: incorrect proof of work", __func__),
2910478b 4243 REJECT_INVALID, "bad-diffbits");
5645d111 4244 }
8d655683 4245
a48f2d6d
LD
4246 // Check timestamp against prev
4247 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
a0dd01bc 4248 {
5262fde0 4249 return state.Invalid(error("%s: block's timestamp is too early", __func__),
2910478b 4250 REJECT_INVALID, "time-too-old");
4251 }
4252
4253 // Check that timestamp is not too far in the future
4254 if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime)
4255 {
4256 return state.Invalid(error("%s: block timestamp too far in the future", __func__),
4257 REJECT_INVALID, "time-too-new");
a0dd01bc 4258 }
a48f2d6d 4259
bfa832c7 4260 if (fCheckpointsEnabled)
a8cdaf5c
CF
4261 {
4262 // Check that the block chain matches the known block chain up to a checkpoint
4263 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
8d787d25 4264 {
49601901 4265 /*CBlockIndex *heightblock = chainActive[nHeight];
8d787d25 4266 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4267 {
4268 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4269 return true;
49601901 4270 }*/
5645d111 4271 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
8d787d25 4272 }
a8cdaf5c
CF
4273 // Don't accept any forks from the main chain prior to last checkpoint
4274 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
b62d7030 4275 int32_t notarized_height;
86131275 4276 if ( nHeight == 1 && chainActive.LastTip() != 0 && chainActive.LastTip()->nHeight > 1 )
e2c2f297 4277 {
4278 CBlockIndex *heightblock = chainActive[nHeight];
cc07ad72 4279 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
e2c2f297 4280 return true;
42bbeb4f 4281 return state.DoS(1, error("%s: trying to change height 1 forbidden", __func__));
333cf46c 4282 }
e7433b08 4283 if ( nHeight != 0 )
e2c2f297 4284 {
2d28ad9c 4285 if ( pcheckpoint != 0 && nHeight < pcheckpoint->nHeight )
9aa708af 4286 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->nHeight));
2d28ad9c 4287 if ( komodo_checkpoint(&notarized_height,nHeight,hash) < 0 )
e2c2f297 4288 {
9aa708af 4289 CBlockIndex *heightblock = chainActive[nHeight];
4290 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
4291 {
4292 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
4293 return true;
4294 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
4295 }
e2c2f297 4296 }
a8cdaf5c 4297 }
542da618
SB
4298 // Reject block.nVersion < 4 blocks
4299 if (block.nVersion < 4)
4300 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
5e82e1c8 4301 REJECT_OBSOLETE, "bad-version");
8d655683 4302
a48f2d6d
LD
4303 return true;
4304}
4305
4306bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
4307{
4308 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
51aa2492 4309 const Consensus::Params& consensusParams = Params().GetConsensus();
8d655683 4310
a48f2d6d 4311 // Check that all transactions are finalized
a1d3c6fb 4312 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
8d655683 4313
072099d7
S
4314 // Check transaction contextually against consensus rules at block height
4315 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
4316 return false; // Failure reason has been set in validation state object
4317 }
1f722359 4318
a1d3c6fb
MF
4319 int nLockTimeFlags = 0;
4320 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
8d655683 4321 ? pindexPrev->GetMedianTimePast()
4322 : block.GetBlockTime();
14aa6cc0 4323 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
5262fde0 4324 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
a48f2d6d 4325 }
a1d3c6fb 4326 }
8d655683 4327
c2a722d3
DH
4328 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
4329 // In Zcash this has been enforced since launch, except that the genesis
4330 // block didn't include the height in the coinbase (see Zcash protocol spec
4331 // section '6.8 Bitcoin Improvement Proposals').
548bbd95 4332 if (nHeight > 0)
a48f2d6d
LD
4333 {
4334 CScript expect = CScript() << nHeight;
4335 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
4336 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
16cd9f2d 4337 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
a48f2d6d
LD
4338 }
4339 }
a48f2d6d
LD
4340 return true;
4341}
4342
531b9293 4343bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
0a61b0df 4344{
161f617d 4345 static uint256 zero;
4e382177 4346 const CChainParams& chainparams = Params();
e07c943c 4347 AssertLockHeld(cs_main);
531b9293 4348
de8834fb 4349 // Check for duplicate
2a4d3464 4350 uint256 hash = block.GetHash();
145d5be8 4351 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
942b33a1 4352 CBlockIndex *pindex = NULL;
5215d24e 4353 if (miSelf != mapBlockIndex.end())
4354 {
341735eb 4355 // Block header is already known.
55c01f13 4356 if ( (pindex= miSelf->second) == 0 )
58ef04c7 4357 miSelf->second = pindex = AddToBlockIndex(block);
341735eb
PW
4358 if (ppindex)
4359 *ppindex = pindex;
6477ad07 4360 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
5262fde0 4361 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
8d725ab4 4362 /*if ( pindex != 0 && hash == komodo_requestedhash )
2c5af2cd 4363 {
b80fef6f 4364 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4365 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
bddeaf5e 4366 komodo_requestedcount = 0;
8d725ab4 4367 }*/
55c01f13 4368
b92dfb1e 4369 //if ( pindex == 0 )
4370 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
341735eb 4371 return true;
942b33a1 4372 }
531b9293 4373 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
44c0859f 4374 {
9840ae39 4375 if ( *futureblockp == 0 )
e8314e82 4376 {
b1af3ff1 4377 LogPrintf("AcceptBlockHeader CheckBlockHeader error\n");
9840ae39 4378 return false;
e8314e82 4379 }
44c0859f 4380 }
0a61b0df 4381 // Get prev block index
7fea4846 4382 CBlockIndex* pindexPrev = NULL;
e6c99a7a 4383 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4384 {
145d5be8 4385 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
b56585d0 4386 if (mi == mapBlockIndex.end())
beb911ec 4387 {
b1af3ff1 4388 LogPrintf("AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
f3071571 4389 return(false);
4390 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
beb911ec 4391 }
b56585d0 4392 pindexPrev = (*mi).second;
e6c99a7a 4393 if (pindexPrev == 0 )
f65a34b9 4394 {
b1af3ff1 4395 LogPrintf("AcceptBlockHeader hashPrevBlock %s no pindexPrev\n",block.hashPrevBlock.ToString().c_str());
e6c99a7a 4396 return(false);
f65a34b9 4397 }
e6c99a7a 4398 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
5262fde0 4399 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
942b33a1 4400 }
a48f2d6d 4401 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
44c0859f 4402 {
2fea1c97 4403 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
b1af3ff1 4404 LogPrintf("AcceptBlockHeader ContextualCheckBlockHeader failed\n");
a48f2d6d 4405 return false;
44c0859f 4406 }
942b33a1 4407 if (pindex == NULL)
7466a330 4408 {
58ef04c7 4409 if ( (pindex= AddToBlockIndex(block)) != 0 )
f7ce3004 4410 {
58ef04c7 4411 miSelf = mapBlockIndex.find(hash);
4412 if (miSelf != mapBlockIndex.end())
4413 miSelf->second = pindex;
e8314e82 4414 //fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
f7ce3004 4415 }
7466a330 4416 }
942b33a1
PW
4417 if (ppindex)
4418 *ppindex = pindex;
8d725ab4 4419 /*if ( pindex != 0 && hash == komodo_requestedhash )
161f617d 4420 {
4421 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4422 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
bddeaf5e 4423 komodo_requestedcount = 0;
8d725ab4 4424 }*/
942b33a1
PW
4425 return true;
4426}
4427
531b9293 4428bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
942b33a1 4429{
e6973430 4430 const CChainParams& chainparams = Params();
942b33a1 4431 AssertLockHeld(cs_main);
8d655683 4432
942b33a1 4433 CBlockIndex *&pindex = *ppindex;
c132b91a 4434 if (!AcceptBlockHeader(futureblockp, block, state, &pindex))
bd8997bf 4435 {
9840ae39 4436 if ( *futureblockp == 0 )
e8314e82 4437 {
857c644f 4438 LogPrintf("AcceptBlock AcceptBlockHeader error\n");
9840ae39 4439 return false;
e8314e82 4440 }
bd8997bf 4441 }
1e9dc6a8 4442 if ( pindex == 0 )
4443 {
b5711436 4444 LogPrintf("AcceptBlock null pindex error\n");
1e9dc6a8 4445 return false;
4446 }
da4020cb 4447 //fprintf(stderr,"acceptblockheader passed\n");
304892fc
SD
4448 // Try to process all requested blocks that we don't have, but only
4449 // process an unrequested block if it's new and has enough work to
93b606ae 4450 // advance our tip, and isn't too many blocks ahead.
304892fc
SD
4451 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4452 bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
93b606ae
SD
4453 // Blocks that are too out-of-order needlessly limit the effectiveness of
4454 // pruning, because pruning will not delete block files that contain any
4455 // blocks which are too close in height to the tip. Apply this test
4456 // regardless of whether pruning is enabled; it should generally be safe to
4457 // not process unrequested blocks.
42c2e91b 4458 bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + BLOCK_DOWNLOAD_WINDOW)); //MIN_BLOCKS_TO_KEEP));
8d655683 4459
304892fc
SD
4460 // TODO: deal better with return value and error conditions for duplicate
4461 // and unrequested blocks.
b92dfb1e 4462 //fprintf(stderr,"Accept %s flags already.%d requested.%d morework.%d farahead.%d\n",pindex->GetBlockHash().ToString().c_str(),fAlreadyHave,fRequested,fHasMoreWork,fTooFarAhead);
304892fc
SD
4463 if (fAlreadyHave) return true;
4464 if (!fRequested) { // If we didn't ask for it:
4465 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4466 if (!fHasMoreWork) return true; // Don't process less-work chains
93b606ae 4467 if (fTooFarAhead) return true; // Block height is too high
341735eb 4468 }
8d655683 4469
6fb8d0c2
JG
4470 // See method docstring for why this is always disabled
4471 auto verifier = libzcash::ProofVerifier::Disabled();
531b9293 4472 if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
07359935 4473 {
9840ae39 4474 if ( *futureblockp == 0 )
4475 {
4476 if (state.IsInvalid() && !state.CorruptionPossible()) {
4477 pindex->nStatus |= BLOCK_FAILED_VALID;
4478 setDirtyBlockIndex.insert(pindex);
4479 }
b1af3ff1 4480 LogPrintf("AcceptBlock CheckBlock or ContextualCheckBlock error\n");
9840ae39 4481 return false;
942b33a1 4482 }
942b33a1 4483 }
8d655683 4484
942b33a1 4485 int nHeight = pindex->nHeight;
0a61b0df 4486 // Write block to history file
421218d3 4487 try {
2a4d3464 4488 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
421218d3
PW
4489 CDiskBlockPos blockPos;
4490 if (dbp != NULL)
4491 blockPos = *dbp;
209377a7 4492 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
5262fde0 4493 return error("AcceptBlock(): FindBlockPos failed");
421218d3 4494 if (dbp == NULL)
e6973430 4495 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
27afcd89 4496 AbortNode(state, "Failed to write block");
942b33a1 4497 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5262fde0 4498 return error("AcceptBlock(): ReceivedBlockTransactions failed");
27df4123 4499 } catch (const std::runtime_error& e) {
27afcd89 4500 return AbortNode(state, std::string("System error: ") + e.what());
421218d3 4501 }
8d655683 4502
f9ec3f0f 4503 if (fCheckForPruning)
4504 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
9840ae39 4505 if ( *futureblockp == 0 )
4506 return true;
857c644f 4507 LogPrintf("AcceptBlock block from future error\n");
e8314e82 4508 return false;
0a61b0df 4509}
f9ec3f0f 4510
51aa2492 4511static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
de237cbf
GA
4512{
4513 unsigned int nFound = 0;
51aa2492 4514 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
de237cbf
GA
4515 {
4516 if (pstart->nVersion >= minVersion)
4517 ++nFound;
4518 pstart = pstart->pprev;
4519 }
4520 return (nFound >= nRequired);
4521}
4522
c75c18fc 4523void komodo_currentheight_set(int32_t height);
c9a09183 4524
b5d0fe2e 4525CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4ac854ea 4526{
58ef04c7 4527 CBlockIndex *pindex = 0;
4ac854ea 4528 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4529 if ( miSelf != mapBlockIndex.end() )
4530 {
4531 if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4532 {
4533 miSelf->second = AddToBlockIndex(*pblock);
4534 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4535 }
58ef04c7 4536 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
4ac854ea 4537 {
4538 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4539 if ( miSelf != mapBlockIndex.end() )
4540 {
4541 if ( miSelf->second == 0 )
4542 {
4543 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4544 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4545 }
4546 }
58ef04c7 4547 }*/
4ac854ea 4548 }
58ef04c7 4549 return(pindex);
0a61b0df 4550}
4551
4ac854ea 4552CBlockIndex *oldkomodo_ensure(CBlock *pblock,uint256 hash)
de237cbf 4553{
b5711436 4554 CBlockIndex *pindex=0,*previndex=0;
5d214ce7 4555 if ( (pindex= mapBlockIndex[hash]) == 0 )
de237cbf 4556 {
d1c9d1b4 4557 pindex = new CBlockIndex();
4558 if (!pindex)
4559 throw runtime_error("komodo_ensure: new CBlockIndex failed");
4560 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindex)).first;
4561 pindex->phashBlock = &((*mi).first);
de237cbf 4562 }
b5d0fe2e 4563 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
b5711436 4564 if ( miSelf == mapBlockIndex.end() )
4565 {
5d214ce7 4566 LogPrintf("komodo_ensure unexpected missing hash %s\n",hash.ToString().c_str());
4567 return(0);
b5711436 4568 }
5d214ce7 4569 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
b5d0fe2e 4570 {
5d214ce7 4571 if ( pindex == 0 )
d1c9d1b4 4572 {
5d214ce7 4573 pindex = AddToBlockIndex(*pblock);
d1c9d1b4 4574 fprintf(stderr,"ensure call addtoblockindex, got %p\n",pindex);
4575 }
5d214ce7 4576 if ( pindex != 0 )
b5d0fe2e 4577 {
5d214ce7 4578 miSelf->second = pindex;
4579 LogPrintf("Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
4580 } else LogPrintf("komodo_ensure unexpected null pindex\n");
4581 }
4582 /*if ( hash != Params().GetConsensus().hashGenesisBlock )
f8a07170 4583 {
4584 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4585 if ( miSelf == mapBlockIndex.end() )
b5711436 4586 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4587 if ( (miSelf= mapBlockIndex.find(pblock->hashPrevBlock)) != mapBlockIndex.end() )
f8a07170 4588 {
b5711436 4589 if ( miSelf->second == 0 ) // create pindex so first Accept block doesnt fail
4590 {
4591 if ( previndex == 0 )
4592 previndex = InsertBlockIndex(pblock->hashPrevBlock);
4593 if ( previndex != 0 )
4594 {
4595 miSelf->second = previndex;
4596 LogPrintf("autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4597 } else LogPrintf("komodo_ensure unexpected null previndex\n");
4598 }
4599 } else LogPrintf("komodo_ensure unexpected null miprev\n");
857c644f 4600 }
5d214ce7 4601 }*/
4602 return(pindex);
de237cbf
GA
4603}
4604
7bb789bb 4605bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
0a61b0df 4606{
0a61b0df 4607 // Preliminary checks
531b9293 4608 bool checked; uint256 hash; int32_t futureblock=0;
6fb8d0c2 4609 auto verifier = libzcash::ProofVerifier::Disabled();
bc2bcf85 4610 hash = pblock->GetHash();
d1bc3a75 4611 //fprintf(stderr,"ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight);
0a61b0df 4612 {
341735eb 4613 LOCK(cs_main);
809f2e25 4614 if ( chainActive.LastTip() != 0 )
4615 komodo_currentheight_set(chainActive.LastTip()->nHeight);
4616 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
bc2bcf85 4617 bool fRequested = MarkBlockAsReceived(hash);
304892fc 4618 fRequested |= fForceProcessing;
55d19b21 4619 if ( checked != 0 && komodo_checkPOW(0,pblock,height) < 0 ) //from_miner && ASSETCHAINS_STAKED == 0
13b8b2ed 4620 {
b8add6a4 4621 checked = 0;
e83bf6b3 4622 //fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
13b8b2ed 4623 }
9f6cb8f0 4624 if (!checked && futureblock == 0)
c7a1d234 4625 {
50c490cb 4626 if ( pfrom != 0 )
c7a1d234 4627 {
fe43f943 4628 Misbehaving(pfrom->GetId(), 1);
c7a1d234 4629 }
5262fde0 4630 return error("%s: CheckBlock FAILED", __func__);
5c88e3c1 4631 }
341735eb
PW
4632 // Store to disk
4633 CBlockIndex *pindex = NULL;
163fbf95 4634 if ( 1 )
17522a55 4635 {
66dd02d2 4636 // 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
c132b91a 4637 komodo_ensure(pblock, hash);
0f102ea7 4638 }
531b9293 4639 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
341735eb
PW
4640 if (pindex && pfrom) {
4641 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
0a61b0df 4642 }
3fcfbc8a 4643 CheckBlockIndex();
531b9293 4644 if (!ret && futureblock == 0)
5262fde0 4645 return error("%s: AcceptBlock FAILED", __func__);
bddeaf5e 4646 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
18e72167 4647 }
8d655683 4648
531b9293 4649 if (futureblock == 0 && !ActivateBestChain(state, pblock))
5262fde0 4650 return error("%s: ActivateBestChain failed", __func__);
d1bc3a75 4651 //fprintf(stderr,"finished ProcessBlock %d\n",(int32_t)chainActive.LastTip()->nHeight);
61cbf1c6 4652
0a61b0df 4653 return true;
4654}
4655
df08a626
LD
4656bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4657{
4658 AssertLockHeld(cs_main);
4659 assert(pindexPrev == chainActive.Tip());
8d655683 4660
df08a626
LD
4661 CCoinsViewCache viewNew(pcoinsTip);
4662 CBlockIndex indexDummy(block);
4663 indexDummy.pprev = pindexPrev;
4664 indexDummy.nHeight = pindexPrev->nHeight + 1;
6fb8d0c2
JG
4665 // JoinSplit proofs are verified in ConnectBlock
4666 auto verifier = libzcash::ProofVerifier::Disabled();
df08a626
LD
4667 // NOTE: CheckBlockHeader is called by CheckBlock
4668 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
d4190a2a 4669 {
b92dfb1e 4670 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
df08a626 4671 return false;
d4190a2a 4672 }
9f6cb8f0 4673 int32_t futureblock;
4674 if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
d4190a2a 4675 {
b92dfb1e 4676 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
df08a626 4677 return false;
d4190a2a 4678 }
df08a626 4679 if (!ContextualCheckBlock(block, state, pindexPrev))
d4190a2a 4680 {
b92dfb1e 4681 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
df08a626 4682 return false;
d4190a2a 4683 }
455ba304 4684 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
d4190a2a 4685 {
b92dfb1e 4686 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
df08a626 4687 return false;
d4190a2a 4688 }
df08a626 4689 assert(state.IsValid());
9840ae39 4690 if ( futureblock != 0 )
4691 return(false);
df08a626
LD
4692 return true;
4693}
4694
f9ec3f0f 4695/**
4696 * BLOCK PRUNING CODE
4697 */
4698
4699/* Calculate the amount of disk space the block & undo files currently use */
4700uint64_t CalculateCurrentUsage()
4701{
4702 uint64_t retval = 0;
4703 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
4704 retval += file.nSize + file.nUndoSize;
4705 }
4706 return retval;
4707}
4708
4709/* Prune a block file (modify associated database entries)*/
4710void PruneOneBlockFile(const int fileNumber)
4711{
4712 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
4713 CBlockIndex* pindex = it->second;
4714 if (pindex->nFile == fileNumber) {
4715 pindex->nStatus &= ~BLOCK_HAVE_DATA;
4716 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
4717 pindex->nFile = 0;
4718 pindex->nDataPos = 0;
4719 pindex->nUndoPos = 0;
4720 setDirtyBlockIndex.insert(pindex);
8d655683 4721
f9ec3f0f 4722 // Prune from mapBlocksUnlinked -- any block we prune would have
4723 // to be downloaded again in order to consider its chain, at which
4724 // point it would be considered as a candidate for
4725 // mapBlocksUnlinked or setBlockIndexCandidates.
4726 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
4727 while (range.first != range.second) {
4728 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
4729 range.first++;
4730 if (it->second == pindex) {
4731 mapBlocksUnlinked.erase(it);
4732 }
4733 }
4734 }
4735 }
8d655683 4736
f9ec3f0f 4737 vinfoBlockFile[fileNumber].SetNull();
4738 setDirtyFileInfo.insert(fileNumber);
4739}
4740
4741
4742void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
4743{
4744 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
4745 CDiskBlockPos pos(*it, 0);
4746 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
4747 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
4748 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
4749 }
4750}
4751
4752/* Calculate the block/rev files that should be deleted to remain under target*/
4753void FindFilesToPrune(std::set<int>& setFilesToPrune)
4754{
4755 LOCK2(cs_main, cs_LastBlockFile);
4756 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
4757 return;
4758 }
4759 if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
4760 return;
4761 }
b89f3077 4762 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
f9ec3f0f 4763 uint64_t nCurrentUsage = CalculateCurrentUsage();
4764 // We don't check to prune until after we've allocated new space for files
4765 // So we should leave a buffer under our target to account for another allocation
4766 // before the next pruning.
4767 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
4768 uint64_t nBytesToPrune;
4769 int count=0;
8d655683 4770
f9ec3f0f 4771 if (nCurrentUsage + nBuffer >= nPruneTarget) {
4772 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4773 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
8d655683 4774
f9ec3f0f 4775 if (vinfoBlockFile[fileNumber].nSize == 0)
4776 continue;
8d655683 4777
f9ec3f0f 4778 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
4779 break;
8d655683 4780
6cb70ca4 4781 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
b89f3077 4782 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
6cb70ca4 4783 continue;
8d655683 4784
f9ec3f0f 4785 PruneOneBlockFile(fileNumber);
4786 // Queue up the files for removal
4787 setFilesToPrune.insert(fileNumber);
4788 nCurrentUsage -= nBytesToPrune;
4789 count++;
4790 }
4791 }
8d655683 4792
b89f3077 4793 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
8d655683 4794 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
4795 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4796 nLastBlockWeCanPrune, count);
f9ec3f0f 4797}
4798
51ed9ec9 4799bool CheckDiskSpace(uint64_t nAdditionalBytes)
0a61b0df 4800{
a3241998 4801 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
8d655683 4802
966ae00f
PK
4803 // Check for nMinDiskSpace bytes (currently 50MB)
4804 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
b9b2e3fa 4805 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
8d655683 4806
0a61b0df 4807 return true;
4808}
4809
5382bcf8 4810FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
42613c97 4811{
cf53fd7c 4812 static int32_t didinit[64];
450cbb09 4813 if (pos.IsNull())
0a61b0df 4814 return NULL;
ec7eb0fa 4815 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5382bcf8
PW
4816 boost::filesystem::create_directories(path.parent_path());
4817 FILE* file = fopen(path.string().c_str(), "rb+");
4818 if (!file && !fReadOnly)
4819 file = fopen(path.string().c_str(), "wb+");
450cbb09 4820 if (!file) {
7d9d134b 4821 LogPrintf("Unable to open file %s\n", path.string());
0a61b0df 4822 return NULL;
450cbb09 4823 }
1a608050 4824 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
f527fcdb 4825 {
cf53fd7c 4826 komodo_prefetch(file);
1a608050 4827 didinit[pos.nFile] = 1;
f527fcdb 4828 }
5382bcf8
PW
4829 if (pos.nPos) {
4830 if (fseek(file, pos.nPos, SEEK_SET)) {
7d9d134b 4831 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5382bcf8
PW
4832 fclose(file);
4833 return NULL;
4834 }
4835 }
0a61b0df 4836 return file;
4837}
4838
5382bcf8
PW
4839FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
4840 return OpenDiskFile(pos, "blk", fReadOnly);
4841}
4842
69e07747 4843FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5382bcf8
PW
4844 return OpenDiskFile(pos, "rev", fReadOnly);
4845}
4846
ec7eb0fa
SD
4847boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
4848{
f7e36370 4849 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
ec7eb0fa
SD
4850}
4851
2d8a4829
PW
4852CBlockIndex * InsertBlockIndex(uint256 hash)
4853{
4f152496 4854 if (hash.IsNull())
2d8a4829 4855 return NULL;
8d655683 4856
2d8a4829 4857 // Return existing
145d5be8 4858 BlockMap::iterator mi = mapBlockIndex.find(hash);
2d8a4829
PW
4859 if (mi != mapBlockIndex.end())
4860 return (*mi).second;
8d655683 4861
2d8a4829
PW
4862 // Create new
4863 CBlockIndex* pindexNew = new CBlockIndex();
4864 if (!pindexNew)
5262fde0 4865 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
2d8a4829
PW
4866 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4867 pindexNew->phashBlock = &((*mi).first);
66dd02d2 4868 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
2d8a4829
PW
4869
4870 return pindexNew;
4871}
4872
102cc989 4873//void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
141950a4 4874
2d8a4829
PW
4875bool static LoadBlockIndexDB()
4876{
11982d36 4877 const CChainParams& chainparams = Params();
6a0c9826 4878 LogPrintf("%s: start loading guts\n", __func__);
2d8a4829
PW
4879 if (!pblocktree->LoadBlockIndexGuts())
4880 return false;
6a0c9826 4881 LogPrintf("%s: loaded guts\n", __func__);
b31499ec 4882 boost::this_thread::interruption_point();
8d655683 4883
1657c4bc 4884 // Calculate nChainWork
2d8a4829
PW
4885 vector<pair<int, CBlockIndex*> > vSortedByHeight;
4886 vSortedByHeight.reserve(mapBlockIndex.size());
4887 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4888 {
4889 CBlockIndex* pindex = item.second;
4890 vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
102cc989 4891 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
2d8a4829 4892 }
e1a6427c 4893 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
2d8a4829 4894 sort(vSortedByHeight.begin(), vSortedByHeight.end());
e1a6427c 4895 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
2d8a4829
PW
4896 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
4897 {
4898 CBlockIndex* pindex = item.second;
092b58d1 4899 pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
f9ec3f0f 4900 // We can link the chain of blocks for which we've received transactions at some point.
4901 // Pruned nodes may have deleted the block.
4902 if (pindex->nTx > 0) {
341735eb
PW
4903 if (pindex->pprev) {
4904 if (pindex->pprev->nChainTx) {
4905 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
ad6a36ad
JG
4906 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4907 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4908 } else {
4909 pindex->nChainSproutValue = boost::none;
4910 }
341735eb
PW
4911 } else {
4912 pindex->nChainTx = 0;
ad6a36ad 4913 pindex->nChainSproutValue = boost::none;
341735eb
PW
4914 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
4915 }
4916 } else {
4917 pindex->nChainTx = pindex->nTx;
ad6a36ad 4918 pindex->nChainSproutValue = pindex->nSproutValue;
341735eb
PW
4919 }
4920 }
9e851450
JG
4921 // Construct in-memory chain of branch IDs.
4922 // Relies on invariant: a block that does not activate a network upgrade
4923 // will always be valid under the same consensus rules as its parent.
828940b1
JG
4924 // Genesis block has a branch ID of zero by definition, but has no
4925 // validity status because it is side-loaded into a fresh chain.
4926 // Activation blocks will have branch IDs set (read from disk).
4927 if (pindex->pprev) {
4928 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
4929 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
4930 }
4931 } else {
be126699 4932 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
9e851450 4933 }
341735eb 4934 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
e17bd583 4935 setBlockIndexCandidates.insert(pindex);
85eb2cef
PW
4936 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
4937 pindexBestInvalid = pindex;
c9a09183
PW
4938 if (pindex->pprev)
4939 pindex->BuildSkip();
341735eb
PW
4940 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
4941 pindexBestHeader = pindex;
102cc989 4942 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
2d8a4829 4943 }
e1a6427c 4944 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
2d8a4829
PW
4945
4946 // Load block file info
4947 pblocktree->ReadLastBlockFile(nLastBlockFile);
ed6d1a2c 4948 vinfoBlockFile.resize(nLastBlockFile + 1);
7b2bb962 4949 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
ed6d1a2c
PW
4950 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4951 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4952 }
7b2bb962 4953 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
ed6d1a2c
PW
4954 for (int nFile = nLastBlockFile + 1; true; nFile++) {
4955 CBlockFileInfo info;
4956 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
4957 vinfoBlockFile.push_back(info);
4958 } else {
4959 break;
4960 }
4961 }
8d655683 4962
8c93bf4c
AH
4963 // Check presence of blk files
4964 LogPrintf("Checking all blk files are present...\n");
4965 set<int> setBlkDataFiles;
4966 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4967 {
4968 CBlockIndex* pindex = item.second;
4969 if (pindex->nStatus & BLOCK_HAVE_DATA) {
4970 setBlkDataFiles.insert(pindex->nFile);
4971 }
102cc989 4972 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
8c93bf4c 4973 }
e1a6427c 4974 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
8c93bf4c
AH
4975 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
4976 {
4977 CDiskBlockPos pos(*it, 0);
a8738238 4978 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
8c93bf4c
AH
4979 return false;
4980 }
4981 }
8d655683 4982
f9ec3f0f 4983 // Check whether we have ever pruned block & undo files
4984 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
4985 if (fHavePruned)
4986 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
8d655683 4987
89b7019b
PW
4988 // Check whether we need to continue reindexing
4989 bool fReindexing = false;
4990 pblocktree->ReadReindexing(fReindexing);
4991 fReindex |= fReindexing;
8d655683 4992
2d1fa42e
PW
4993 // Check whether we have a transaction index
4994 pblocktree->ReadFlag("txindex", fTxIndex);
52070c87 4995 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
8b78a819
T
4996 // Check whether we have an address index
4997 pblocktree->ReadFlag("addressindex", fAddressIndex);
4998 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
4999
5000 // Check whether we have a timestamp index
5001 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
5002 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
5003
5004 // Check whether we have a spent index
5005 pblocktree->ReadFlag("spentindex", fSpentIndex);
5006 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
2d1fa42e 5007
0bc1e2c4
JG
5008 // Fill in-memory data
5009 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
5010 {
5011 CBlockIndex* pindex = item.second;
5012 // - This relationship will always be true even if pprev has multiple
5013 // children, because hashAnchor is technically a property of pprev,
5014 // not its children.
5015 // - This will miss chain tips; we handle the best tip below, and other
5016 // tips will be handled by ConnectTip during a re-org.
5017 if (pindex->pprev) {
5018 pindex->pprev->hashAnchorEnd = pindex->hashAnchor;
5019 }
102cc989 5020 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
0bc1e2c4 5021 }
8d655683 5022
85eb2cef 5023 // Load pointer to end of best chain
145d5be8 5024 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
84674082 5025 if (it == mapBlockIndex.end())
89b7019b 5026 return true;
84674082 5027 chainActive.SetTip(it->second);
0bc1e2c4
JG
5028 // Set hashAnchorEnd for the end of best chain
5029 it->second->hashAnchorEnd = pcoinsTip->GetBestAnchor();
8d655683 5030
cca48f69 5031 PruneBlockIndexCandidates();
3bd2c3bd
DL
5032
5033 double progress;
5034 if ( ASSETCHAINS_SYMBOL[0] == 0 ) {
5035 progress = Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip());
5036 } else {
5037 int32_t longestchain = komodo_longestchain();
5038 // TODO: komodo_longestchain does not have the data it needs at the time LoadBlockIndexDB
5039 // runs, which makes it return 0, so we guess 50% for now
5040 progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 0.5;
5041 }
8d655683 5042
52070c87 5043 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
86131275 5044 chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(),
5045 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.LastTip()->GetBlockTime()),
3bd2c3bd 5046 progress);
8d655683 5047
5b3bc971 5048 EnforceNodeDeprecation(chainActive.Height(), true);
8d655683 5049
1f355b66
PW
5050 return true;
5051}
5052
06a91d96
CL
5053CVerifyDB::CVerifyDB()
5054{
5055 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
5056}
5057
5058CVerifyDB::~CVerifyDB()
5059{
5060 uiInterface.ShowProgress("", 100);
5061}
5062
2e280311 5063bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
168ba993 5064{
a475285a 5065 LOCK(cs_main);
4c6d41b8 5066 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
1f355b66 5067 return true;
8d655683 5068
2d8a4829 5069 // Verify blocks in the best chain
f5906533 5070 if (nCheckDepth <= 0)
2d8a4829 5071 nCheckDepth = 1000000000; // suffices until the year 19000
4c6d41b8
PW
5072 if (nCheckDepth > chainActive.Height())
5073 nCheckDepth = chainActive.Height();
1f355b66 5074 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
881a85a2 5075 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
7c70438d 5076 CCoinsViewCache coins(coinsview);
4c6d41b8 5077 CBlockIndex* pindexState = chainActive.Tip();
1f355b66
PW
5078 CBlockIndex* pindexFailure = NULL;
5079 int nGoodTransactions = 0;
ef3988ca 5080 CValidationState state;
6fb8d0c2
JG
5081 // No need to verify JoinSplits twice
5082 auto verifier = libzcash::ProofVerifier::Disabled();
d00db115 5083 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
4c6d41b8 5084 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
2d8a4829 5085 {
b31499ec 5086 boost::this_thread::interruption_point();
06a91d96 5087 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
4c6d41b8 5088 if (pindex->nHeight < chainActive.Height()-nCheckDepth)
2d8a4829
PW
5089 break;
5090 CBlock block;
1f355b66 5091 // check level 0: read from disk
b8add6a4 5092 if (!ReadBlockFromDisk(block, pindex,0))
5262fde0 5093 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
2d8a4829 5094 // check level 1: verify block validity
9f6cb8f0 5095 int32_t futureblock;
4342e69b 5096 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0) )
5262fde0 5097 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66
PW
5098 // check level 2: verify undo validity
5099 if (nCheckLevel >= 2 && pindex) {
5100 CBlockUndo undo;
5101 CDiskBlockPos pos = pindex->GetUndoPos();
5102 if (!pos.IsNull()) {
e035c6a7 5103 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5262fde0 5104 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66
PW
5105 }
5106 }
5107 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
fc684ad8 5108 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
1f355b66 5109 bool fClean = true;
5c363ed6 5110 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5262fde0 5111 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66
PW
5112 pindexState = pindex->pprev;
5113 if (!fClean) {
5114 nGoodTransactions = 0;
5115 pindexFailure = pindex;
5116 } else
5117 nGoodTransactions += block.vtx.size();
2d8a4829 5118 }
70477a0b
TZ
5119 if (ShutdownRequested())
5120 return true;
2d8a4829 5121 }
d00db115 5122 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
1f355b66 5123 if (pindexFailure)
5262fde0 5124 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
8d655683 5125
1f355b66
PW
5126 // check level 4: try reconnecting blocks
5127 if (nCheckLevel >= 4) {
5128 CBlockIndex *pindex = pindexState;
4c6d41b8 5129 while (pindex != chainActive.Tip()) {
b31499ec 5130 boost::this_thread::interruption_point();
06a91d96 5131 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
4c6d41b8 5132 pindex = chainActive.Next(pindex);
b001c871 5133 CBlock block;
b8add6a4 5134 if (!ReadBlockFromDisk(block, pindex,0))
5262fde0 5135 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
96f9009e 5136 if (!ConnectBlock(block, state, pindex, coins,false, true))
5262fde0 5137 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66 5138 }
2d8a4829 5139 }
8d655683 5140
4c6d41b8 5141 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
8d655683 5142
2d8a4829
PW
5143 return true;
5144}
5145
89f20450
PW
5146bool RewindBlockIndex(const CChainParams& params)
5147{
5148 LOCK(cs_main);
8d655683 5149
9e851450 5150 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
828940b1
JG
5151 // index will have nCachedBranchId set based on the values previously persisted
5152 // to disk. By definition, a set nCachedBranchId means that the block was
9e851450
JG
5153 // fully-validated under the corresponding consensus rules. Thus we can quickly
5154 // identify whether the current active chain matches our expected sequence of
5155 // consensus rule changes, with two checks:
5156 //
5157 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
828940b1 5158 // - nCachedBranchId for each block matches what we expect.
9e851450
JG
5159 auto sufficientlyValidated = [&params](const CBlockIndex* pindex) {
5160 auto consensus = params.GetConsensus();
5161 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
5162 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus);
828940b1 5163 return fFlagSet == fFlagExpected &&
8d655683 5164 pindex->nCachedBranchId &&
5165 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->nHeight, consensus);
9e851450 5166 };
8d655683 5167
89f20450
PW
5168 int nHeight = 1;
5169 while (nHeight <= chainActive.Height()) {
9e851450 5170 if (!sufficientlyValidated(chainActive[nHeight])) {
89f20450
PW
5171 break;
5172 }
5173 nHeight++;
5174 }
8d655683 5175
89f20450 5176 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
cb580c72
JG
5177 auto rewindLength = chainActive.Height() - nHeight;
5178 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH) {
5179 auto pindexOldTip = chainActive.Tip();
5180 auto pindexRewind = chainActive[nHeight - 1];
5181 auto msg = strprintf(_(
8d655683 5182 "A block chain rewind has been detected that would roll back %d blocks! "
5183 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
5184 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
5185 _("Rewind details") + ":\n" +
5186 "- " + strprintf(_("Current tip: %s, height %d"),
5187 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
5188 "- " + strprintf(_("Rewinding to: %s, height %d"),
5189 pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
5190 _("Please help, human!");
cb580c72
JG
5191 LogPrintf("*** %s\n", msg);
5192 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
5193 StartShutdown();
5194 return false;
5195 }
8d655683 5196
89f20450
PW
5197 CValidationState state;
5198 CBlockIndex* pindex = chainActive.Tip();
5199 while (chainActive.Height() >= nHeight) {
5200 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
5201 // If pruning, don't try rewinding past the HAVE_DATA point;
5202 // since older blocks can't be served anyway, there's
5203 // no need to walk further, and trying to DisconnectTip()
5204 // will fail (and require a needless reindex/redownload
5205 // of the blockchain).
5206 break;
5207 }
5208 if (!DisconnectTip(state, true)) {
5209 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
5210 }
5211 // Occasionally flush state to disk.
5212 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
5213 return false;
5214 }
8d655683 5215
89f20450
PW
5216 // Reduce validity flag and have-data flags.
5217 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
5218 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
5219 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
5220 CBlockIndex* pindexIter = it->second;
8d655683 5221
89f20450
PW
5222 // Note: If we encounter an insufficiently validated block that
5223 // is on chainActive, it must be because we are a pruning node, and
5224 // this block or some successor doesn't HAVE_DATA, so we were unable to
5225 // rewind all the way. Blocks remaining on chainActive at this point
5226 // must not have their validity reduced.
9e851450 5227 if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
89f20450 5228 // Reduce validity
9e851450 5229 pindexIter->nStatus =
8d655683 5230 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
5231 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
9e851450 5232 // Remove have-data flags
89f20450 5233 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
9e851450
JG
5234 // Remove branch ID
5235 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
828940b1 5236 pindexIter->nCachedBranchId = boost::none;
9e851450 5237 // Remove storage location
89f20450
PW
5238 pindexIter->nFile = 0;
5239 pindexIter->nDataPos = 0;
5240 pindexIter->nUndoPos = 0;
5241 // Remove various other things
5242 pindexIter->nTx = 0;
5243 pindexIter->nChainTx = 0;
9e851450
JG
5244 pindexIter->nSproutValue = boost::none;
5245 pindexIter->nChainSproutValue = boost::none;
89f20450 5246 pindexIter->nSequenceId = 0;
9e851450 5247 // Make sure it gets written
89f20450 5248 setDirtyBlockIndex.insert(pindexIter);
cef5ad03 5249 if (pindexIter == pindexBestInvalid)
5250 {
3d3f275f 5251 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
cef5ad03 5252 pindexBestInvalid = NULL;
5253 }
5254
9e851450 5255 // Update indices
89f20450 5256 setBlockIndexCandidates.erase(pindexIter);
9e851450 5257 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
89f20450
PW
5258 while (ret.first != ret.second) {
5259 if (ret.first->second == pindexIter) {
5260 mapBlocksUnlinked.erase(ret.first++);
5261 } else {
5262 ++ret.first;
5263 }
5264 }
5265 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
5266 setBlockIndexCandidates.insert(pindexIter);
5267 }
5268 }
8d655683 5269
89f20450 5270 PruneBlockIndexCandidates();
8d655683 5271
89f20450 5272 CheckBlockIndex();
8d655683 5273
89f20450
PW
5274 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
5275 return false;
5276 }
8d655683 5277
89f20450
PW
5278 return true;
5279}
5280
f7f3a96b
PW
5281void UnloadBlockIndex()
5282{
51598b26 5283 LOCK(cs_main);
e17bd583 5284 setBlockIndexCandidates.clear();
4c6d41b8 5285 chainActive.SetTip(NULL);
85eb2cef 5286 pindexBestInvalid = NULL;
51598b26
PW
5287 pindexBestHeader = NULL;
5288 mempool.clear();
5289 mapOrphanTransactions.clear();
5290 mapOrphanTransactionsByPrev.clear();
5291 nSyncStarted = 0;
5292 mapBlocksUnlinked.clear();
5293 vinfoBlockFile.clear();
5294 nLastBlockFile = 0;
5295 nBlockSequenceId = 1;
5296 mapBlockSource.clear();
5297 mapBlocksInFlight.clear();
5298 nQueuedValidatedHeaders = 0;
5299 nPreferredDownload = 0;
5300 setDirtyBlockIndex.clear();
5301 setDirtyFileInfo.clear();
5302 mapNodeState.clear();
ec9b6c33 5303 recentRejects.reset(NULL);
8d655683 5304
51598b26
PW
5305 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
5306 delete entry.second;
5307 }
5308 mapBlockIndex.clear();
f9ec3f0f 5309 fHavePruned = false;
f7f3a96b
PW
5310}
5311
7fea4846 5312bool LoadBlockIndex()
0a61b0df 5313{
d979e6e3 5314 // Load block index from databases
d042777b 5315 KOMODO_LOADINGBLOCKS = 1;
2d1fa42e 5316 if (!fReindex && !LoadBlockIndexDB())
d042777b 5317 {
5318 KOMODO_LOADINGBLOCKS = 0;
0a61b0df 5319 return false;
d042777b 5320 }
25f7ef8c 5321 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
38603761
PW
5322 return true;
5323}
2d1fa42e 5324
2d1fa42e 5325
38603761 5326bool InitBlockIndex() {
e6973430 5327 const CChainParams& chainparams = Params();
55a1db4f 5328 LOCK(cs_main);
8d655683 5329
5094a81d
WL
5330 // Initialize global variables that cannot be constructed at startup.
5331 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
8d655683 5332
38603761 5333 // Check whether we're already initialized
4c6d41b8 5334 if (chainActive.Genesis() != NULL)
38603761 5335 return true;
8d655683 5336
38603761 5337 // Use the provided setting for -txindex in the new database
b2c00e54 5338 fTxIndex = GetBoolArg("-txindex", true);
38603761 5339 pblocktree->WriteFlag("txindex", fTxIndex);
8b78a819
T
5340 // Use the provided setting for -addressindex in the new database
5341 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
5342 pblocktree->WriteFlag("addressindex", fAddressIndex);
38603761 5343
8b78a819
T
5344 // Use the provided setting for -timestampindex in the new database
5345 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
5346 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
5347
5348 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
5349 pblocktree->WriteFlag("spentindex", fSpentIndex);
881a85a2 5350 LogPrintf("Initializing databases...\n");
8d655683 5351
38603761
PW
5352 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
5353 if (!fReindex) {
38603761 5354 try {
0e4b3175
MH
5355 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
5356 // Start new block file
38603761
PW
5357 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
5358 CDiskBlockPos blockPos;
5359 CValidationState state;
209377a7 5360 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5262fde0 5361 return error("LoadBlockIndex(): FindBlockPos failed");
e6973430 5362 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5262fde0 5363 return error("LoadBlockIndex(): writing genesis block to disk failed");
942b33a1 5364 CBlockIndex *pindex = AddToBlockIndex(block);
294925c7 5365 if ( pindex == 0 )
5366 return error("LoadBlockIndex(): couldnt add to block index");
942b33a1 5367 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5262fde0 5368 return error("LoadBlockIndex(): genesis block not accepted");
92bb6f2f 5369 if (!ActivateBestChain(state, &block))
5262fde0 5370 return error("LoadBlockIndex(): genesis block cannot be activated");
bf7835c2 5371 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
a2069500 5372 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
27df4123 5373 } catch (const std::runtime_error& e) {
5262fde0 5374 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
38603761 5375 }
0a61b0df 5376 }
8d655683 5377
0a61b0df 5378 return true;
5379}
5380
5381
5382
7fea4846 5383bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
1d740055 5384{
4e382177 5385 const CChainParams& chainparams = Params();
ad96e7cc
WL
5386 // Map of disk positions for blocks with unknown parent (only used for reindex)
5387 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
51ed9ec9 5388 int64_t nStart = GetTimeMillis();
8d655683 5389
1d740055 5390 int nLoaded = 0;
421218d3 5391 try {
c9fb27da 5392 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
b8add6a4 5393 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
0e32bd33 5394 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
51ed9ec9 5395 uint64_t nRewind = blkdat.GetPos();
eb0b56b1 5396 while (!blkdat.eof()) {
21eb5ada 5397 boost::this_thread::interruption_point();
8d655683 5398
05d97268
PW
5399 blkdat.SetPos(nRewind);
5400 nRewind++; // start one byte further next time, in case of failure
5401 blkdat.SetLimit(); // remove former limit
7fea4846 5402 unsigned int nSize = 0;
05d97268
PW
5403 try {
5404 // locate a header
0caf2b18 5405 unsigned char buf[MESSAGE_START_SIZE];
0e4b3175 5406 blkdat.FindByte(Params().MessageStart()[0]);
05d97268
PW
5407 nRewind = blkdat.GetPos()+1;
5408 blkdat >> FLATDATA(buf);
0caf2b18 5409 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
05d97268
PW
5410 continue;
5411 // read size
1d740055 5412 blkdat >> nSize;
05d97268
PW
5413 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
5414 continue;
27df4123 5415 } catch (const std::exception&) {
7fea4846
PW
5416 // no valid block header found; don't complain
5417 break;
5418 }
5419 try {
05d97268 5420 // read block
51ed9ec9 5421 uint64_t nBlockPos = blkdat.GetPos();
ad96e7cc
WL
5422 if (dbp)
5423 dbp->nPos = nBlockPos;
7fea4846 5424 blkdat.SetLimit(nBlockPos + nSize);
16d51941
PW
5425 blkdat.SetPos(nBlockPos);
5426 CBlock block;
5427 blkdat >> block;
ad96e7cc 5428 nRewind = blkdat.GetPos();
8d655683 5429
16d51941
PW
5430 // detect out of order blocks, and store them for later
5431 uint256 hash = block.GetHash();
4e382177 5432 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
ad96e7cc 5433 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
8d655683 5434 block.hashPrevBlock.ToString());
ad96e7cc 5435 if (dbp)
16d51941 5436 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
ad96e7cc
WL
5437 continue;
5438 }
8d655683 5439
16d51941 5440 // process in case the block isn't known yet
8375e221 5441 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
16d51941 5442 CValidationState state;
7bb789bb 5443 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
16d51941
PW
5444 nLoaded++;
5445 if (state.IsError())
5446 break;
4e382177 5447 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
50b43fda 5448 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
16d51941 5449 }
8d655683 5450
ad96e7cc
WL
5451 // Recursively process earlier encountered successors of this block
5452 deque<uint256> queue;
5453 queue.push_back(hash);
5454 while (!queue.empty()) {
5455 uint256 head = queue.front();
5456 queue.pop_front();
5457 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5458 while (range.first != range.second) {
5459 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
b8add6a4 5460 if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1))
ad96e7cc
WL
5461 {
5462 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
8d655683 5463 head.ToString());
ad96e7cc 5464 CValidationState dummy;
7bb789bb 5465 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
ad96e7cc
WL
5466 {
5467 nLoaded++;
5468 queue.push_back(block.GetHash());
5469 }
5470 }
5471 range.first++;
5472 mapBlocksUnknownParent.erase(it);
5473 }
1d740055 5474 }
27df4123 5475 } catch (const std::exception& e) {
7ff9d122 5476 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
1d740055
PW
5477 }
5478 }
27df4123 5479 } catch (const std::runtime_error& e) {
b9b2e3fa 5480 AbortNode(std::string("System error: ") + e.what());
1d740055 5481 }
7fea4846 5482 if (nLoaded > 0)
f48742c2 5483 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
1d740055
PW
5484 return nLoaded > 0;
5485}
0a61b0df 5486
3fcfbc8a
PW
5487void static CheckBlockIndex()
5488{
4e382177 5489 const Consensus::Params& consensusParams = Params().GetConsensus();
3fcfbc8a
PW
5490 if (!fCheckBlockIndex) {
5491 return;
5492 }
8d655683 5493
3fcfbc8a 5494 LOCK(cs_main);
8d655683 5495
0421c18f 5496 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5497 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5498 // iterating the block tree require that chainActive has been initialized.)
5499 if (chainActive.Height() < 0) {
5500 assert(mapBlockIndex.size() <= 1);
5501 return;
5502 }
8d655683 5503
3fcfbc8a
PW
5504 // Build forward-pointing map of the entire block tree.
5505 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5506 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
e2c2eec4 5507 if ( it->second != 0 )
5508 forward.insert(std::make_pair(it->second->pprev, it->second));
3fcfbc8a 5509 }
d916630e 5510 if ( Params().NetworkIDString() != "regtest" )
5511 assert(forward.size() == mapBlockIndex.size());
8d655683 5512
3fcfbc8a
PW
5513 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5514 CBlockIndex *pindex = rangeGenesis.first->second;
5515 rangeGenesis.first++;
5516 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
8d655683 5517
3fcfbc8a
PW
5518 // Iterate over the entire block tree, using depth-first search.
5519 // Along the way, remember whether there are blocks on the path from genesis
5520 // block being explored which are the first to have certain properties.
5521 size_t nNodes = 0;
5522 int nHeight = 0;
5523 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5524 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
f9ec3f0f 5525 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
3fcfbc8a 5526 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
ede379f7 5527 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
3fcfbc8a
PW
5528 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5529 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5530 while (pindex != NULL) {
5531 nNodes++;
5532 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5533 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
f9ec3f0f 5534 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
3fcfbc8a 5535 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
ede379f7 5536 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
3fcfbc8a
PW
5537 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5538 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
8d655683 5539
3fcfbc8a
PW
5540 // Begin: actual consistency checks.
5541 if (pindex->pprev == NULL) {
5542 // Genesis block checks.
4e382177 5543 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
3fcfbc8a
PW
5544 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5545 }
c1ecee8f 5546 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
f9ec3f0f 5547 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5548 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5549 if (!fHavePruned) {
5550 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5551 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5552 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5553 } else {
5554 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5555 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5556 }
5557 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5558 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5559 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5560 assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
ede379f7 5561 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
3fcfbc8a
PW
5562 assert(pindex->nHeight == nHeight); // nHeight must be consistent.
5563 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.
5564 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5565 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5566 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5567 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5568 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5569 if (pindexFirstInvalid == NULL) {
5570 // Checks for not-invalid blocks.
5571 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5572 }
f9ec3f0f 5573 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5574 if (pindexFirstInvalid == NULL) {
5575 // If this block sorts at least as good as the current tip and
5576 // is valid and we have all data for its parents, it must be in
5577 // setBlockIndexCandidates. chainActive.Tip() must also be there
5578 // even if some data has been pruned.
5579 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5580 assert(setBlockIndexCandidates.count(pindex));
5581 }
5582 // If some parent is missing, then it could be that this block was in
5583 // setBlockIndexCandidates but had to be removed because of the missing data.
5584 // In this case it must be in mapBlocksUnlinked -- see test below.
3fcfbc8a 5585 }
f9ec3f0f 5586 } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
3fcfbc8a
PW
5587 assert(setBlockIndexCandidates.count(pindex) == 0);
5588 }
5589 // Check whether this block is in mapBlocksUnlinked.
5590 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5591 bool foundInUnlinked = false;
5592 while (rangeUnlinked.first != rangeUnlinked.second) {
5593 assert(rangeUnlinked.first->first == pindex->pprev);
5594 if (rangeUnlinked.first->second == pindex) {
5595 foundInUnlinked = true;
5596 break;
5597 }
5598 rangeUnlinked.first++;
5599 }
f9ec3f0f 5600 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5601 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5602 assert(foundInUnlinked);
5603 }
5604 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5605 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5606 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5607 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5608 assert(fHavePruned); // We must have pruned.
5609 // This block may have entered mapBlocksUnlinked if:
5610 // - it has a descendant that at some point had more work than the
5611 // tip, and
5612 // - we tried switching to that descendant but were missing
5613 // data for some intermediate block between chainActive and the
5614 // tip.
5615 // So if this block is itself better than chainActive.Tip() and it wasn't in
5616 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5617 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5618 if (pindexFirstInvalid == NULL) {
5619 assert(foundInUnlinked);
5620 }
3fcfbc8a 5621 }
3fcfbc8a
PW
5622 }
5623 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5624 // End: actual consistency checks.
8d655683 5625
3fcfbc8a
PW
5626 // Try descending into the first subnode.
5627 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5628 if (range.first != range.second) {
5629 // A subnode was found.
5630 pindex = range.first->second;
5631 nHeight++;
5632 continue;
5633 }
5634 // This is a leaf node.
5635 // Move upwards until we reach a node of which we have not yet visited the last child.
5636 while (pindex) {
5637 // We are going to either move to a parent or a sibling of pindex.
5638 // If pindex was the first with a certain property, unset the corresponding variable.
5639 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
5640 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
f9ec3f0f 5641 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
3fcfbc8a 5642 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
ede379f7 5643 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
3fcfbc8a
PW
5644 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
5645 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
5646 // Find our parent.
5647 CBlockIndex* pindexPar = pindex->pprev;
5648 // Find which child we just visited.
5649 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
5650 while (rangePar.first->second != pindex) {
5651 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
5652 rangePar.first++;
5653 }
5654 // Proceed to the next one.
5655 rangePar.first++;
5656 if (rangePar.first != rangePar.second) {
5657 // Move to the sibling.
5658 pindex = rangePar.first->second;
5659 break;
5660 } else {
5661 // Move up further.
5662 pindex = pindexPar;
5663 nHeight--;
5664 continue;
5665 }
5666 }
5667 }
8d655683 5668
3fcfbc8a
PW
5669 // Check that we actually traversed the entire map.
5670 assert(nNodes == forward.size());
5671}
5672
0a61b0df 5673//////////////////////////////////////////////////////////////////////////////
5674//
5675// CAlert
5676//
5677
db954a65 5678std::string GetWarnings(const std::string& strFor)
0a61b0df 5679{
5680 int nPriority = 0;
5681 string strStatusBar;
5682 string strRPC;
8d655683 5683
62e21fb5
WL
5684 if (!CLIENT_VERSION_IS_RELEASE)
5685 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
8d655683 5686
73578933 5687 if (GetBoolArg("-testsafemode", false))
5688 strStatusBar = strRPC = "testsafemode enabled";
8d655683 5689
0a61b0df 5690 // Misc warnings like out of disk space and clock is wrong
5691 if (strMiscWarning != "")
5692 {
5693 nPriority = 1000;
5694 strStatusBar = strMiscWarning;
5695 }
8d655683 5696
b8585384 5697 if (fLargeWorkForkFound)
0a61b0df 5698 {
5699 nPriority = 2000;
f65e7092
MC
5700 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
5701 }
5702 else if (fLargeWorkInvalidChainFound)
0a61b0df 5703 {
5704 nPriority = 2000;
f65e7092 5705 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.");
0a61b0df 5706 }
8d655683 5707
0a61b0df 5708 // Alerts
0a61b0df 5709 {
f8dcd5ca 5710 LOCK(cs_mapAlerts);
223b6f1b 5711 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
0a61b0df 5712 {
5713 const CAlert& alert = item.second;
5714 if (alert.AppliesToMe() && alert.nPriority > nPriority)
5715 {
5716 nPriority = alert.nPriority;
5717 strStatusBar = alert.strStatusBar;
a40034f7
JG
5718 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
5719 strRPC = alert.strRPCError;
5720 }
0a61b0df 5721 }
5722 }
5723 }
8d655683 5724
0a61b0df 5725 if (strFor == "statusbar")
5726 return strStatusBar;
5727 else if (strFor == "rpc")
5728 return strRPC;
5262fde0 5729 assert(!"GetWarnings(): invalid parameter");
0a61b0df 5730 return "error";
5731}
5732
0a61b0df 5733
5734
5735
5736
5737
5738
5739
5740//////////////////////////////////////////////////////////////////////////////
5741//
5742// Messages
5743//
5744
5745
72b25b0f 5746bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
0a61b0df 5747{
5748 switch (inv.type)
5749 {
8d655683 5750 case MSG_TX:
8deb9822 5751 {
5094a81d 5752 assert(recentRejects);
ec9b6c33
PT
5753 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
5754 {
5755 // If the chain tip has changed previously rejected transactions
5756 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
5757 // or a double-spend. Reset the rejects filter and give those
5758 // txs a second chance.
5759 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
5760 recentRejects->reset();
5761 }
8d655683 5762
ec9b6c33 5763 return recentRejects->contains(inv.hash) ||
8d655683 5764 mempool.exists(inv.hash) ||
5765 mapOrphanTransactions.count(inv.hash) ||
5766 pcoinsTip->HaveCoins(inv.hash);
8deb9822 5767 }
8d655683 5768 case MSG_BLOCK:
5769 return mapBlockIndex.count(inv.hash);
0a61b0df 5770 }
5771 // Don't know what it is, just say we already got one
5772 return true;
5773}
5774
c7f039b6
PW
5775void static ProcessGetData(CNode* pfrom)
5776{
5777 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
8d655683 5778
c7f039b6 5779 vector<CInv> vNotFound;
8d655683 5780
7d38af3c 5781 LOCK(cs_main);
8d655683 5782
c7f039b6
PW
5783 while (it != pfrom->vRecvGetData.end()) {
5784 // Don't bother if send buffer is too full to respond anyway
5785 if (pfrom->nSendSize >= SendBufferSize())
5786 break;
8d655683 5787
c7f039b6
PW
5788 const CInv &inv = *it;
5789 {
b31499ec 5790 boost::this_thread::interruption_point();
c7f039b6 5791 it++;
8d655683 5792
c7f039b6
PW
5793 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5794 {
d8b4b496 5795 bool send = false;
145d5be8 5796 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
c7f039b6
PW
5797 if (mi != mapBlockIndex.end())
5798 {
85da07a5 5799 if (chainActive.Contains(mi->second)) {
2b45345a 5800 send = true;
85da07a5 5801 } else {
f7303f97 5802 static const int nOneMonth = 30 * 24 * 60 * 60;
85da07a5 5803 // To prevent fingerprinting attacks, only send blocks outside of the active
f7303f97
PW
5804 // chain if they are valid, and no more than a month older (both in time, and in
5805 // best equivalent proof of work) than the best header chain we know about.
85da07a5 5806 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
8d655683 5807 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
5808 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
85da07a5 5809 if (!send) {
30c1db1c 5810 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
85da07a5 5811 }
d8b4b496
AH
5812 }
5813 }
f9ec3f0f 5814 // Pruned nodes may have deleted the block, so check whether
5815 // it's available before trying to send.
5816 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
d8b4b496
AH
5817 {
5818 // Send block from disk
c7f039b6 5819 CBlock block;
b8add6a4 5820 if (!ReadBlockFromDisk(block, (*mi).second,1))
13931733 5821 {
b34b7b31 5822 assert(!"cannot load block from disk");
13931733 5823 }
5824 else
c7f039b6 5825 {
13931733 5826 if (inv.type == MSG_BLOCK)
c2b0ec2e 5827 {
37782e4e 5828 //uint256 hash; int32_t z;
5829 //hash = block.GetHash();
5830 //for (z=31; z>=0; z--)
5831 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
5832 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
13931733 5833 pfrom->PushMessage("block", block);
c2b0ec2e 5834 }
13931733 5835 else // MSG_FILTERED_BLOCK)
c7f039b6 5836 {
13931733 5837 LOCK(pfrom->cs_filter);
5838 if (pfrom->pfilter)
5839 {
5840 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
5841 pfrom->PushMessage("merkleblock", merkleBlock);
5842 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
5843 // This avoids hurting performance by pointlessly requiring a round-trip
5844 // Note that there is currently no way for a node to request any single transactions we didn't send here -
5845 // they must either disconnect and retry or request the full block.
5846 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
5847 // however we MUST always provide at least what the remote peer needs
5848 typedef std::pair<unsigned int, uint256> PairType;
5849 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
c7f039b6
PW
5850 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
5851 pfrom->PushMessage("tx", block.vtx[pair.first]);
13931733 5852 }
5853 // else
c7f039b6 5854 // no response
13931733 5855 }
c7f039b6 5856 }
b05a89b2 5857 // Trigger the peer node to send a getblocks request for the next batch of inventory
c7f039b6
PW
5858 if (inv.hash == pfrom->hashContinue)
5859 {
5860 // Bypass PushInventory, this must send even if redundant,
5861 // and we want it right after the last block so they don't
5862 // wait for other stuff first.
5863 vector<CInv> vInv;
4c6d41b8 5864 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
c7f039b6 5865 pfrom->PushMessage("inv", vInv);
4f152496 5866 pfrom->hashContinue.SetNull();
c7f039b6
PW
5867 }
5868 }
5869 }
5870 else if (inv.IsKnownType())
5871 {
5872 // Send stream from relay memory
5873 bool pushed = false;
5874 {
5875 LOCK(cs_mapRelay);
5876 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
5877 if (mi != mapRelay.end()) {
5878 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
5879 pushed = true;
5880 }
5881 }
5882 if (!pushed && inv.type == MSG_TX) {
319b1160
GA
5883 CTransaction tx;
5884 if (mempool.lookup(inv.hash, tx)) {
c7f039b6
PW
5885 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
5886 ss.reserve(1000);
5887 ss << tx;
5888 pfrom->PushMessage("tx", ss);
5889 pushed = true;
5890 }
5891 }
5892 if (!pushed) {
5893 vNotFound.push_back(inv);
5894 }
5895 }
8d655683 5896
c7f039b6 5897 // Track requests for our stuff.
26c16d9d 5898 GetMainSignals().Inventory(inv.hash);
8d655683 5899
75ef87dd
PS
5900 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5901 break;
c7f039b6
PW
5902 }
5903 }
8d655683 5904
c7f039b6 5905 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
8d655683 5906
c7f039b6
PW
5907 if (!vNotFound.empty()) {
5908 // Let the peer know that we didn't find what it asked for, so it doesn't
5909 // have to wait around forever. Currently only SPV clients actually care
5910 // about this message: it's needed when they are recursively walking the
5911 // dependencies of relevant unconfirmed transactions. SPV clients want to
5912 // do that because they want to know about (and store and rebroadcast and
5913 // risk analyze) the dependencies of transactions relevant to them, without
5914 // having to download the entire memory pool.
5915 pfrom->PushMessage("notfound", vNotFound);
5916 }
5917}
5918
9f4da19b 5919bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
0a61b0df 5920{
e8e8904d 5921 const CChainParams& chainparams = Params();
28d4cff0 5922 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
37782e4e 5923 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
0a61b0df 5924 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
5925 {
881a85a2 5926 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
0a61b0df 5927 return true;
5928 }
dbe656fe 5929
0a61b0df 5930 if (strCommand == "version")
5931 {
5932 // Each connection can only send one version message
5933 if (pfrom->nVersion != 0)
806704c2 5934 {
358ce266 5935 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
b2864d2f 5936 Misbehaving(pfrom->GetId(), 1);
0a61b0df 5937 return false;
806704c2 5938 }
8d655683 5939
51ed9ec9 5940 int64_t nTime;
0a61b0df 5941 CAddress addrMe;
5942 CAddress addrFrom;
51ed9ec9 5943 uint64_t nNonce = 1;
0a61b0df 5944 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
1ce41892 5945 if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
18c0fa97 5946 {
1ce41892 5947 // disconnect from peers older than this proto version
2e36866f 5948 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
358ce266
GA
5949 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5950 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
18c0fa97
PW
5951 pfrom->fDisconnect = true;
5952 return false;
5953 }
8d655683 5954
72b21929
S
5955 // When Overwinter is active, reject incoming connections from non-Overwinter nodes
5956 const Consensus::Params& params = Params().GetConsensus();
5957 if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER)
5958 && pfrom->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)
5959 {
5960 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5961 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
8d655683 5962 strprintf("Version must be %d or greater",
5963 params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
72b21929
S
5964 pfrom->fDisconnect = true;
5965 return false;
5966 }
8d655683 5967
0a61b0df 5968 if (pfrom->nVersion == 10300)
5969 pfrom->nVersion = 300;
18c0fa97 5970 if (!vRecv.empty())
0a61b0df 5971 vRecv >> addrFrom >> nNonce;
a946aa8d 5972 if (!vRecv.empty()) {
216e9a44 5973 vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
a946aa8d
MH
5974 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
5975 }
18c0fa97 5976 if (!vRecv.empty())
0a61b0df 5977 vRecv >> pfrom->nStartingHeight;
4c8fc1a5
MC
5978 if (!vRecv.empty())
5979 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
5980 else
5981 pfrom->fRelayTxes = true;
8d655683 5982
0a61b0df 5983 // Disconnect if we connected to ourself
5984 if (nNonce == nLocalHostNonce && nNonce > 1)
5985 {
7d9d134b 5986 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
0a61b0df 5987 pfrom->fDisconnect = true;
5988 return true;
5989 }
8d655683 5990
845c86d1
GM
5991 pfrom->addrLocal = addrMe;
5992 if (pfrom->fInbound && addrMe.IsRoutable())
5993 {
5994 SeenLocal(addrMe);
5995 }
8d655683 5996
cbc920d4
GA
5997 // Be shy and don't send version until we hear
5998 if (pfrom->fInbound)
5999 pfrom->PushVersion();
8d655683 6000
0a61b0df 6001 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
8d655683 6002
b4ee0bdd
PW
6003 // Potentially mark this peer as a preferred download peer.
6004 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
8d655683 6005
0a61b0df 6006 // Change version
18c0fa97 6007 pfrom->PushMessage("verack");
41b052ad 6008 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
8d655683 6009
c891967b 6010 if (!pfrom->fInbound)
6011 {
6012 // Advertise our address
53a08815 6013 if (fListen && !IsInitialBlockDownload())
c891967b 6014 {
39857190
PW
6015 CAddress addr = GetLocalAddress(&pfrom->addr);
6016 if (addr.IsRoutable())
845c86d1 6017 {
eb5f63fe 6018 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
845c86d1
GM
6019 pfrom->PushAddress(addr);
6020 } else if (IsPeerAddrLocalGood(pfrom)) {
6021 addr.SetIP(pfrom->addrLocal);
eb5f63fe 6022 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
39857190 6023 pfrom->PushAddress(addr);
845c86d1 6024 }
c891967b 6025 }
8d655683 6026
c891967b 6027 // Get recent addresses
478b01d9 6028 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
c891967b 6029 {
6030 pfrom->PushMessage("getaddr");
6031 pfrom->fGetAddr = true;
6032 }
5fee401f
PW
6033 addrman.Good(pfrom->addr);
6034 } else {
6035 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
6036 {
6037 addrman.Add(addrFrom, addrFrom);
6038 addrman.Good(addrFrom);
6039 }
c891967b 6040 }
8d655683 6041
0a61b0df 6042 // Relay alerts
f8dcd5ca
PW
6043 {
6044 LOCK(cs_mapAlerts);
223b6f1b 6045 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
8d655683 6046 item.second.RelayTo(pfrom);
f8dcd5ca 6047 }
8d655683 6048
0a61b0df 6049 pfrom->fSuccessfullyConnected = true;
8d655683 6050
70b9d36a
JG
6051 string remoteAddr;
6052 if (fLogIPs)
6053 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
8d655683 6054
70b9d36a
JG
6055 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
6056 pfrom->cleanSubVer, pfrom->nVersion,
6057 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
6058 remoteAddr);
8d655683 6059
26a6bae7
PJ
6060 int64_t nTimeOffset = nTime - GetTime();
6061 pfrom->nTimeOffset = nTimeOffset;
6062 AddTimeData(pfrom->addr, nTimeOffset);
0a61b0df 6063 }
8d655683 6064
6065
0a61b0df 6066 else if (pfrom->nVersion == 0)
6067 {
6068 // Must have a version message before anything else
b2864d2f 6069 Misbehaving(pfrom->GetId(), 1);
0a61b0df 6070 return false;
6071 }
8d655683 6072
6073
0a61b0df 6074 else if (strCommand == "verack")
6075 {
607dbfde 6076 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
8d655683 6077
9c273790
PW
6078 // Mark this node as currently connected, so we update its timestamp later.
6079 if (pfrom->fNetworkNode) {
6080 LOCK(cs_main);
6081 State(pfrom->GetId())->fCurrentlyConnected = true;
6082 }
0a61b0df 6083 }
8d655683 6084
6085
72b21929
S
6086 // Disconnect existing peer connection when:
6087 // 1. The version message has been received
6088 // 2. Overwinter is active
6089 // 3. Peer version is pre-Overwinter
6090 else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
8d655683 6091 && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
72b21929
S
6092 {
6093 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
6094 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
8d655683 6095 strprintf("Version must be %d or greater",
6096 chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
72b21929
S
6097 pfrom->fDisconnect = true;
6098 return false;
6099 }
8d655683 6100
6101
0a61b0df 6102 else if (strCommand == "addr")
6103 {
6104 vector<CAddress> vAddr;
6105 vRecv >> vAddr;
8d655683 6106
c891967b 6107 // Don't want addr from older versions unless seeding
8b09cd3a 6108 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
0a61b0df 6109 return true;
6110 if (vAddr.size() > 1000)
806704c2 6111 {
b2864d2f 6112 Misbehaving(pfrom->GetId(), 20);
783b182c 6113 return error("message addr size() = %u", vAddr.size());
806704c2 6114 }
8d655683 6115
0a61b0df 6116 // Store the new addresses
090e5b40 6117 vector<CAddress> vAddrOk;
51ed9ec9
BD
6118 int64_t nNow = GetAdjustedTime();
6119 int64_t nSince = nNow - 10 * 60;
223b6f1b 6120 BOOST_FOREACH(CAddress& addr, vAddr)
0a61b0df 6121 {
b31499ec 6122 boost::this_thread::interruption_point();
8d655683 6123
c891967b 6124 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
6125 addr.nTime = nNow - 5 * 24 * 60 * 60;
0a61b0df 6126 pfrom->AddAddressKnown(addr);
090e5b40 6127 bool fReachable = IsReachable(addr);
c891967b 6128 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
0a61b0df 6129 {
6130 // Relay to a limited number of other nodes
0a61b0df 6131 {
f8dcd5ca 6132 LOCK(cs_vNodes);
5cbf7532 6133 // Use deterministic randomness to send to the same nodes for 24 hours
d81cff32 6134 // at a time so the addrKnowns of the chosen nodes prevent repeats
0a61b0df 6135 static uint256 hashSalt;
4f152496 6136 if (hashSalt.IsNull())
f718aedd 6137 hashSalt = GetRandHash();
51ed9ec9 6138 uint64_t hashAddr = addr.GetHash();
734f85c4 6139 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
5cbf7532 6140 hashRand = Hash(BEGIN(hashRand), END(hashRand));
0a61b0df 6141 multimap<uint256, CNode*> mapMix;
223b6f1b 6142 BOOST_FOREACH(CNode* pnode, vNodes)
5cbf7532 6143 {
8b09cd3a 6144 if (pnode->nVersion < CADDR_TIME_VERSION)
c891967b 6145 continue;
5cbf7532 6146 unsigned int nPointer;
6147 memcpy(&nPointer, &pnode, sizeof(nPointer));
734f85c4 6148 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
5cbf7532 6149 hashKey = Hash(BEGIN(hashKey), END(hashKey));
6150 mapMix.insert(make_pair(hashKey, pnode));
6151 }
090e5b40 6152 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
0a61b0df 6153 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
6154 ((*mi).second)->PushAddress(addr);
6155 }
6156 }
090e5b40
PW
6157 // Do not store addresses outside our network
6158 if (fReachable)
6159 vAddrOk.push_back(addr);
0a61b0df 6160 }
090e5b40 6161 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
0a61b0df 6162 if (vAddr.size() < 1000)
6163 pfrom->fGetAddr = false;
478b01d9
PW
6164 if (pfrom->fOneShot)
6165 pfrom->fDisconnect = true;
0a61b0df 6166 }
8d655683 6167
6168
0a61b0df 6169 else if (strCommand == "inv")
6170 {
6171 vector<CInv> vInv;
6172 vRecv >> vInv;
05a85b2b 6173 if (vInv.size() > MAX_INV_SZ)
806704c2 6174 {
b2864d2f 6175 Misbehaving(pfrom->GetId(), 20);
783b182c 6176 return error("message inv size() = %u", vInv.size());
806704c2 6177 }
8d655683 6178
7d38af3c 6179 LOCK(cs_main);
8d655683 6180
341735eb 6181 std::vector<CInv> vToFetch;
8d655683 6182
c376ac35 6183 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
0a61b0df 6184 {
0aa89c08 6185 const CInv &inv = vInv[nInv];
8d655683 6186
b31499ec 6187 boost::this_thread::interruption_point();
0a61b0df 6188 pfrom->AddInventoryKnown(inv);
8d655683 6189
ae8bfd12 6190 bool fAlreadyHave = AlreadyHave(inv);
2e36866f 6191 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
8d655683 6192
341735eb
PW
6193 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
6194 pfrom->AskFor(inv);
8d655683 6195
341735eb 6196 if (inv.type == MSG_BLOCK) {
aa815647 6197 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
341735eb 6198 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
7e6d23b1 6199 // First request the headers preceding the announced block. In the normal fully-synced
341735eb
PW
6200 // case where a new block is announced that succeeds the current tip (no reorganization),
6201 // there are no such headers.
6202 // Secondly, and only when we are close to being synced, we request the announced block directly,
6203 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
6204 // time the block arrives, the header chain leading up to it is already validated. Not
6205 // doing this will result in the received block being rejected as an orphan in case it is
6206 // not a direct successor.
6207 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
c9077043 6208 CNodeState *nodestate = State(pfrom->GetId());
e8e8904d 6209 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
c9077043 6210 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
341735eb
PW
6211 vToFetch.push_back(inv);
6212 // Mark block as in flight already, even though the actual "getdata" message only goes out
6213 // later (within the same cs_main lock, though).
82737933 6214 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
341735eb 6215 }
4c933229 6216 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
341735eb
PW
6217 }
6218 }
8d655683 6219
0a61b0df 6220 // Track requests for our stuff
26c16d9d 6221 GetMainSignals().Inventory(inv.hash);
8d655683 6222
540ac451
JG
6223 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
6224 Misbehaving(pfrom->GetId(), 50);
6225 return error("send buffer size() = %u", pfrom->nSendSize);
6226 }
0a61b0df 6227 }
8d655683 6228
341735eb
PW
6229 if (!vToFetch.empty())
6230 pfrom->PushMessage("getdata", vToFetch);
0a61b0df 6231 }
8d655683 6232
6233
0a61b0df 6234 else if (strCommand == "getdata")
6235 {
6236 vector<CInv> vInv;
6237 vRecv >> vInv;
05a85b2b 6238 if (vInv.size() > MAX_INV_SZ)
806704c2 6239 {
b2864d2f 6240 Misbehaving(pfrom->GetId(), 20);
783b182c 6241 return error("message getdata size() = %u", vInv.size());
806704c2 6242 }
8d655683 6243
3b570559 6244 if (fDebug || (vInv.size() != 1))
2e36866f 6245 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
8d655683 6246
3b570559 6247 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
2e36866f 6248 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
8d655683 6249
c7f039b6
PW
6250 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
6251 ProcessGetData(pfrom);
0a61b0df 6252 }
8d655683 6253
6254
0a61b0df 6255 else if (strCommand == "getblocks")
6256 {
6257 CBlockLocator locator;
6258 uint256 hashStop;
6259 vRecv >> locator >> hashStop;
8d655683 6260
7d38af3c 6261 LOCK(cs_main);
8d655683 6262
f03304a9 6263 // Find the last block the caller has in the main chain
6db83db3 6264 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
8d655683 6265
0a61b0df 6266 // Send the rest of the chain
6267 if (pindex)
4c6d41b8 6268 pindex = chainActive.Next(pindex);
9d6cd04b 6269 int nLimit = 500;
4f152496 6270 LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
4c6d41b8 6271 for (; pindex; pindex = chainActive.Next(pindex))
0a61b0df 6272 {
6273 if (pindex->GetBlockHash() == hashStop)
6274 {
7d9d134b 6275 LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
0a61b0df 6276 break;
6277 }
6278 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
9d6cd04b 6279 if (--nLimit <= 0)
0a61b0df 6280 {
b05a89b2
LD
6281 // When this block is requested, we'll send an inv that'll
6282 // trigger the peer to getblocks the next batch of inventory.
7d9d134b 6283 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
0a61b0df 6284 pfrom->hashContinue = pindex->GetBlockHash();
6285 break;
6286 }
6287 }
6288 }
8d655683 6289
6290
f03304a9 6291 else if (strCommand == "getheaders")
6292 {
6293 CBlockLocator locator;
6294 uint256 hashStop;
6295 vRecv >> locator >> hashStop;
8d655683 6296
7d38af3c 6297 LOCK(cs_main);
8d655683 6298
b4bbad18
SD
6299 if (IsInitialBlockDownload())
6300 return true;
8d655683 6301
f03304a9 6302 CBlockIndex* pindex = NULL;
6303 if (locator.IsNull())
6304 {
6305 // If locator is null, return the hashStop block
145d5be8 6306 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
f03304a9 6307 if (mi == mapBlockIndex.end())
6308 return true;
6309 pindex = (*mi).second;
6310 }
6311 else
6312 {
6313 // Find the last block the caller has in the main chain
6db83db3 6314 pindex = FindForkInGlobalIndex(chainActive, locator);
f03304a9 6315 if (pindex)
4c6d41b8 6316 pindex = chainActive.Next(pindex);
f03304a9 6317 }
52670b72 6318
c2923066
MT
6319 // we must use CNetworkBlockHeader, as CBlockHeader won't include the 0x00 nTx count at the end for compatibility
6320 vector<CNetworkBlockHeader> vHeaders;
341735eb 6321 int nLimit = MAX_HEADERS_RESULTS;
4c933229 6322 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
f8a07170 6323 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) )// no need to ever suppress this
f03304a9 6324 {
164bbe6c 6325 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->nHeight : -1);
336a60cf 6326 for (; pindex; pindex = chainActive.Next(pindex))
6327 {
01ff13ce 6328 CBlockHeader h = pindex->GetBlockHeader();
f6608b5a
MT
6329 //printf("size.%i, solution size.%i\n", (int)sizeof(h), (int)h.nSolution.size());
6330 //printf("hash.%s prevhash.%s nonce.%s\n", h.GetHash().ToString().c_str(), h.hashPrevBlock.ToString().c_str(), h.nNonce.ToString().c_str());
e96e4e61 6331 vHeaders.push_back(pindex->GetBlockHeader());
336a60cf 6332 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
6333 break;
6334 }
6335 pfrom->PushMessage("headers", vHeaders);
8dcf7f94 6336 }
4d068367 6337 /*else if ( IS_KOMODO_NOTARY != 0 )
bd901dd7 6338 {
6339 static uint32_t counter;
6340 if ( counter++ < 3 )
6341 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);
f8a07170 6342 }*/
f03304a9 6343 }
8d655683 6344
6345
0a61b0df 6346 else if (strCommand == "tx")
6347 {
6348 vector<uint256> vWorkQueue;
7a15109c 6349 vector<uint256> vEraseQueue;
0a61b0df 6350 CTransaction tx;
6351 vRecv >> tx;
8d655683 6352
805344dc 6353 CInv inv(MSG_TX, tx.GetHash());
0a61b0df 6354 pfrom->AddInventoryKnown(inv);
8d655683 6355
7d38af3c 6356 LOCK(cs_main);
8d655683 6357
0a61b0df 6358 bool fMissingInputs = false;
ef3988ca 6359 CValidationState state;
8d655683 6360
e2190f80 6361 pfrom->setAskFor.erase(inv.hash);
604ee2aa 6362 mapAlreadyAskedFor.erase(inv);
8d655683 6363
60aed954 6364 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
0a61b0df 6365 {
a0fa20a1 6366 mempool.check(pcoinsTip);
d38da59b 6367 RelayTransaction(tx);
0a61b0df 6368 vWorkQueue.push_back(inv.hash);
8d655683 6369
5262fde0 6370 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
8d655683 6371 pfrom->id, pfrom->cleanSubVer,
6372 tx.GetHash().ToString(),
6373 mempool.mapTx.size());
6374
0a61b0df 6375 // Recursively process any orphan transactions that depended on this one
c74332c6 6376 set<NodeId> setMisbehaving;
c376ac35 6377 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
0a61b0df 6378 {
89d91f6a
WL
6379 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
6380 if (itByPrev == mapOrphanTransactionsByPrev.end())
6381 continue;
6382 for (set<uint256>::iterator mi = itByPrev->second.begin();
6383 mi != itByPrev->second.end();
0a61b0df 6384 ++mi)
6385 {
159bc481 6386 const uint256& orphanHash = *mi;
c74332c6
GA
6387 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
6388 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
7a15109c 6389 bool fMissingInputs2 = false;
159bc481
GA
6390 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
6391 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
6392 // anyone relaying LegitTxX banned)
8c4e4313 6393 CValidationState stateDummy;
8d655683 6394
6395
c74332c6
GA
6396 if (setMisbehaving.count(fromPeer))
6397 continue;
319b1160 6398 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
0a61b0df 6399 {
7d9d134b 6400 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
d38da59b 6401 RelayTransaction(orphanTx);
159bc481 6402 vWorkQueue.push_back(orphanHash);
37b4e425 6403 vEraseQueue.push_back(orphanHash);
7a15109c
GA
6404 }
6405 else if (!fMissingInputs2)
6406 {
c74332c6
GA
6407 int nDos = 0;
6408 if (stateDummy.IsInvalid(nDos) && nDos > 0)
6409 {
6410 // Punish peer that gave us an invalid orphan tx
6411 Misbehaving(fromPeer, nDos);
6412 setMisbehaving.insert(fromPeer);
6413 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
6414 }
37b4e425
AM
6415 // Has inputs but not accepted to mempool
6416 // Probably non-standard or insufficient fee/priority
7d9d134b 6417 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
37b4e425 6418 vEraseQueue.push_back(orphanHash);
5094a81d 6419 assert(recentRejects);
ec9b6c33 6420 recentRejects->insert(orphanHash);
0a61b0df 6421 }
a0fa20a1 6422 mempool.check(pcoinsTip);
0a61b0df 6423 }
6424 }
8d655683 6425
7a15109c 6426 BOOST_FOREACH(uint256 hash, vEraseQueue)
8d655683 6427 EraseOrphanTx(hash);
0a61b0df 6428 }
b7e4abd6 6429 // TODO: currently, prohibit joinsplits from entering mapOrphans
8675d94b 6430 else if (fMissingInputs && tx.vjoinsplit.size() == 0)
0a61b0df 6431 {
c74332c6 6432 AddOrphanTx(tx, pfrom->GetId());
8d655683 6433
142e6041 6434 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
aa3c697e
GA
6435 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6436 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
142e6041 6437 if (nEvicted > 0)
881a85a2 6438 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
ec9b6c33 6439 } else {
36f14bf2 6440 assert(recentRejects);
805344dc 6441 recentRejects->insert(tx.GetHash());
8d655683 6442
ec9b6c33
PT
6443 if (pfrom->fWhitelisted) {
6444 // Always relay transactions received from whitelisted peers, even
60aed954
PW
6445 // if they were already in the mempool or rejected from it due
6446 // to policy, allowing the node to function as a gateway for
6447 // nodes hidden behind it.
ec9b6c33 6448 //
60aed954
PW
6449 // Never relay transactions that we would assign a non-zero DoS
6450 // score for, as we expect peers to do the same with us in that
6451 // case.
6452 int nDoS = 0;
6453 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6454 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6455 RelayTransaction(tx);
6456 } else {
e63d14fd 6457 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
8d655683 6458 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
60aed954 6459 }
ec9b6c33 6460 }
0a61b0df 6461 }
fbed9c9d 6462 int nDoS = 0;
5ea66c54 6463 if (state.IsInvalid(nDoS))
2b45345a 6464 {
805344dc 6465 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
8d655683 6466 pfrom->id, pfrom->cleanSubVer,
6467 state.GetRejectReason());
358ce266 6468 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
307f7d48 6469 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
5ea66c54 6470 if (nDoS > 0)
b2864d2f 6471 Misbehaving(pfrom->GetId(), nDoS);
358ce266 6472 }
0a61b0df 6473 }
c2923066 6474
341735eb
PW
6475 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6476 {
6477 std::vector<CBlockHeader> headers;
8d655683 6478
341735eb
PW
6479 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6480 unsigned int nCount = ReadCompactSize(vRecv);
6481 if (nCount > MAX_HEADERS_RESULTS) {
6482 Misbehaving(pfrom->GetId(), 20);
6483 return error("headers message size = %u", nCount);
6484 }
6485 headers.resize(nCount);
6486 for (unsigned int n = 0; n < nCount; n++) {
6487 vRecv >> headers[n];
c2923066 6488 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
341735eb 6489 }
8d655683 6490
341735eb 6491 LOCK(cs_main);
8d655683 6492
341735eb
PW
6493 if (nCount == 0) {
6494 // Nothing interesting. Stop asking this peers for more headers.
6495 return true;
6496 }
8d655683 6497
341735eb 6498 CBlockIndex *pindexLast = NULL;
e96e4e61 6499 BOOST_FOREACH(const CBlockHeader& header, headers) {
f6608b5a
MT
6500 //printf("size.%i, solution size.%i\n", (int)sizeof(header), (int)header.nSolution.size());
6501 //printf("hash.%s prevhash.%s nonce.%s\n", header.GetHash().ToString().c_str(), header.hashPrevBlock.ToString().c_str(), header.nNonce.ToString().c_str());
fbe86cec 6502
341735eb
PW
6503 CValidationState state;
6504 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6505 Misbehaving(pfrom->GetId(), 20);
6506 return error("non-continuous headers sequence");
6507 }
531b9293 6508 int32_t futureblock;
531b9293 6509 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
341735eb 6510 int nDoS;
753b841f 6511 if (state.IsInvalid(nDoS) && futureblock == 0)
6477ad07 6512 {
531b9293 6513 if (nDoS > 0 && futureblock == 0)
0d2cefb0 6514 Misbehaving(pfrom->GetId(), nDoS/nDoS);
341735eb
PW
6515 return error("invalid header received");
6516 }
6517 }
6518 }
8d655683 6519
341735eb
PW
6520 if (pindexLast)
6521 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
8d655683 6522
341735eb
PW
6523 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6524 // Headers message had its maximum size; the peer may have more headers.
6525 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6526 // from there instead.
8ab425f8 6527 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->nHeight != pfrom->sendhdrsreq )
6528 {
6529 pfrom->sendhdrsreq = (int32_t)pindexLast->nHeight;
6530 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
6531 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6532 }
341735eb 6533 }
8d655683 6534
3fcfbc8a 6535 CheckBlockIndex();
341735eb 6536 }
8d655683 6537
7fea4846 6538 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
0a61b0df 6539 {
f03304a9 6540 CBlock block;
6541 vRecv >> block;
8d655683 6542
f03304a9 6543 CInv inv(MSG_BLOCK, block.GetHash());
341735eb 6544 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
8d655683 6545
341735eb 6546 pfrom->AddInventoryKnown(inv);
8d655683 6547
ef3988ca 6548 CValidationState state;
93b606ae
SD
6549 // Process all blocks from whitelisted peers, even if not requested,
6550 // unless we're still syncing with the network.
6551 // Such an unrequested block may still be processed, subject to the
6552 // conditions in AcceptBlock().
6553 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
7bb789bb 6554 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
40f5cb87
PW
6555 int nDoS;
6556 if (state.IsInvalid(nDoS)) {
6557 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
307f7d48 6558 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
40f5cb87
PW
6559 if (nDoS > 0) {
6560 LOCK(cs_main);
6561 Misbehaving(pfrom->GetId(), nDoS);
6562 }
6563 }
8d655683 6564
0a61b0df 6565 }
8d655683 6566
6567
dca799e1
IP
6568 // This asymmetric behavior for inbound and outbound connections was introduced
6569 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
b05a89b2
LD
6570 // to users' AddrMan and later request them by sending getaddr messages.
6571 // Making nodes which are behind NAT and can only make outgoing connections ignore
6572 // the getaddr message mitigates the attack.
dca799e1 6573 else if ((strCommand == "getaddr") && (pfrom->fInbound))
0a61b0df 6574 {
a514cb29
GM
6575 // Only send one GetAddr response per connection to reduce resource waste
6576 // and discourage addr stamping of INV announcements.
6577 if (pfrom->fSentAddr) {
6578 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6579 return true;
6580 }
6581 pfrom->fSentAddr = true;
8d655683 6582
0a61b0df 6583 pfrom->vAddrToSend.clear();
5fee401f
PW
6584 vector<CAddress> vAddr = addrman.GetAddr();
6585 BOOST_FOREACH(const CAddress &addr, vAddr)
8d655683 6586 pfrom->PushAddress(addr);
0a61b0df 6587 }
8d655683 6588
6589
05a85b2b
JG
6590 else if (strCommand == "mempool")
6591 {
319b1160 6592 LOCK2(cs_main, pfrom->cs_filter);
8d655683 6593
05a85b2b
JG
6594 std::vector<uint256> vtxid;
6595 mempool.queryHashes(vtxid);
6596 vector<CInv> vInv;
c51694eb
MC
6597 BOOST_FOREACH(uint256& hash, vtxid) {
6598 CInv inv(MSG_TX, hash);
319b1160
GA
6599 CTransaction tx;
6600 bool fInMemPool = mempool.lookup(hash, tx);
6601 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
d38da59b 6602 if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
8d655683 6603 (!pfrom->pfilter))
c51694eb 6604 vInv.push_back(inv);
1f3d3647
GA
6605 if (vInv.size() == MAX_INV_SZ) {
6606 pfrom->PushMessage("inv", vInv);
6607 vInv.clear();
6608 }
05a85b2b
JG
6609 }
6610 if (vInv.size() > 0)
6611 pfrom->PushMessage("inv", vInv);
6612 }
8d655683 6613
6614
0a61b0df 6615 else if (strCommand == "ping")
6616 {
93e447b6
JG
6617 if (pfrom->nVersion > BIP0031_VERSION)
6618 {
51ed9ec9 6619 uint64_t nonce = 0;
93e447b6
JG
6620 vRecv >> nonce;
6621 // Echo the message back with the nonce. This allows for two useful features:
6622 //
6623 // 1) A remote node can quickly check if the connection is operational
6624 // 2) Remote nodes can measure the latency of the network thread. If this node
6625 // is overloaded it won't respond to pings quickly and the remote node can
6626 // avoid sending us more work, like chain download requests.
6627 //
6628 // The nonce stops the remote getting confused between different pings: without
6629 // it, if the remote node sends a ping once per second and this node takes 5
6630 // seconds to respond to each, the 5th ping the remote sends would appear to
6631 // return very quickly.
6632 pfrom->PushMessage("pong", nonce);
6633 }
0a61b0df 6634 }
8d655683 6635
6636
971bb3e9
JL
6637 else if (strCommand == "pong")
6638 {
9f4da19b 6639 int64_t pingUsecEnd = nTimeReceived;
51ed9ec9 6640 uint64_t nonce = 0;
971bb3e9
JL
6641 size_t nAvail = vRecv.in_avail();
6642 bool bPingFinished = false;
6643 std::string sProblem;
8d655683 6644
971bb3e9
JL
6645 if (nAvail >= sizeof(nonce)) {
6646 vRecv >> nonce;
8d655683 6647
971bb3e9
JL
6648 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
6649 if (pfrom->nPingNonceSent != 0) {
6650 if (nonce == pfrom->nPingNonceSent) {
6651 // Matching pong received, this ping is no longer outstanding
6652 bPingFinished = true;
51ed9ec9 6653 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
971bb3e9
JL
6654 if (pingUsecTime > 0) {
6655 // Successful ping time measurement, replace previous
6656 pfrom->nPingUsecTime = pingUsecTime;
e279e5f9 6657 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
971bb3e9
JL
6658 } else {
6659 // This should never happen
6660 sProblem = "Timing mishap";
6661 }
6662 } else {
6663 // Nonce mismatches are normal when pings are overlapping
6664 sProblem = "Nonce mismatch";
6665 if (nonce == 0) {
7e6d23b1 6666 // This is most likely a bug in another implementation somewhere; cancel this ping
971bb3e9
JL
6667 bPingFinished = true;
6668 sProblem = "Nonce zero";
6669 }
6670 }
6671 } else {
6672 sProblem = "Unsolicited pong without ping";
6673 }
6674 } else {
7e6d23b1 6675 // This is most likely a bug in another implementation somewhere; cancel this ping
971bb3e9
JL
6676 bPingFinished = true;
6677 sProblem = "Short payload";
6678 }
8d655683 6679
971bb3e9 6680 if (!(sProblem.empty())) {
2e36866f 6681 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
8d655683 6682 pfrom->id,
6683 pfrom->cleanSubVer,
6684 sProblem,
6685 pfrom->nPingNonceSent,
6686 nonce,
6687 nAvail);
971bb3e9
JL
6688 }
6689 if (bPingFinished) {
6690 pfrom->nPingNonceSent = 0;
6691 }
6692 }
8d655683 6693
6694
4d9c7fe6 6695 else if (fAlerts && strCommand == "alert")
0a61b0df 6696 {
6697 CAlert alert;
6698 vRecv >> alert;
8d655683 6699
d5a52d9b
GA
6700 uint256 alertHash = alert.GetHash();
6701 if (pfrom->setKnown.count(alertHash) == 0)
0a61b0df 6702 {
f14e687f 6703 if (alert.ProcessAlert(Params().AlertKey()))
f8dcd5ca 6704 {
d5a52d9b
GA
6705 // Relay
6706 pfrom->setKnown.insert(alertHash);
6707 {
6708 LOCK(cs_vNodes);
6709 BOOST_FOREACH(CNode* pnode, vNodes)
8d655683 6710 alert.RelayTo(pnode);
d5a52d9b
GA
6711 }
6712 }
6713 else {
6714 // Small DoS penalty so peers that send us lots of
6715 // duplicate/expired/invalid-signature/whatever alerts
6716 // eventually get banned.
6717 // This isn't a Misbehaving(100) (immediate ban) because the
6718 // peer might be an older or different implementation with
6719 // a different signature key, etc.
b2864d2f 6720 Misbehaving(pfrom->GetId(), 10);
f8dcd5ca 6721 }
0a61b0df 6722 }
6723 }
8d655683 6724
6725
422d1225
MC
6726 else if (strCommand == "filterload")
6727 {
6728 CBloomFilter filter;
6729 vRecv >> filter;
8d655683 6730
422d1225
MC
6731 if (!filter.IsWithinSizeConstraints())
6732 // There is no excuse for sending a too-large filter
b2864d2f 6733 Misbehaving(pfrom->GetId(), 100);
422d1225
MC
6734 else
6735 {
6736 LOCK(pfrom->cs_filter);
6737 delete pfrom->pfilter;
6738 pfrom->pfilter = new CBloomFilter(filter);
a7f533a9 6739 pfrom->pfilter->UpdateEmptyFull();
422d1225 6740 }
4c8fc1a5 6741 pfrom->fRelayTxes = true;
422d1225 6742 }
8d655683 6743
6744
422d1225
MC
6745 else if (strCommand == "filteradd")
6746 {
6747 vector<unsigned char> vData;
6748 vRecv >> vData;
8d655683 6749
422d1225
MC
6750 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
6751 // and thus, the maximum size any matched object can have) in a filteradd message
192cc910 6752 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
422d1225 6753 {
b2864d2f 6754 Misbehaving(pfrom->GetId(), 100);
422d1225
MC
6755 } else {
6756 LOCK(pfrom->cs_filter);
6757 if (pfrom->pfilter)
6758 pfrom->pfilter->insert(vData);
6759 else
b2864d2f 6760 Misbehaving(pfrom->GetId(), 100);
422d1225
MC
6761 }
6762 }
8d655683 6763
6764
422d1225
MC
6765 else if (strCommand == "filterclear")
6766 {
6767 LOCK(pfrom->cs_filter);
6768 delete pfrom->pfilter;
37c6389c 6769 pfrom->pfilter = new CBloomFilter();
4c8fc1a5 6770 pfrom->fRelayTxes = true;
422d1225 6771 }
8d655683 6772
6773
358ce266
GA
6774 else if (strCommand == "reject")
6775 {
efad808a
PW
6776 if (fDebug) {
6777 try {
6778 string strMsg; unsigned char ccode; string strReason;
307f7d48 6779 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
8d655683 6780
efad808a
PW
6781 ostringstream ss;
6782 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
8d655683 6783
efad808a
PW
6784 if (strMsg == "block" || strMsg == "tx")
6785 {
6786 uint256 hash;
6787 vRecv >> hash;
6788 ss << ": hash " << hash.ToString();
6789 }
6790 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
27df4123 6791 } catch (const std::ios_base::failure&) {
efad808a
PW
6792 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
6793 LogPrint("net", "Unparseable reject message received\n");
358ce266 6794 }
358ce266
GA
6795 }
6796 }
432bc22a 6797 else if (strCommand == "notfound") {
e496b2e3
WL
6798 // We do not care about the NOTFOUND message, but logging an Unknown Command
6799 // message would be undesirable as we transmit it ourselves.
6800 }
8d655683 6801
e496b2e3 6802 else {
0a61b0df 6803 // Ignore unknown commands for extensibility
6ecf3edf 6804 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
0a61b0df 6805 }
8d655683 6806
6807
6808
0a61b0df 6809 return true;
6810}
6811
607dbfde 6812// requires LOCK(cs_vRecvMsg)
e89b9f6a
PW
6813bool ProcessMessages(CNode* pfrom)
6814{
e89b9f6a 6815 //if (fDebug)
30c1db1c 6816 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
8d655683 6817
e89b9f6a
PW
6818 //
6819 // Message format
6820 // (4) message start
6821 // (12) command
6822 // (4) size
6823 // (4) checksum
6824 // (x) data
6825 //
967f2459 6826 bool fOk = true;
8d655683 6827
c7f039b6
PW
6828 if (!pfrom->vRecvGetData.empty())
6829 ProcessGetData(pfrom);
8d655683 6830
75ef87dd
PS
6831 // this maintains the order of responses
6832 if (!pfrom->vRecvGetData.empty()) return fOk;
8d655683 6833
967f2459 6834 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
41b052ad 6835 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
9d6cd04b 6836 // Don't bother if send buffer is too full to respond anyway
41b052ad 6837 if (pfrom->nSendSize >= SendBufferSize())
9d6cd04b 6838 break;
8d655683 6839
967f2459
PW
6840 // get next message
6841 CNetMessage& msg = *it;
8d655683 6842
607dbfde 6843 //if (fDebug)
30c1db1c 6844 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
607dbfde
JG
6845 // msg.hdr.nMessageSize, msg.vRecv.size(),
6846 // msg.complete() ? "Y" : "N");
8d655683 6847
967f2459 6848 // end, if an incomplete message is found
607dbfde 6849 if (!msg.complete())
e89b9f6a 6850 break;
8d655683 6851
967f2459
PW
6852 // at this point, any failure means we can delete the current message
6853 it++;
8d655683 6854
607dbfde 6855 // Scan for message start
0e4b3175 6856 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
28d4cff0 6857 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
967f2459
PW
6858 fOk = false;
6859 break;
e89b9f6a 6860 }
8d655683 6861
e89b9f6a 6862 // Read header
607dbfde 6863 CMessageHeader& hdr = msg.hdr;
eec37136 6864 if (!hdr.IsValid(Params().MessageStart()))
e89b9f6a 6865 {
28d4cff0 6866 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
e89b9f6a
PW
6867 continue;
6868 }
6869 string strCommand = hdr.GetCommand();
8d655683 6870
e89b9f6a
PW
6871 // Message size
6872 unsigned int nMessageSize = hdr.nMessageSize;
8d655683 6873
e89b9f6a 6874 // Checksum
607dbfde 6875 CDataStream& vRecv = msg.vRecv;
18c0fa97 6876 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
556814ec 6877 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
18c0fa97 6878 if (nChecksum != hdr.nChecksum)
e89b9f6a 6879 {
30c1db1c 6880 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
8d655683 6881 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
18c0fa97 6882 continue;
e89b9f6a 6883 }
8d655683 6884
e89b9f6a
PW
6885 // Process message
6886 bool fRet = false;
6887 try
6888 {
9f4da19b 6889 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
b31499ec 6890 boost::this_thread::interruption_point();
e89b9f6a 6891 }
27df4123 6892 catch (const std::ios_base::failure& e)
e89b9f6a 6893 {
358ce266 6894 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
e89b9f6a
PW
6895 if (strstr(e.what(), "end of data"))
6896 {
814efd6f 6897 // Allow exceptions from under-length message on vRecv
30c1db1c 6898 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());
e89b9f6a
PW
6899 }
6900 else if (strstr(e.what(), "size too large"))
6901 {
814efd6f 6902 // Allow exceptions from over-long size
30c1db1c 6903 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
e89b9f6a
PW
6904 }
6905 else
6906 {
5970a0d7 6907 //PrintExceptionContinue(&e, "ProcessMessages()");
e89b9f6a
PW
6908 }
6909 }
27df4123 6910 catch (const boost::thread_interrupted&) {
b31499ec
GA
6911 throw;
6912 }
27df4123 6913 catch (const std::exception& e) {
ea591ead 6914 PrintExceptionContinue(&e, "ProcessMessages()");
e89b9f6a 6915 } catch (...) {
ea591ead 6916 PrintExceptionContinue(NULL, "ProcessMessages()");
e89b9f6a 6917 }
8d655683 6918
e89b9f6a 6919 if (!fRet)
30c1db1c 6920 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
8d655683 6921
75ef87dd 6922 break;
e89b9f6a 6923 }
8d655683 6924
41b052ad
PW
6925 // In case the connection got shut down, its receive buffer was wiped
6926 if (!pfrom->fDisconnect)
6927 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
8d655683 6928
967f2459 6929 return fOk;
e89b9f6a 6930}
0a61b0df 6931
6932
0a61b0df 6933bool SendMessages(CNode* pto, bool fSendTrickle)
6934{
e8e8904d 6935 const Consensus::Params& consensusParams = Params().GetConsensus();
6055b910 6936 {
b05a89b2 6937 // Don't send anything until we get its version message
0a61b0df 6938 if (pto->nVersion == 0)
6939 return true;
8d655683 6940
971bb3e9
JL
6941 //
6942 // Message: ping
6943 //
6944 bool pingSend = false;
6945 if (pto->fPingQueued) {
6946 // RPC ping request by user
6947 pingSend = true;
6948 }
f1920e86
PW
6949 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
6950 // Ping automatically sent as a latency probe & keepalive.
971bb3e9
JL
6951 pingSend = true;
6952 }
6953 if (pingSend) {
51ed9ec9 6954 uint64_t nonce = 0;
971bb3e9 6955 while (nonce == 0) {
001a53d7 6956 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
971bb3e9 6957 }
971bb3e9 6958 pto->fPingQueued = false;
f1920e86 6959 pto->nPingUsecStart = GetTimeMicros();
971bb3e9 6960 if (pto->nVersion > BIP0031_VERSION) {
f1920e86 6961 pto->nPingNonceSent = nonce;
c971112d 6962 pto->PushMessage("ping", nonce);
971bb3e9 6963 } else {
f1920e86
PW
6964 // Peer is too old to support ping command with nonce, pong will never arrive.
6965 pto->nPingNonceSent = 0;
93e447b6 6966 pto->PushMessage("ping");
971bb3e9 6967 }
93e447b6 6968 }
8d655683 6969
55a1db4f
WL
6970 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
6971 if (!lockMain)
6972 return true;
8d655683 6973
0a61b0df 6974 // Address refresh broadcast
51ed9ec9 6975 static int64_t nLastRebroadcast;
5d1b8f17 6976 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
0a61b0df 6977 {
845c86d1
GM
6978 LOCK(cs_vNodes);
6979 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 6980 {
d81cff32 6981 // Periodically clear addrKnown to allow refresh broadcasts
845c86d1 6982 if (nLastRebroadcast)
83671efe 6983 pnode->addrKnown.reset();
8d655683 6984
845c86d1
GM
6985 // Rebroadcast our address
6986 AdvertizeLocal(pnode);
0a61b0df 6987 }
845c86d1
GM
6988 if (!vNodes.empty())
6989 nLastRebroadcast = GetTime();
0a61b0df 6990 }
8d655683 6991
0a61b0df 6992 //
6993 // Message: addr
6994 //
6995 if (fSendTrickle)
6996 {
6997 vector<CAddress> vAddr;
6998 vAddr.reserve(pto->vAddrToSend.size());
223b6f1b 6999 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
0a61b0df 7000 {
d81cff32 7001 if (!pto->addrKnown.contains(addr.GetKey()))
0a61b0df 7002 {
d81cff32 7003 pto->addrKnown.insert(addr.GetKey());
0a61b0df 7004 vAddr.push_back(addr);
7005 // receiver rejects addr messages larger than 1000
7006 if (vAddr.size() >= 1000)
7007 {
7008 pto->PushMessage("addr", vAddr);
7009 vAddr.clear();
7010 }
7011 }
7012 }
7013 pto->vAddrToSend.clear();
7014 if (!vAddr.empty())
7015 pto->PushMessage("addr", vAddr);
7016 }
8d655683 7017
75f51f2a
PW
7018 CNodeState &state = *State(pto->GetId());
7019 if (state.fShouldBan) {
dc942e6f
PW
7020 if (pto->fWhitelisted)
7021 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
b2864d2f
PW
7022 else {
7023 pto->fDisconnect = true;
dc942e6f
PW
7024 if (pto->addr.IsLocal())
7025 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
7026 else
c74332c6 7027 {
dc942e6f 7028 CNode::Ban(pto->addr);
c74332c6 7029 }
b2864d2f 7030 }
75f51f2a 7031 state.fShouldBan = false;
b2864d2f 7032 }
8d655683 7033
75f51f2a 7034 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
8d655683 7035 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
75f51f2a 7036 state.rejects.clear();
8d655683 7037
6055b910 7038 // Start block sync
341735eb
PW
7039 if (pindexBestHeader == NULL)
7040 pindexBestHeader = chainActive.Tip();
b4ee0bdd 7041 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.
00dcaf4b 7042 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
341735eb 7043 // Only actively request headers from a single peer, unless we're close to today.
00dcaf4b 7044 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
341735eb
PW
7045 state.fSyncStarted = true;
7046 nSyncStarted++;
7047 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
4c933229 7048 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
4f152496 7049 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
341735eb 7050 }
6055b910 7051 }
8d655683 7052
6055b910
PW
7053 // Resend wallet transactions that haven't gotten in a block yet
7054 // Except during reindex, importing and IBD, when old wallet
7055 // transactions become unconfirmed and spams other nodes.
7056 if (!fReindex && !fImporting && !IsInitialBlockDownload())
7057 {
0f5954c4 7058 GetMainSignals().Broadcast(nTimeBestReceived);
6055b910 7059 }
8d655683 7060
0a61b0df 7061 //
7062 // Message: inventory
7063 //
7064 vector<CInv> vInv;
7065 vector<CInv> vInvWait;
0a61b0df 7066 {
f8dcd5ca 7067 LOCK(pto->cs_inventory);
0a61b0df 7068 vInv.reserve(pto->vInventoryToSend.size());
7069 vInvWait.reserve(pto->vInventoryToSend.size());
223b6f1b 7070 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
0a61b0df 7071 {
7072 if (pto->setInventoryKnown.count(inv))
7073 continue;
8d655683 7074
0a61b0df 7075 // trickle out tx inv to protect privacy
7076 if (inv.type == MSG_TX && !fSendTrickle)
7077 {
7078 // 1/4 of tx invs blast to all immediately
7079 static uint256 hashSalt;
4f152496 7080 if (hashSalt.IsNull())
f718aedd 7081 hashSalt = GetRandHash();
734f85c4 7082 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
0a61b0df 7083 hashRand = Hash(BEGIN(hashRand), END(hashRand));
734f85c4 7084 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
8d655683 7085
0a61b0df 7086 if (fTrickleWait)
7087 {
7088 vInvWait.push_back(inv);
7089 continue;
7090 }
7091 }
8d655683 7092
0a61b0df 7093 // returns true if wasn't already contained in the set
7094 if (pto->setInventoryKnown.insert(inv).second)
7095 {
7096 vInv.push_back(inv);
7097 if (vInv.size() >= 1000)
7098 {
7099 pto->PushMessage("inv", vInv);
7100 vInv.clear();
7101 }
7102 }
7103 }
7104 pto->vInventoryToSend = vInvWait;
7105 }
7106 if (!vInv.empty())
7107 pto->PushMessage("inv", vInv);
8d655683 7108
341735eb 7109 // Detect whether we're stalling
f59d8f0b 7110 int64_t nNow = GetTimeMicros();
341735eb
PW
7111 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
7112 // Stalling only triggers when the block download window cannot move. During normal steady state,
7113 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
7114 // should only happen during initial block download.
7115 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
f59d8f0b
PW
7116 pto->fDisconnect = true;
7117 }
3ff735c9 7118 // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
91613034
PW
7119 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
7120 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7e6d23b1 7121 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
91613034 7122 // to unreasonably increase our timeout.
8ba7f842
SD
7123 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
7124 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
7125 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
7126 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
7127 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
7128 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
7129 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
82737933 7130 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
8ba7f842
SD
7131 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
7132 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
7133 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
7134 }
7135 if (queuedBlock.nTimeDisconnect < nNow) {
7136 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
7137 pto->fDisconnect = true;
7138 }
91613034 7139 }
8d655683 7140
0a61b0df 7141 //
f59d8f0b 7142 // Message: getdata (blocks)
0a61b0df 7143 //
161f617d 7144 static uint256 zero;
0a61b0df 7145 vector<CInv> vGetData;
00dcaf4b 7146 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
341735eb
PW
7147 vector<CBlockIndex*> vToDownload;
7148 NodeId staller = -1;
7149 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
7150 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
7151 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
82737933 7152 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
1af838b3 7153 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
8d655683 7154 pindex->nHeight, pto->id);
341735eb
PW
7155 }
7156 if (state.nBlocksInFlight == 0 && staller != -1) {
1bcee67e 7157 if (State(staller)->nStallingSince == 0) {
341735eb 7158 State(staller)->nStallingSince = nNow;
1bcee67e
B
7159 LogPrint("net", "Stall started peer=%d\n", staller);
7160 }
f59d8f0b
PW
7161 }
7162 }
8d725ab4 7163 /*CBlockIndex *pindex;
bddeaf5e 7164 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
161f617d 7165 {
bddeaf5e 7166 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
7167 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
161f617d 7168 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
7169 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
bddeaf5e 7170 komodo_requestedcount++;
7171 if ( komodo_requestedcount > 16 )
7172 {
7173 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
7174 komodo_requestedcount = 0;
7175 }
8d725ab4 7176 }*/
161f617d 7177
f59d8f0b
PW
7178 //
7179 // Message: getdata (non-blocks)
7180 //
7181 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
0a61b0df 7182 {
7183 const CInv& inv = (*pto->mapAskFor.begin()).second;
ae8bfd12 7184 if (!AlreadyHave(inv))
0a61b0df 7185 {
3b570559 7186 if (fDebug)
2e36866f 7187 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
0a61b0df 7188 vGetData.push_back(inv);
7189 if (vGetData.size() >= 1000)
7190 {
7191 pto->PushMessage("getdata", vGetData);
7192 vGetData.clear();
7193 }
e2190f80
GM
7194 } else {
7195 //If we're not going to ask, don't expect a response.
7196 pto->setAskFor.erase(inv.hash);
0a61b0df 7197 }
7198 pto->mapAskFor.erase(pto->mapAskFor.begin());
7199 }
7200 if (!vGetData.empty())
7201 pto->PushMessage("getdata", vGetData);
8d655683 7202
0a61b0df 7203 }
7204 return true;
7205}
7206
8d655683 7207std::string CBlockFileInfo::ToString() const {
7208 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));
7209}
0a61b0df 7210
7211
7212
3427517d
PW
7213class CMainCleanup
7214{
7215public:
7216 CMainCleanup() {}
7217 ~CMainCleanup() {
7218 // block headers
145d5be8 7219 BlockMap::iterator it1 = mapBlockIndex.begin();
3427517d
PW
7220 for (; it1 != mapBlockIndex.end(); it1++)
7221 delete (*it1).second;
7222 mapBlockIndex.clear();
8d655683 7223
3427517d 7224 // orphan transactions
3427517d 7225 mapOrphanTransactions.clear();
c74332c6 7226 mapOrphanTransactionsByPrev.clear();
3427517d
PW
7227 }
7228} instance_of_cmaincleanup;
431cce98 7229
431cce98 7230extern "C" const char* getDataDir()
7231{
8d655683 7232 return GetDataDir().string().c_str();
431cce98 7233}
7234
072099d7
S
7235
7236// Set default values of new CMutableTransaction based on consensus rules at given height.
7237CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
7238{
7239 CMutableTransaction mtx;
8d655683 7240
072099d7
S
7241 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
7242 if (isOverwintered) {
7243 mtx.fOverwintered = true;
7244 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
7245 mtx.nVersion = 3;
7246 // Expiry height is not set. Only fields required for a parser to treat as a valid Overwinter V3 tx.
8d655683 7247
072099d7
S
7248 // TODO: In future, when moving from Overwinter to Sapling, it will be useful
7249 // to set the expiry height to: min(activation_height - 1, default_expiry_height)
7250 }
7251 return mtx;
7252}
This page took 2.943615 seconds and 4 git commands to generate.