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