]> Git Repo - VerusCoin.git/blame - src/main.cpp
Allow future block to not trigger severe rejection
[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 {
d6eb511b 1297 //static uint32_t counter;
9000990c 1298 // Disable replacement feature for now
1299 //if ( counter++ < 100 )
d6eb511b 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();
9f6cb8f0 2586 int32_t futureblock;
6fb8d0c2 2587 // Check it again to verify JoinSplit proofs, and in case a previous version let a bad block in
9f6cb8f0 2588 if (!CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, fExpensiveChecks ? verifier : disabledVerifier, fCheckPOW, !fJustCheck))
cdb2a22f 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 {
64b45b71 3553 if ( it->second != 0 ) // vNodes.size() >= KOMODO_LIMITED_NETWORKSIZE, change behavior to allow komodo_ensure to work
66dd02d2 3554 {
3555 // 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
3556 //fprintf(stderr,"addtoblockindex already there %p\n",it->second);
7732dbc2 3557 return it->second;
66dd02d2 3558 }
b8513092 3559 if ( miPrev != mapBlockIndex.end() && (*miPrev).second == 0 )
3560 {
e3e263b5 3561 //fprintf(stderr,"edge case of both block and prevblock in the strange state\n");
b8513092 3562 return(0); // return here to avoid the state of pindex->nHeight not set and pprev NULL
3563 }
fd835d94 3564 }
0a61b0df 3565 // Construct new block index object
1959997a 3566 CBlockIndex* pindexNew = new CBlockIndex(block);
94c8bfb2 3567 assert(pindexNew);
341735eb
PW
3568 // We assign the sequence id to blocks only when the full data is available,
3569 // to avoid miners withholding blocks but broadcasting headers, to get a
3570 // competitive advantage.
3571 pindexNew->nSequenceId = 0;
145d5be8 3572 BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
0a61b0df 3573 pindexNew->phashBlock = &((*mi).first);
0a61b0df 3574 if (miPrev != mapBlockIndex.end())
3575 {
b92dfb1e 3576 if ( (pindexNew->pprev= (*miPrev).second) != 0 )
3577 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
8dcf7f3f 3578 else fprintf(stderr,"unexpected null pprev %s\n",hash.ToString().c_str());
c9a09183 3579 pindexNew->BuildSkip();
0a61b0df 3580 }
092b58d1 3581 pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
942b33a1 3582 pindexNew->RaiseValidity(BLOCK_VALID_TREE);
341735eb
PW
3583 if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
3584 pindexBestHeader = pindexNew;
8d655683 3585
51ce901a 3586 setDirtyBlockIndex.insert(pindexNew);
66dd02d2 3587 //fprintf(stderr,"added to block index %s %p\n",hash.ToString().c_str(),pindexNew);
942b33a1
PW
3588 return pindexNew;
3589}
3590
c5b390b6 3591/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
942b33a1
PW
3592bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
3593{
3594 pindexNew->nTx = block.vtx.size();
341735eb 3595 pindexNew->nChainTx = 0;
ad6a36ad
JG
3596 CAmount sproutValue = 0;
3597 for (auto tx : block.vtx) {
3598 for (auto js : tx.vjoinsplit) {
3599 sproutValue += js.vpub_old;
3600 sproutValue -= js.vpub_new;
3601 }
3602 }
3603 pindexNew->nSproutValue = sproutValue;
3604 pindexNew->nChainSproutValue = boost::none;
857c61df
PW
3605 pindexNew->nFile = pos.nFile;
3606 pindexNew->nDataPos = pos.nPos;
5382bcf8 3607 pindexNew->nUndoPos = 0;
942b33a1 3608 pindexNew->nStatus |= BLOCK_HAVE_DATA;
341735eb 3609 pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
51ce901a 3610 setDirtyBlockIndex.insert(pindexNew);
8d655683 3611
341735eb
PW
3612 if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
3613 // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
3614 deque<CBlockIndex*> queue;
3615 queue.push_back(pindexNew);
8d655683 3616
341735eb
PW
3617 // Recursively process any descendant blocks that now may be eligible to be connected.
3618 while (!queue.empty()) {
3619 CBlockIndex *pindex = queue.front();
3620 queue.pop_front();
3621 pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
ad6a36ad
JG
3622 if (pindex->pprev) {
3623 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
3624 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
3625 } else {
3626 pindex->nChainSproutValue = boost::none;
3627 }
3628 } else {
3629 pindex->nChainSproutValue = pindex->nSproutValue;
3630 }
c1ecee8f
SD
3631 {
3632 LOCK(cs_nBlockSequenceId);
3633 pindex->nSequenceId = nBlockSequenceId++;
3634 }
3fcfbc8a
PW
3635 if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
3636 setBlockIndexCandidates.insert(pindex);
3637 }
341735eb
PW
3638 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
3639 while (range.first != range.second) {
3640 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3641 queue.push_back(it->second);
3642 range.first++;
3643 mapBlocksUnlinked.erase(it);
3644 }
341735eb
PW
3645 }
3646 } else {
3647 if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
3648 mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
3649 }
341735eb 3650 }
8d655683 3651
18e72167 3652 return true;
0a61b0df 3653}
3654
51ed9ec9 3655bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
5382bcf8 3656{
5382bcf8 3657 LOCK(cs_LastBlockFile);
8d655683 3658
ed6d1a2c
PW
3659 unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
3660 if (vinfoBlockFile.size() <= nFile) {
3661 vinfoBlockFile.resize(nFile + 1);
3662 }
8d655683 3663
ed6d1a2c
PW
3664 if (!fKnown) {
3665 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
ed6d1a2c
PW
3666 nFile++;
3667 if (vinfoBlockFile.size() <= nFile) {
3668 vinfoBlockFile.resize(nFile + 1);
3669 }
7fea4846 3670 }
ed6d1a2c
PW
3671 pos.nFile = nFile;
3672 pos.nPos = vinfoBlockFile[nFile].nSize;
5382bcf8 3673 }
8d655683 3674
4e895b08
PW
3675 if (nFile != nLastBlockFile) {
3676 if (!fKnown) {
3677 LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
3678 }
3679 FlushBlockFile(!fKnown);
3680 nLastBlockFile = nFile;
3681 }
8d655683 3682
ed6d1a2c 3683 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
bb6acff0
CF
3684 if (fKnown)
3685 vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3686 else
3687 vinfoBlockFile[nFile].nSize += nAddSize;
8d655683 3688
7fea4846
PW
3689 if (!fKnown) {
3690 unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
ed6d1a2c 3691 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
7fea4846 3692 if (nNewChunks > nOldChunks) {
f9ec3f0f 3693 if (fPruneMode)
3694 fCheckForPruning = true;
fa45c26a
PK
3695 if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
3696 FILE *file = OpenBlockFile(pos);
3697 if (file) {
881a85a2 3698 LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
fa45c26a
PK
3699 AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
3700 fclose(file);
3701 }
7fea4846 3702 }
fa45c26a 3703 else
c117d9e9 3704 return state.Error("out of disk space");
bba89aa8 3705 }
bba89aa8 3706 }
8d655683 3707
51ce901a 3708 setDirtyFileInfo.insert(nFile);
5382bcf8
PW
3709 return true;
3710}
3711
ef3988ca 3712bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
5382bcf8
PW
3713{
3714 pos.nFile = nFile;
8d655683 3715
5382bcf8 3716 LOCK(cs_LastBlockFile);
8d655683 3717
bba89aa8 3718 unsigned int nNewSize;
ed6d1a2c
PW
3719 pos.nPos = vinfoBlockFile[nFile].nUndoSize;
3720 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
51ce901a 3721 setDirtyFileInfo.insert(nFile);
8d655683 3722
bba89aa8
PW
3723 unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3724 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3725 if (nNewChunks > nOldChunks) {
f9ec3f0f 3726 if (fPruneMode)
3727 fCheckForPruning = true;
fa45c26a
PK
3728 if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
3729 FILE *file = OpenUndoFile(pos);
3730 if (file) {
881a85a2 3731 LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
fa45c26a
PK
3732 AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
3733 fclose(file);
3734 }
bba89aa8 3735 }
fa45c26a 3736 else
c117d9e9 3737 return state.Error("out of disk space");
5382bcf8 3738 }
8d655683 3739
5382bcf8
PW
3740 return true;
3741}
3742
9f6cb8f0 3743bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, const CBlockHeader& blockhdr, CValidationState& state, bool fCheckPOW)
0a61b0df 3744{
d7426190 3745 // Check timestamp
e40b78e9 3746 if ( 0 )
c0dbb034 3747 {
3748 uint256 hash; int32_t i;
3749 hash = blockhdr.GetHash();
92266e99 3750 for (i=31; i>=0; i--)
c0dbb034 3751 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
3752 fprintf(stderr," <- CheckBlockHeader\n");
807949f4 3753 if ( chainActive.Tip() != 0 )
3754 {
3755 hash = chainActive.Tip()->GetBlockHash();
3756 for (i=31; i>=0; i--)
3757 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
3758 fprintf(stderr," <- chainTip\n");
3759 }
c0dbb034 3760 }
9f6cb8f0 3761 *futureblockp = 0;
5dde7075 3762 if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60)
8999ab66 3763 {
82b4714b 3764 CBlockIndex *tipindex;
531b9293 3765 fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime());
d1cd2af5 3766 if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60*2 )
5d9f1119 3767 {
2fea1c97 3768 //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime());
5d9f1119 3769 while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 )
3770 sleep(1);
2fea1c97 3771 //fprintf(stderr,"now its valid\n");
5d9f1119 3772 }
3773 else
3774 {
9f6cb8f0 3775 if (blockhdr.GetBlockTime() < GetAdjustedTime() + 600)
3776 *futureblockp = 1;
5d9f1119 3777 return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new");
3778 }
8999ab66 3779 }
5d9f1119 3780 if ( ASSETCHAINS_STAKED != 0 && pindex != 0 && pindex->pprev != 0 && pindex->nTime <= pindex->pprev->nTime )
935fee29 3781 {
c38ad724 3782 fprintf(stderr,"ht.%d %u vs ht.%d %u, is not monotonic\n",pindex->nHeight,pindex->nTime,pindex->pprev->nHeight,pindex->pprev->nTime);
9339a0cb 3783 return state.Invalid(error("CheckBlockHeader(): block timestamp needs to always increase"),REJECT_INVALID, "time-too-new");
935fee29 3784 }
80f4cdcf 3785 // Check block version
5d173d2a 3786 if (height > 0 && blockhdr.nVersion < MIN_BLOCK_VERSION)
edddf5f0 3787 return state.DoS(100, error("CheckBlockHeader(): block version too low"),REJECT_INVALID, "version-too-low");
8d655683 3788
f2dd868d 3789 // Check Equihash solution is valid
dc4124de 3790 if ( fCheckPOW )
3791 {
3792 if ( !CheckEquihashSolution(&blockhdr, Params()) )
3793 return state.DoS(100, error("CheckBlockHeader(): Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
b8add6a4 3794 }
f2dd868d 3795 // Check proof of work matches claimed amount
ec06a2e3 3796 /*komodo_index2pubkey33(pubkey33,pindex,height);
3ad8d247 3797 if ( fCheckPOW && !CheckProofOfWork(height,pubkey33,blockhdr.GetHash(), blockhdr.nBits, Params().GetConsensus(),blockhdr.nTime) )
8d655683 3798 return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),REJECT_INVALID, "high-hash");*/
f4573470
PW
3799 return true;
3800}
3801
ce5dd547 3802int32_t komodo_check_deposit(int32_t height,const CBlock& block,uint32_t prevtime);
18443f69 3803int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height);
b8add6a4 3804
9f6cb8f0 3805bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const CBlock& block, CValidationState& state,
6fb8d0c2
JG
3806 libzcash::ProofVerifier& verifier,
3807 bool fCheckPOW, bool fCheckMerkleRoot)
0a61b0df 3808{
e5d9a702 3809 uint8_t pubkey33[33]; uint256 hash;
8d655683 3810 // These are checks that are independent of context.
18dd6a3b 3811 hash = block.GetHash();
18dd6a3b 3812
57425a24
DK
3813 // Check that the header is valid (particularly PoW). This is mostly
3814 // redundant with the call in AcceptBlockHeader.
9f6cb8f0 3815 if (!CheckBlockHeader(futureblockp,height,pindex,block,state,fCheckPOW))
3283cb53 3816 {
41427baa 3817 //fprintf(stderr,"checkblockheader error PoW.%d\n",fCheckPOW);
f4573470 3818 return false;
3283cb53 3819 }
18443f69 3820 if ( fCheckPOW )
3821 {
e5d9a702 3822 //if ( !CheckEquihashSolution(&block, Params()) )
18443f69 3823 // return state.DoS(100, error("CheckBlock: Equihash solution invalid"),REJECT_INVALID, "invalid-solution");
3824 komodo_block2pubkey33(pubkey33,(CBlock *)&block);
e5d9a702 3825 if ( !CheckProofOfWork(height,pubkey33,hash,block.nBits,Params().GetConsensus(),block.nTime) )
d3358987 3826 {
560da193 3827 int32_t z; for (z=31; z>=0; z--)
e5d9a702 3828 fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
80afe35b 3829 fprintf(stderr," failed hash ht.%d\n",height);
8fbee929 3830 return state.DoS(50, error("CheckBlock: proof of work failed"),REJECT_INVALID, "high-hash");
d3358987 3831 }
3acce042 3832 if ( komodo_checkPOW(1,(CBlock *)&block,height) < 0 ) // checks Equihash
18443f69 3833 return state.DoS(100, error("CheckBlock: failed slow_checkPOW"),REJECT_INVALID, "failed-slow_checkPOW");
3834 }
341735eb
PW
3835 // Check the merkle root.
3836 if (fCheckMerkleRoot) {
3837 bool mutated;
3838 uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
3839 if (block.hashMerkleRoot != hashMerkleRoot2)
b8add6a4 3840 return state.DoS(100, error("CheckBlock: hashMerkleRoot mismatch"),
341735eb 3841 REJECT_INVALID, "bad-txnmrklroot", true);
8d655683 3842
341735eb
PW
3843 // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
3844 // of transactions in a block without affecting the merkle root of a block,
3845 // while still invalidating it.
3846 if (mutated)
b8add6a4 3847 return state.DoS(100, error("CheckBlock: duplicate transaction"),
341735eb
PW
3848 REJECT_INVALID, "bad-txns-duplicate", true);
3849 }
8d655683 3850
341735eb
PW
3851 // All potential-corruption validation must be done before we do any
3852 // transaction validation, as otherwise we may mark the header as invalid
3853 // because we receive the wrong transactions for it.
8d655683 3854
0a61b0df 3855 // Size limits
38991ffa 3856 if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
b8add6a4 3857 return state.DoS(100, error("CheckBlock: size limits failed"),
14e7ffcc 3858 REJECT_INVALID, "bad-blk-length");
8d655683 3859
0a61b0df 3860 // First transaction must be coinbase, the rest must not be
38991ffa 3861 if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
b8add6a4 3862 return state.DoS(100, error("CheckBlock: first tx is not coinbase"),
14e7ffcc 3863 REJECT_INVALID, "bad-cb-missing");
38991ffa
EL
3864 for (unsigned int i = 1; i < block.vtx.size(); i++)
3865 if (block.vtx[i].IsCoinBase())
b8add6a4 3866 return state.DoS(100, error("CheckBlock: more than one coinbase"),
14e7ffcc 3867 REJECT_INVALID, "bad-cb-multiple");
8d655683 3868
0a61b0df 3869 // Check transactions
38991ffa 3870 BOOST_FOREACH(const CTransaction& tx, block.vtx)
837b94ee 3871 {
f8a07170 3872 if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,0) < 0 )
8d655683 3873 return error("CheckBlock: komodo_validate_interest failed");
6fb8d0c2 3874 if (!CheckTransaction(tx, state, verifier))
b8add6a4 3875 return error("CheckBlock: CheckTransaction failed");
837b94ee 3876 }
7bd9c3a3 3877 unsigned int nSigOps = 0;
38991ffa 3878 BOOST_FOREACH(const CTransaction& tx, block.vtx)
e679ec96 3879 {
05df3fc6 3880 nSigOps += GetLegacySigOpCount(tx);
e679ec96
GA
3881 }
3882 if (nSigOps > MAX_BLOCK_SIGOPS)
b8add6a4 3883 return state.DoS(100, error("CheckBlock: out-of-bounds SigOpCount"),
14e7ffcc 3884 REJECT_INVALID, "bad-blk-sigops", true);
b1e74295 3885 if ( komodo_check_deposit(height,block,(pindex==0||pindex->pprev==0)?0:pindex->pprev->nTime) < 0 )
e699e13d 3886 {
1a26c3fa 3887 //static uint32_t counter;
3888 //if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
41427baa 3889 // fprintf(stderr,"check deposit rejection\n");
59642d51 3890 return(false);
e699e13d 3891 }
0a61b0df 3892 return true;
3893}
3894
a48f2d6d
LD
3895bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
3896{
11982d36
CF
3897 const CChainParams& chainParams = Params();
3898 const Consensus::Params& consensusParams = chainParams.GetConsensus();
a48f2d6d 3899 uint256 hash = block.GetHash();
4e382177 3900 if (hash == consensusParams.hashGenesisBlock)
a48f2d6d 3901 return true;
8d655683 3902
a48f2d6d 3903 assert(pindexPrev);
8d655683 3904
a48f2d6d 3905 int nHeight = pindexPrev->nHeight+1;
8d655683 3906
a48f2d6d 3907 // Check proof of work
36f1b84b 3908 if ( (nHeight < 235300 || nHeight > 236000) && block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
5645d111 3909 {
c939721c 3910 cout << block.nBits << " block.nBits vs. calc " << GetNextWorkRequired(pindexPrev, &block, consensusParams) << endl;
5262fde0 3911 return state.DoS(100, error("%s: incorrect proof of work", __func__),
a48f2d6d 3912 REJECT_INVALID, "bad-diffbits");
5645d111 3913 }
8d655683 3914
a48f2d6d
LD
3915 // Check timestamp against prev
3916 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
5262fde0 3917 return state.Invalid(error("%s: block's timestamp is too early", __func__),
a48f2d6d 3918 REJECT_INVALID, "time-too-old");
8d655683 3919
bfa832c7 3920 if (fCheckpointsEnabled)
a8cdaf5c
CF
3921 {
3922 // Check that the block chain matches the known block chain up to a checkpoint
3923 if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
8d787d25 3924 {
49601901 3925 /*CBlockIndex *heightblock = chainActive[nHeight];
8d787d25 3926 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
3927 {
3928 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
3929 return true;
49601901 3930 }*/
3931 return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),REJECT_CHECKPOINT, "checkpoint mismatch");
8d787d25 3932 }
a8cdaf5c
CF
3933 // Don't accept any forks from the main chain prior to last checkpoint
3934 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
b62d7030 3935 int32_t notarized_height;
4786d20c 3936 if (pcheckpoint && nHeight > 1 && nHeight < pcheckpoint->nHeight )
176eeb77 3937 return state.DoS(1, error("%s: forked chain older than last checkpoint (height %d) vs %d", __func__, nHeight,pcheckpoint->nHeight));
b62d7030 3938 else if ( komodo_checkpoint(&notarized_height,nHeight,hash) < 0 )
e2c2f297 3939 {
3940 CBlockIndex *heightblock = chainActive[nHeight];
cc07ad72 3941 if ( heightblock != 0 && heightblock->GetBlockHash() == hash )
e2c2f297 3942 {
2c5af2cd 3943 //fprintf(stderr,"got a pre notarization block that matches height.%d\n",(int32_t)nHeight);
e2c2f297 3944 return true;
176eeb77 3945 } else return state.DoS(1, error("%s: forked chain %d older than last notarized (height %d) vs %d", __func__,nHeight, notarized_height));
e2c2f297 3946 }
a8cdaf5c 3947 }
542da618
SB
3948 // Reject block.nVersion < 4 blocks
3949 if (block.nVersion < 4)
3950 return state.Invalid(error("%s : rejected nVersion<4 block", __func__),
5e82e1c8 3951 REJECT_OBSOLETE, "bad-version");
8d655683 3952
a48f2d6d
LD
3953 return true;
3954}
3955
3956bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
3957{
3958 const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
51aa2492 3959 const Consensus::Params& consensusParams = Params().GetConsensus();
8d655683 3960
a48f2d6d 3961 // Check that all transactions are finalized
a1d3c6fb 3962 BOOST_FOREACH(const CTransaction& tx, block.vtx) {
8d655683 3963
072099d7
S
3964 // Check transaction contextually against consensus rules at block height
3965 if (!ContextualCheckTransaction(tx, state, nHeight, 100)) {
3966 return false; // Failure reason has been set in validation state object
3967 }
8d655683 3968
a1d3c6fb
MF
3969 int nLockTimeFlags = 0;
3970 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
8d655683 3971 ? pindexPrev->GetMedianTimePast()
3972 : block.GetBlockTime();
14aa6cc0 3973 if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) {
5262fde0 3974 return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
a48f2d6d 3975 }
a1d3c6fb 3976 }
8d655683 3977
c2a722d3
DH
3978 // Enforce BIP 34 rule that the coinbase starts with serialized block height.
3979 // In Zcash this has been enforced since launch, except that the genesis
3980 // block didn't include the height in the coinbase (see Zcash protocol spec
3981 // section '6.8 Bitcoin Improvement Proposals').
548bbd95 3982 if (nHeight > 0)
a48f2d6d
LD
3983 {
3984 CScript expect = CScript() << nHeight;
3985 if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
3986 !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
16cd9f2d 3987 return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
a48f2d6d
LD
3988 }
3989 }
8d655683 3990
a48f2d6d
LD
3991 return true;
3992}
3993
8d725ab4 3994//static uint256 komodo_requestedhash;
3995//static int32_t komodo_requestedcount;
161f617d 3996
531b9293 3997bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
0a61b0df 3998{
161f617d 3999 static uint256 zero;
4e382177 4000 const CChainParams& chainparams = Params();
e07c943c 4001 AssertLockHeld(cs_main);
531b9293 4002
0a61b0df 4003 // Check for duplicate
2a4d3464 4004 uint256 hash = block.GetHash();
145d5be8 4005 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
6d3df1e6 4006 CBlockIndex *pindex = NULL;
5215d24e 4007 if (miSelf != mapBlockIndex.end())
4008 {
341735eb 4009 // Block header is already known.
942b33a1 4010 pindex = miSelf->second;
341735eb
PW
4011 if (ppindex)
4012 *ppindex = pindex;
6477ad07 4013 if ( pindex != 0 && pindex->nStatus & BLOCK_FAILED_MASK )
dc4124de 4014 return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
8d725ab4 4015 /*if ( pindex != 0 && hash == komodo_requestedhash )
b80fef6f 4016 {
4017 fprintf(stderr,"AddToBlockIndex A komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4018 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
bddeaf5e 4019 komodo_requestedcount = 0;
8d725ab4 4020 }*/
b92dfb1e 4021 //if ( pindex == 0 )
4022 // fprintf(stderr,"accepthdr %s already known but no pindex\n",hash.ToString().c_str());
dc4124de 4023 return true;
942b33a1 4024 }
531b9293 4025 if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->nHeight:0,*ppindex, block, state,0))
44c0859f 4026 {
2fea1c97 4027 //fprintf(stderr,"AcceptBlockHeader: CheckBlockHeader failed\n");
5f197aee 4028 return false;
44c0859f 4029 }
0a61b0df 4030 // Get prev block index
7fea4846 4031 CBlockIndex* pindexPrev = NULL;
e6c99a7a 4032 if (hash != chainparams.GetConsensus().hashGenesisBlock)
4033 {
145d5be8 4034 BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
b56585d0 4035 if (mi == mapBlockIndex.end())
beb911ec 4036 {
e5301556 4037 //fprintf(stderr,"AcceptBlockHeader hashPrevBlock %s not found\n",block.hashPrevBlock.ToString().c_str());
8d725ab4 4038 /*if ( komodo_requestedhash == zero )
bddeaf5e 4039 {
161f617d 4040 komodo_requestedhash = block.hashPrevBlock;
bddeaf5e 4041 komodo_requestedcount = 0;
8d725ab4 4042 }*/
f3071571 4043 return(false);
4044 //return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
beb911ec 4045 }
b56585d0 4046 pindexPrev = (*mi).second;
e6c99a7a 4047 if (pindexPrev == 0 )
f65a34b9 4048 {
531b9293 4049 /*fprintf(stderr,"AcceptBlockHeader failed no pindexPrev %s\n",block.hashPrevBlock.ToString().c_str());
4050 if ( komodo_requestedhash == zero )
f65a34b9 4051 {
4052 komodo_requestedhash = block.hashPrevBlock;
4053 komodo_requestedcount = 0;
8d725ab4 4054 }*/
e6c99a7a 4055 return(false);
f65a34b9 4056 }
e6c99a7a 4057 if ( (pindexPrev->nStatus & BLOCK_FAILED_MASK) )
5262fde0 4058 return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
942b33a1 4059 }
a48f2d6d 4060 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
44c0859f 4061 {
2fea1c97 4062 //fprintf(stderr,"AcceptBlockHeader ContextualCheckBlockHeader failed\n");
a48f2d6d 4063 return false;
44c0859f 4064 }
942b33a1 4065 if (pindex == NULL)
7466a330 4066 {
4067 if ( (pindex= AddToBlockIndex(block)) == 0 )
f7ce3004 4068 {
f65a34b9 4069 fprintf(stderr,"AcceptBlockHeader couldnt add to block index\n");
f7ce3004 4070 }
7466a330 4071 }
942b33a1
PW
4072 if (ppindex)
4073 *ppindex = pindex;
8d725ab4 4074 /*if ( pindex != 0 && hash == komodo_requestedhash )
161f617d 4075 {
4076 fprintf(stderr,"AddToBlockIndex komodo_requestedhash %s\n",komodo_requestedhash.ToString().c_str());
4077 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
bddeaf5e 4078 komodo_requestedcount = 0;
8d725ab4 4079 }*/
942b33a1
PW
4080 return true;
4081}
4082
531b9293 4083bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
942b33a1 4084{
e6973430 4085 const CChainParams& chainparams = Params();
942b33a1 4086 AssertLockHeld(cs_main);
8d655683 4087
942b33a1 4088 CBlockIndex *&pindex = *ppindex;
531b9293 4089 if (!AcceptBlockHeader(futureblockp,block, state, &pindex))
bd8997bf 4090 {
b92dfb1e 4091 //fprintf(stderr,"AcceptBlockHeader rejected\n");
942b33a1 4092 return false;
bd8997bf 4093 }
1e9dc6a8 4094 if ( pindex == 0 )
4095 {
e3e263b5 4096 //fprintf(stderr,"AcceptBlock error null pindex\n");
1e9dc6a8 4097 return false;
4098 }
da4020cb 4099 //fprintf(stderr,"acceptblockheader passed\n");
304892fc
SD
4100 // Try to process all requested blocks that we don't have, but only
4101 // process an unrequested block if it's new and has enough work to
93b606ae 4102 // advance our tip, and isn't too many blocks ahead.
304892fc
SD
4103 bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
4104 bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
93b606ae
SD
4105 // Blocks that are too out-of-order needlessly limit the effectiveness of
4106 // pruning, because pruning will not delete block files that contain any
4107 // blocks which are too close in height to the tip. Apply this test
4108 // regardless of whether pruning is enabled; it should generally be safe to
4109 // not process unrequested blocks.
71f2c696 4110 bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
8d655683 4111
304892fc
SD
4112 // TODO: deal better with return value and error conditions for duplicate
4113 // and unrequested blocks.
b92dfb1e 4114 //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
4115 if (fAlreadyHave) return true;
4116 if (!fRequested) { // If we didn't ask for it:
4117 if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
4118 if (!fHasMoreWork) return true; // Don't process less-work chains
93b606ae 4119 if (fTooFarAhead) return true; // Block height is too high
341735eb 4120 }
8d655683 4121
6fb8d0c2
JG
4122 // See method docstring for why this is always disabled
4123 auto verifier = libzcash::ProofVerifier::Disabled();
531b9293 4124 if ((!CheckBlock(futureblockp,pindex->nHeight,pindex,block, state, verifier,0)) || !ContextualCheckBlock(block, state, pindex->pprev))
07359935 4125 {
9f6cb8f0 4126 if (futureblock == 0 && state.IsInvalid() && !state.CorruptionPossible()) {
942b33a1 4127 pindex->nStatus |= BLOCK_FAILED_VALID;
51ce901a 4128 setDirtyBlockIndex.insert(pindex);
942b33a1 4129 }
b92dfb1e 4130 //fprintf(stderr,"CheckBlock or ContextualCheckBlock failed\n");
942b33a1
PW
4131 return false;
4132 }
8d655683 4133
942b33a1 4134 int nHeight = pindex->nHeight;
8d655683 4135
0a61b0df 4136 // Write block to history file
421218d3 4137 try {
2a4d3464 4138 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
421218d3
PW
4139 CDiskBlockPos blockPos;
4140 if (dbp != NULL)
4141 blockPos = *dbp;
209377a7 4142 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
5262fde0 4143 return error("AcceptBlock(): FindBlockPos failed");
421218d3 4144 if (dbp == NULL)
e6973430 4145 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
27afcd89 4146 AbortNode(state, "Failed to write block");
942b33a1 4147 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5262fde0 4148 return error("AcceptBlock(): ReceivedBlockTransactions failed");
27df4123 4149 } catch (const std::runtime_error& e) {
27afcd89 4150 return AbortNode(state, std::string("System error: ") + e.what());
421218d3 4151 }
8d655683 4152
f9ec3f0f 4153 if (fCheckForPruning)
4154 FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
8d655683 4155
0a61b0df 4156 return true;
4157}
4158
51aa2492 4159static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
de237cbf
GA
4160{
4161 unsigned int nFound = 0;
51aa2492 4162 for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
de237cbf
GA
4163 {
4164 if (pstart->nVersion >= minVersion)
4165 ++nFound;
4166 pstart = pstart->pprev;
4167 }
4168 return (nFound >= nRequired);
4169}
4170
c75c18fc 4171void komodo_currentheight_set(int32_t height);
c9a09183 4172
b5d0fe2e 4173CBlockIndex *komodo_ensure(CBlock *pblock,uint256 hash)
4174{
4175 CBlockIndex *pindex;
4176 BlockMap::iterator miSelf = mapBlockIndex.find(hash);
4177 if ( miSelf != mapBlockIndex.end() )
4178 {
4179 if ( (pindex= miSelf->second) == 0 ) // create pindex so first Accept block doesnt fail
4180 {
519578c9 4181 miSelf->second = AddToBlockIndex(*pblock);
b0bf5d02 4182 //fprintf(stderr,"Block header %s is already known, but without pindex -> ensured %p\n",hash.ToString().c_str(),miSelf->second);
b5d0fe2e 4183 }
882c4cfe 4184 /*if ( hash != chainparams.GetConsensus().hashGenesisBlock )
f8a07170 4185 {
4186 miSelf = mapBlockIndex.find(pblock->hashPrevBlock);
4187 if ( miSelf == mapBlockIndex.end() )
4188 {
4189 miSelf->second = InsertBlockIndex(pblock->hashPrevBlock);
4190 fprintf(stderr,"autocreate previndex %s\n",pblock->hashPrevBlock.ToString().c_str());
4191 }
882c4cfe 4192 }*/
b5d0fe2e 4193 }
4194}
4195
7bb789bb 4196bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
0a61b0df 4197{
0a61b0df 4198 // Preliminary checks
531b9293 4199 bool checked; uint256 hash; int32_t futureblock=0;
6fb8d0c2 4200 auto verifier = libzcash::ProofVerifier::Disabled();
bc2bcf85 4201 hash = pblock->GetHash();
bddeaf5e 4202//fprintf(stderr,"process newblock %s\n",hash.ToString().c_str());
6ae728c7 4203 if ( chainActive.Tip() != 0 )
c75c18fc 4204 komodo_currentheight_set(chainActive.Tip()->nHeight);
9f6cb8f0 4205 checked = CheckBlock(&futureblock,height!=0?height:komodo_block2height(pblock),0,*pblock, state, verifier,0);
0a61b0df 4206 {
341735eb 4207 LOCK(cs_main);
bc2bcf85 4208 bool fRequested = MarkBlockAsReceived(hash);
304892fc 4209 fRequested |= fForceProcessing;
bd87f0c0 4210 if ( checked != 0 && komodo_checkPOW(from_miner && ASSETCHAINS_STAKED == 0,pblock,height) < 0 )
13b8b2ed 4211 {
b8add6a4 4212 checked = 0;
ebb59e60 4213 fprintf(stderr,"passed checkblock but failed checkPOW.%d\n",from_miner && ASSETCHAINS_STAKED == 0);
13b8b2ed 4214 }
9f6cb8f0 4215 if (!checked && futureblock == 0)
c7a1d234 4216 {
50c490cb 4217 if ( pfrom != 0 )
c7a1d234 4218 {
04a1f0bb 4219 Misbehaving(pfrom->GetId(), 1);
c7a1d234 4220 }
872cf91b 4221 return error("%s: CheckBlock FAILED", __func__);
5c88e3c1 4222 }
341735eb
PW
4223 // Store to disk
4224 CBlockIndex *pindex = NULL;
17522a55 4225 {
66dd02d2 4226 // 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 4227 komodo_ensure(pblock,hash);
0f102ea7 4228 }
531b9293 4229 bool ret = AcceptBlock(&futureblock,*pblock, state, &pindex, fRequested, dbp);
341735eb
PW
4230 if (pindex && pfrom) {
4231 mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
0a61b0df 4232 }
3fcfbc8a 4233 CheckBlockIndex();
531b9293 4234 if (!ret && futureblock == 0)
5262fde0 4235 return error("%s: AcceptBlock FAILED", __func__);
bddeaf5e 4236 //else fprintf(stderr,"added block %s %p\n",pindex->GetBlockHash().ToString().c_str(),pindex->pprev);
18e72167 4237 }
8d655683 4238
531b9293 4239 if (futureblock == 0 && !ActivateBestChain(state, pblock))
5262fde0 4240 return error("%s: ActivateBestChain failed", __func__);
8d655683 4241
0a61b0df 4242 return true;
4243}
4244
df08a626
LD
4245bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
4246{
4247 AssertLockHeld(cs_main);
4248 assert(pindexPrev == chainActive.Tip());
8d655683 4249
df08a626
LD
4250 CCoinsViewCache viewNew(pcoinsTip);
4251 CBlockIndex indexDummy(block);
4252 indexDummy.pprev = pindexPrev;
4253 indexDummy.nHeight = pindexPrev->nHeight + 1;
6fb8d0c2
JG
4254 // JoinSplit proofs are verified in ConnectBlock
4255 auto verifier = libzcash::ProofVerifier::Disabled();
df08a626
LD
4256 // NOTE: CheckBlockHeader is called by CheckBlock
4257 if (!ContextualCheckBlockHeader(block, state, pindexPrev))
d4190a2a 4258 {
b92dfb1e 4259 //fprintf(stderr,"TestBlockValidity failure A checkPOW.%d\n",fCheckPOW);
df08a626 4260 return false;
d4190a2a 4261 }
9f6cb8f0 4262 int32_t futureblock;
4263 if (!CheckBlock(&futureblock,indexDummy.nHeight,0,block, state, verifier, fCheckPOW, fCheckMerkleRoot))
d4190a2a 4264 {
b92dfb1e 4265 //fprintf(stderr,"TestBlockValidity failure B checkPOW.%d\n",fCheckPOW);
df08a626 4266 return false;
d4190a2a 4267 }
df08a626 4268 if (!ContextualCheckBlock(block, state, pindexPrev))
d4190a2a 4269 {
b92dfb1e 4270 //fprintf(stderr,"TestBlockValidity failure C checkPOW.%d\n",fCheckPOW);
df08a626 4271 return false;
d4190a2a 4272 }
455ba304 4273 if (!ConnectBlock(block, state, &indexDummy, viewNew, true,fCheckPOW))
d4190a2a 4274 {
b92dfb1e 4275 //fprintf(stderr,"TestBlockValidity failure D checkPOW.%d\n",fCheckPOW);
df08a626 4276 return false;
d4190a2a 4277 }
df08a626 4278 assert(state.IsValid());
8d655683 4279
df08a626
LD
4280 return true;
4281}
4282
f9ec3f0f 4283/**
4284 * BLOCK PRUNING CODE
4285 */
4286
4287/* Calculate the amount of disk space the block & undo files currently use */
4288uint64_t CalculateCurrentUsage()
4289{
4290 uint64_t retval = 0;
4291 BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
4292 retval += file.nSize + file.nUndoSize;
4293 }
4294 return retval;
4295}
4296
4297/* Prune a block file (modify associated database entries)*/
4298void PruneOneBlockFile(const int fileNumber)
4299{
4300 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
4301 CBlockIndex* pindex = it->second;
4302 if (pindex->nFile == fileNumber) {
4303 pindex->nStatus &= ~BLOCK_HAVE_DATA;
4304 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
4305 pindex->nFile = 0;
4306 pindex->nDataPos = 0;
4307 pindex->nUndoPos = 0;
4308 setDirtyBlockIndex.insert(pindex);
8d655683 4309
f9ec3f0f 4310 // Prune from mapBlocksUnlinked -- any block we prune would have
4311 // to be downloaded again in order to consider its chain, at which
4312 // point it would be considered as a candidate for
4313 // mapBlocksUnlinked or setBlockIndexCandidates.
4314 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
4315 while (range.first != range.second) {
4316 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
4317 range.first++;
4318 if (it->second == pindex) {
4319 mapBlocksUnlinked.erase(it);
4320 }
4321 }
4322 }
4323 }
8d655683 4324
f9ec3f0f 4325 vinfoBlockFile[fileNumber].SetNull();
4326 setDirtyFileInfo.insert(fileNumber);
4327}
4328
4329
4330void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
4331{
4332 for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
4333 CDiskBlockPos pos(*it, 0);
4334 boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
4335 boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
4336 LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
4337 }
4338}
4339
4340/* Calculate the block/rev files that should be deleted to remain under target*/
4341void FindFilesToPrune(std::set<int>& setFilesToPrune)
4342{
4343 LOCK2(cs_main, cs_LastBlockFile);
4344 if (chainActive.Tip() == NULL || nPruneTarget == 0) {
4345 return;
4346 }
4347 if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
4348 return;
4349 }
b89f3077 4350 unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
f9ec3f0f 4351 uint64_t nCurrentUsage = CalculateCurrentUsage();
4352 // We don't check to prune until after we've allocated new space for files
4353 // So we should leave a buffer under our target to account for another allocation
4354 // before the next pruning.
4355 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
4356 uint64_t nBytesToPrune;
4357 int count=0;
8d655683 4358
f9ec3f0f 4359 if (nCurrentUsage + nBuffer >= nPruneTarget) {
4360 for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4361 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
8d655683 4362
f9ec3f0f 4363 if (vinfoBlockFile[fileNumber].nSize == 0)
4364 continue;
8d655683 4365
f9ec3f0f 4366 if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
4367 break;
8d655683 4368
6cb70ca4 4369 // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
b89f3077 4370 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
6cb70ca4 4371 continue;
8d655683 4372
f9ec3f0f 4373 PruneOneBlockFile(fileNumber);
4374 // Queue up the files for removal
4375 setFilesToPrune.insert(fileNumber);
4376 nCurrentUsage -= nBytesToPrune;
4377 count++;
4378 }
4379 }
8d655683 4380
b89f3077 4381 LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
8d655683 4382 nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
4383 ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4384 nLastBlockWeCanPrune, count);
f9ec3f0f 4385}
4386
51ed9ec9 4387bool CheckDiskSpace(uint64_t nAdditionalBytes)
0a61b0df 4388{
a3241998 4389 uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
8d655683 4390
966ae00f
PK
4391 // Check for nMinDiskSpace bytes (currently 50MB)
4392 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
b9b2e3fa 4393 return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
8d655683 4394
0a61b0df 4395 return true;
4396}
4397
5382bcf8 4398FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
42613c97 4399{
cf53fd7c 4400 static int32_t didinit[64];
450cbb09 4401 if (pos.IsNull())
0a61b0df 4402 return NULL;
ec7eb0fa 4403 boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
5382bcf8
PW
4404 boost::filesystem::create_directories(path.parent_path());
4405 FILE* file = fopen(path.string().c_str(), "rb+");
4406 if (!file && !fReadOnly)
4407 file = fopen(path.string().c_str(), "wb+");
450cbb09 4408 if (!file) {
7d9d134b 4409 LogPrintf("Unable to open file %s\n", path.string());
0a61b0df 4410 return NULL;
450cbb09 4411 }
1a608050 4412 if ( pos.nFile < sizeof(didinit)/sizeof(*didinit) && didinit[pos.nFile] == 0 && strcmp(prefix,(char *)"blk") == 0 )
f527fcdb 4413 {
cf53fd7c 4414 komodo_prefetch(file);
1a608050 4415 didinit[pos.nFile] = 1;
f527fcdb 4416 }
5382bcf8
PW
4417 if (pos.nPos) {
4418 if (fseek(file, pos.nPos, SEEK_SET)) {
7d9d134b 4419 LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
5382bcf8
PW
4420 fclose(file);
4421 return NULL;
4422 }
4423 }
0a61b0df 4424 return file;
4425}
4426
5382bcf8
PW
4427FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
4428 return OpenDiskFile(pos, "blk", fReadOnly);
4429}
4430
69e07747 4431FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
5382bcf8
PW
4432 return OpenDiskFile(pos, "rev", fReadOnly);
4433}
4434
ec7eb0fa
SD
4435boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
4436{
f7e36370 4437 return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
ec7eb0fa
SD
4438}
4439
2d8a4829
PW
4440CBlockIndex * InsertBlockIndex(uint256 hash)
4441{
4f152496 4442 if (hash.IsNull())
2d8a4829 4443 return NULL;
8d655683 4444
2d8a4829 4445 // Return existing
145d5be8 4446 BlockMap::iterator mi = mapBlockIndex.find(hash);
2d8a4829
PW
4447 if (mi != mapBlockIndex.end())
4448 return (*mi).second;
8d655683 4449
2d8a4829
PW
4450 // Create new
4451 CBlockIndex* pindexNew = new CBlockIndex();
4452 if (!pindexNew)
5262fde0 4453 throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
2d8a4829
PW
4454 mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
4455 pindexNew->phashBlock = &((*mi).first);
66dd02d2 4456 //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str());
e1407365 4457
2d8a4829
PW
4458 return pindexNew;
4459}
4460
102cc989 4461//void komodo_pindex_init(CBlockIndex *pindex,int32_t height);
141950a4 4462
2d8a4829
PW
4463bool static LoadBlockIndexDB()
4464{
11982d36 4465 const CChainParams& chainparams = Params();
6a0c9826 4466 LogPrintf("%s: start loading guts\n", __func__);
2d8a4829
PW
4467 if (!pblocktree->LoadBlockIndexGuts())
4468 return false;
6a0c9826 4469 LogPrintf("%s: loaded guts\n", __func__);
b31499ec 4470 boost::this_thread::interruption_point();
8d655683 4471
1657c4bc 4472 // Calculate nChainWork
2d8a4829
PW
4473 vector<pair<int, CBlockIndex*> > vSortedByHeight;
4474 vSortedByHeight.reserve(mapBlockIndex.size());
4475 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4476 {
4477 CBlockIndex* pindex = item.second;
4478 vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
102cc989 4479 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
2d8a4829 4480 }
e1a6427c 4481 //fprintf(stderr,"load blockindexDB paired %u\n",(uint32_t)time(NULL));
2d8a4829 4482 sort(vSortedByHeight.begin(), vSortedByHeight.end());
e1a6427c 4483 //fprintf(stderr,"load blockindexDB sorted %u\n",(uint32_t)time(NULL));
2d8a4829
PW
4484 BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
4485 {
4486 CBlockIndex* pindex = item.second;
092b58d1 4487 pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
f9ec3f0f 4488 // We can link the chain of blocks for which we've received transactions at some point.
4489 // Pruned nodes may have deleted the block.
4490 if (pindex->nTx > 0) {
341735eb
PW
4491 if (pindex->pprev) {
4492 if (pindex->pprev->nChainTx) {
4493 pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
ad6a36ad
JG
4494 if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
4495 pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
4496 } else {
4497 pindex->nChainSproutValue = boost::none;
4498 }
341735eb
PW
4499 } else {
4500 pindex->nChainTx = 0;
ad6a36ad 4501 pindex->nChainSproutValue = boost::none;
341735eb
PW
4502 mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
4503 }
4504 } else {
4505 pindex->nChainTx = pindex->nTx;
ad6a36ad 4506 pindex->nChainSproutValue = pindex->nSproutValue;
341735eb
PW
4507 }
4508 }
9e851450
JG
4509 // Construct in-memory chain of branch IDs.
4510 // Relies on invariant: a block that does not activate a network upgrade
4511 // will always be valid under the same consensus rules as its parent.
828940b1
JG
4512 // Genesis block has a branch ID of zero by definition, but has no
4513 // validity status because it is side-loaded into a fresh chain.
4514 // Activation blocks will have branch IDs set (read from disk).
4515 if (pindex->pprev) {
4516 if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) {
4517 pindex->nCachedBranchId = pindex->pprev->nCachedBranchId;
4518 }
4519 } else {
be126699 4520 pindex->nCachedBranchId = SPROUT_BRANCH_ID;
9e851450 4521 }
341735eb 4522 if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
e17bd583 4523 setBlockIndexCandidates.insert(pindex);
85eb2cef
PW
4524 if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
4525 pindexBestInvalid = pindex;
c9a09183
PW
4526 if (pindex->pprev)
4527 pindex->BuildSkip();
341735eb
PW
4528 if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
4529 pindexBestHeader = pindex;
102cc989 4530 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
2d8a4829 4531 }
e1a6427c 4532 //fprintf(stderr,"load blockindexDB chained %u\n",(uint32_t)time(NULL));
d00db115 4533
2d8a4829
PW
4534 // Load block file info
4535 pblocktree->ReadLastBlockFile(nLastBlockFile);
ed6d1a2c 4536 vinfoBlockFile.resize(nLastBlockFile + 1);
7b2bb962 4537 LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
ed6d1a2c
PW
4538 for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4539 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4540 }
7b2bb962 4541 LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
ed6d1a2c
PW
4542 for (int nFile = nLastBlockFile + 1; true; nFile++) {
4543 CBlockFileInfo info;
4544 if (pblocktree->ReadBlockFileInfo(nFile, info)) {
4545 vinfoBlockFile.push_back(info);
4546 } else {
4547 break;
4548 }
4549 }
8d655683 4550
8c93bf4c
AH
4551 // Check presence of blk files
4552 LogPrintf("Checking all blk files are present...\n");
4553 set<int> setBlkDataFiles;
4554 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4555 {
4556 CBlockIndex* pindex = item.second;
4557 if (pindex->nStatus & BLOCK_HAVE_DATA) {
4558 setBlkDataFiles.insert(pindex->nFile);
4559 }
102cc989 4560 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
8c93bf4c 4561 }
e1a6427c 4562 //fprintf(stderr,"load blockindexDB %u\n",(uint32_t)time(NULL));
8c93bf4c
AH
4563 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
4564 {
4565 CDiskBlockPos pos(*it, 0);
a8738238 4566 if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
8c93bf4c
AH
4567 return false;
4568 }
4569 }
8d655683 4570
f9ec3f0f 4571 // Check whether we have ever pruned block & undo files
4572 pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
4573 if (fHavePruned)
4574 LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
8d655683 4575
89b7019b
PW
4576 // Check whether we need to continue reindexing
4577 bool fReindexing = false;
4578 pblocktree->ReadReindexing(fReindexing);
4579 fReindex |= fReindexing;
8d655683 4580
2d1fa42e
PW
4581 // Check whether we have a transaction index
4582 pblocktree->ReadFlag("txindex", fTxIndex);
52070c87 4583 LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
8b78a819
T
4584 // Check whether we have an address index
4585 pblocktree->ReadFlag("addressindex", fAddressIndex);
4586 LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
4587
4588 // Check whether we have a timestamp index
4589 pblocktree->ReadFlag("timestampindex", fTimestampIndex);
4590 LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
4591
4592 // Check whether we have a spent index
4593 pblocktree->ReadFlag("spentindex", fSpentIndex);
4594 LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
4595
0bc1e2c4
JG
4596 // Fill in-memory data
4597 BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
4598 {
4599 CBlockIndex* pindex = item.second;
4600 // - This relationship will always be true even if pprev has multiple
4601 // children, because hashAnchor is technically a property of pprev,
4602 // not its children.
4603 // - This will miss chain tips; we handle the best tip below, and other
4604 // tips will be handled by ConnectTip during a re-org.
4605 if (pindex->pprev) {
4606 pindex->pprev->hashAnchorEnd = pindex->hashAnchor;
4607 }
102cc989 4608 //komodo_pindex_init(pindex,(int32_t)pindex->nHeight);
0bc1e2c4 4609 }
8d655683 4610
85eb2cef 4611 // Load pointer to end of best chain
145d5be8 4612 BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
84674082 4613 if (it == mapBlockIndex.end())
89b7019b 4614 return true;
84674082 4615 chainActive.SetTip(it->second);
0bc1e2c4
JG
4616 // Set hashAnchorEnd for the end of best chain
4617 it->second->hashAnchorEnd = pcoinsTip->GetBestAnchor();
8d655683 4618
cca48f69 4619 PruneBlockIndexCandidates();
8d655683 4620
52070c87 4621 LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
8d655683 4622 chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
4623 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
4624 Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()));
4625
5b3bc971 4626 EnforceNodeDeprecation(chainActive.Height(), true);
8d655683 4627
1f355b66
PW
4628 return true;
4629}
4630
06a91d96
CL
4631CVerifyDB::CVerifyDB()
4632{
4633 uiInterface.ShowProgress(_("Verifying blocks..."), 0);
4634}
4635
4636CVerifyDB::~CVerifyDB()
4637{
4638 uiInterface.ShowProgress("", 100);
4639}
4640
2e280311 4641bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
168ba993 4642{
a475285a 4643 LOCK(cs_main);
4c6d41b8 4644 if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
1f355b66 4645 return true;
8d655683 4646
2d8a4829 4647 // Verify blocks in the best chain
f5906533 4648 if (nCheckDepth <= 0)
2d8a4829 4649 nCheckDepth = 1000000000; // suffices until the year 19000
4c6d41b8
PW
4650 if (nCheckDepth > chainActive.Height())
4651 nCheckDepth = chainActive.Height();
1f355b66 4652 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
881a85a2 4653 LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
7c70438d 4654 CCoinsViewCache coins(coinsview);
4c6d41b8 4655 CBlockIndex* pindexState = chainActive.Tip();
1f355b66
PW
4656 CBlockIndex* pindexFailure = NULL;
4657 int nGoodTransactions = 0;
ef3988ca 4658 CValidationState state;
6fb8d0c2
JG
4659 // No need to verify JoinSplits twice
4660 auto verifier = libzcash::ProofVerifier::Disabled();
d00db115 4661 //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL));
4c6d41b8 4662 for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
2d8a4829 4663 {
b31499ec 4664 boost::this_thread::interruption_point();
06a91d96 4665 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
4c6d41b8 4666 if (pindex->nHeight < chainActive.Height()-nCheckDepth)
2d8a4829
PW
4667 break;
4668 CBlock block;
1f355b66 4669 // check level 0: read from disk
b8add6a4 4670 if (!ReadBlockFromDisk(block, pindex,0))
5262fde0 4671 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
2d8a4829 4672 // check level 1: verify block validity
9f6cb8f0 4673 int32_t futureblock;
4674 if (nCheckLevel >= 1 && !CheckBlock(&futureblock,pindex->nHeight,pindex,block, state, verifier,0))
5262fde0 4675 return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66
PW
4676 // check level 2: verify undo validity
4677 if (nCheckLevel >= 2 && pindex) {
4678 CBlockUndo undo;
4679 CDiskBlockPos pos = pindex->GetUndoPos();
4680 if (!pos.IsNull()) {
e035c6a7 4681 if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
5262fde0 4682 return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66
PW
4683 }
4684 }
4685 // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
fc684ad8 4686 if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
1f355b66 4687 bool fClean = true;
5c363ed6 4688 if (!DisconnectBlock(block, state, pindex, coins, &fClean))
5262fde0 4689 return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66
PW
4690 pindexState = pindex->pprev;
4691 if (!fClean) {
4692 nGoodTransactions = 0;
4693 pindexFailure = pindex;
4694 } else
4695 nGoodTransactions += block.vtx.size();
2d8a4829 4696 }
70477a0b
TZ
4697 if (ShutdownRequested())
4698 return true;
2d8a4829 4699 }
d00db115 4700 //fprintf(stderr,"end VerifyDB %u\n",(uint32_t)time(NULL));
1f355b66 4701 if (pindexFailure)
5262fde0 4702 return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
8d655683 4703
1f355b66
PW
4704 // check level 4: try reconnecting blocks
4705 if (nCheckLevel >= 4) {
4706 CBlockIndex *pindex = pindexState;
4c6d41b8 4707 while (pindex != chainActive.Tip()) {
b31499ec 4708 boost::this_thread::interruption_point();
06a91d96 4709 uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
4c6d41b8 4710 pindex = chainActive.Next(pindex);
b001c871 4711 CBlock block;
b8add6a4 4712 if (!ReadBlockFromDisk(block, pindex,0))
5262fde0 4713 return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
96f9009e 4714 if (!ConnectBlock(block, state, pindex, coins,false, true))
5262fde0 4715 return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
1f355b66 4716 }
2d8a4829 4717 }
8d655683 4718
4c6d41b8 4719 LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
8d655683 4720
2d8a4829
PW
4721 return true;
4722}
4723
89f20450
PW
4724bool RewindBlockIndex(const CChainParams& params)
4725{
4726 LOCK(cs_main);
8d655683 4727
9e851450 4728 // RewindBlockIndex is called after LoadBlockIndex, so at this point every block
828940b1
JG
4729 // index will have nCachedBranchId set based on the values previously persisted
4730 // to disk. By definition, a set nCachedBranchId means that the block was
9e851450
JG
4731 // fully-validated under the corresponding consensus rules. Thus we can quickly
4732 // identify whether the current active chain matches our expected sequence of
4733 // consensus rule changes, with two checks:
4734 //
4735 // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades.
828940b1 4736 // - nCachedBranchId for each block matches what we expect.
9e851450
JG
4737 auto sufficientlyValidated = [&params](const CBlockIndex* pindex) {
4738 auto consensus = params.GetConsensus();
4739 bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE;
4740 bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus);
828940b1 4741 return fFlagSet == fFlagExpected &&
8d655683 4742 pindex->nCachedBranchId &&
4743 *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->nHeight, consensus);
9e851450 4744 };
8d655683 4745
89f20450
PW
4746 int nHeight = 1;
4747 while (nHeight <= chainActive.Height()) {
9e851450 4748 if (!sufficientlyValidated(chainActive[nHeight])) {
89f20450
PW
4749 break;
4750 }
4751 nHeight++;
4752 }
8d655683 4753
89f20450 4754 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
cb580c72
JG
4755 auto rewindLength = chainActive.Height() - nHeight;
4756 if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH) {
4757 auto pindexOldTip = chainActive.Tip();
4758 auto pindexRewind = chainActive[nHeight - 1];
4759 auto msg = strprintf(_(
8d655683 4760 "A block chain rewind has been detected that would roll back %d blocks! "
4761 "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety."
4762 ), rewindLength, MAX_REORG_LENGTH) + "\n\n" +
4763 _("Rewind details") + ":\n" +
4764 "- " + strprintf(_("Current tip: %s, height %d"),
4765 pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" +
4766 "- " + strprintf(_("Rewinding to: %s, height %d"),
4767 pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" +
4768 _("Please help, human!");
cb580c72
JG
4769 LogPrintf("*** %s\n", msg);
4770 uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR);
4771 StartShutdown();
4772 return false;
4773 }
8d655683 4774
89f20450
PW
4775 CValidationState state;
4776 CBlockIndex* pindex = chainActive.Tip();
4777 while (chainActive.Height() >= nHeight) {
4778 if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) {
4779 // If pruning, don't try rewinding past the HAVE_DATA point;
4780 // since older blocks can't be served anyway, there's
4781 // no need to walk further, and trying to DisconnectTip()
4782 // will fail (and require a needless reindex/redownload
4783 // of the blockchain).
4784 break;
4785 }
4786 if (!DisconnectTip(state, true)) {
4787 return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight);
4788 }
4789 // Occasionally flush state to disk.
4790 if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC))
4791 return false;
4792 }
8d655683 4793
89f20450
PW
4794 // Reduce validity flag and have-data flags.
4795 // We do this after actual disconnecting, otherwise we'll end up writing the lack of data
4796 // to disk before writing the chainstate, resulting in a failure to continue if interrupted.
4797 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
4798 CBlockIndex* pindexIter = it->second;
8d655683 4799
89f20450
PW
4800 // Note: If we encounter an insufficiently validated block that
4801 // is on chainActive, it must be because we are a pruning node, and
4802 // this block or some successor doesn't HAVE_DATA, so we were unable to
4803 // rewind all the way. Blocks remaining on chainActive at this point
4804 // must not have their validity reduced.
9e851450 4805 if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) {
89f20450 4806 // Reduce validity
9e851450 4807 pindexIter->nStatus =
8d655683 4808 std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) |
4809 (pindexIter->nStatus & ~BLOCK_VALID_MASK);
9e851450 4810 // Remove have-data flags
89f20450 4811 pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO);
9e851450
JG
4812 // Remove branch ID
4813 pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE;
828940b1 4814 pindexIter->nCachedBranchId = boost::none;
9e851450 4815 // Remove storage location
89f20450
PW
4816 pindexIter->nFile = 0;
4817 pindexIter->nDataPos = 0;
4818 pindexIter->nUndoPos = 0;
4819 // Remove various other things
4820 pindexIter->nTx = 0;
4821 pindexIter->nChainTx = 0;
9e851450
JG
4822 pindexIter->nSproutValue = boost::none;
4823 pindexIter->nChainSproutValue = boost::none;
89f20450 4824 pindexIter->nSequenceId = 0;
9e851450 4825 // Make sure it gets written
89f20450 4826 setDirtyBlockIndex.insert(pindexIter);
cef5ad03 4827 if (pindexIter == pindexBestInvalid)
4828 {
3d3f275f 4829 //fprintf(stderr,"Reset invalid block marker if it was pointing to this block\n");
cef5ad03 4830 pindexBestInvalid = NULL;
4831 }
4832
9e851450 4833 // Update indices
89f20450 4834 setBlockIndexCandidates.erase(pindexIter);
9e851450 4835 auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev);
89f20450
PW
4836 while (ret.first != ret.second) {
4837 if (ret.first->second == pindexIter) {
4838 mapBlocksUnlinked.erase(ret.first++);
4839 } else {
4840 ++ret.first;
4841 }
4842 }
4843 } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) {
4844 setBlockIndexCandidates.insert(pindexIter);
4845 }
4846 }
8d655683 4847
89f20450 4848 PruneBlockIndexCandidates();
8d655683 4849
89f20450 4850 CheckBlockIndex();
8d655683 4851
89f20450
PW
4852 if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) {
4853 return false;
4854 }
8d655683 4855
89f20450
PW
4856 return true;
4857}
4858
f7f3a96b
PW
4859void UnloadBlockIndex()
4860{
51598b26 4861 LOCK(cs_main);
e17bd583 4862 setBlockIndexCandidates.clear();
4c6d41b8 4863 chainActive.SetTip(NULL);
85eb2cef 4864 pindexBestInvalid = NULL;
51598b26
PW
4865 pindexBestHeader = NULL;
4866 mempool.clear();
4867 mapOrphanTransactions.clear();
4868 mapOrphanTransactionsByPrev.clear();
4869 nSyncStarted = 0;
4870 mapBlocksUnlinked.clear();
4871 vinfoBlockFile.clear();
4872 nLastBlockFile = 0;
4873 nBlockSequenceId = 1;
4874 mapBlockSource.clear();
4875 mapBlocksInFlight.clear();
4876 nQueuedValidatedHeaders = 0;
4877 nPreferredDownload = 0;
4878 setDirtyBlockIndex.clear();
4879 setDirtyFileInfo.clear();
4880 mapNodeState.clear();
ec9b6c33 4881 recentRejects.reset(NULL);
8d655683 4882
51598b26
PW
4883 BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
4884 delete entry.second;
4885 }
4886 mapBlockIndex.clear();
f9ec3f0f 4887 fHavePruned = false;
f7f3a96b
PW
4888}
4889
7fea4846 4890bool LoadBlockIndex()
0a61b0df 4891{
d979e6e3 4892 // Load block index from databases
d042777b 4893 KOMODO_LOADINGBLOCKS = 1;
2d1fa42e 4894 if (!fReindex && !LoadBlockIndexDB())
d042777b 4895 {
4896 KOMODO_LOADINGBLOCKS = 0;
0a61b0df 4897 return false;
d042777b 4898 }
25f7ef8c 4899 fprintf(stderr,"finished loading blocks %s\n",ASSETCHAINS_SYMBOL);
38603761
PW
4900 return true;
4901}
2d1fa42e 4902
2d1fa42e 4903
38603761 4904bool InitBlockIndex() {
e6973430 4905 const CChainParams& chainparams = Params();
55a1db4f 4906 LOCK(cs_main);
8d655683 4907
5094a81d
WL
4908 // Initialize global variables that cannot be constructed at startup.
4909 recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
8d655683 4910
38603761 4911 // Check whether we're already initialized
4c6d41b8 4912 if (chainActive.Genesis() != NULL)
38603761 4913 return true;
8d655683 4914
38603761 4915 // Use the provided setting for -txindex in the new database
b2c00e54 4916 fTxIndex = GetBoolArg("-txindex", true);
38603761 4917 pblocktree->WriteFlag("txindex", fTxIndex);
8b78a819
T
4918 // Use the provided setting for -addressindex in the new database
4919 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
4920 pblocktree->WriteFlag("addressindex", fAddressIndex);
4921
4922 // Use the provided setting for -timestampindex in the new database
4923 fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
4924 pblocktree->WriteFlag("timestampindex", fTimestampIndex);
4925
4926 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
4927 pblocktree->WriteFlag("spentindex", fSpentIndex);
881a85a2 4928 LogPrintf("Initializing databases...\n");
8d655683 4929
38603761
PW
4930 // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
4931 if (!fReindex) {
38603761 4932 try {
0e4b3175
MH
4933 CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
4934 // Start new block file
38603761
PW
4935 unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
4936 CDiskBlockPos blockPos;
4937 CValidationState state;
209377a7 4938 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
5262fde0 4939 return error("LoadBlockIndex(): FindBlockPos failed");
e6973430 4940 if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
5262fde0 4941 return error("LoadBlockIndex(): writing genesis block to disk failed");
942b33a1 4942 CBlockIndex *pindex = AddToBlockIndex(block);
294925c7 4943 if ( pindex == 0 )
4944 return error("LoadBlockIndex(): couldnt add to block index");
942b33a1 4945 if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
5262fde0 4946 return error("LoadBlockIndex(): genesis block not accepted");
92bb6f2f 4947 if (!ActivateBestChain(state, &block))
5262fde0 4948 return error("LoadBlockIndex(): genesis block cannot be activated");
bf7835c2 4949 // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
a2069500 4950 return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
27df4123 4951 } catch (const std::runtime_error& e) {
5262fde0 4952 return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
38603761 4953 }
0a61b0df 4954 }
8d655683 4955
0a61b0df 4956 return true;
4957}
4958
4959
4960
7fea4846 4961bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
1d740055 4962{
4e382177 4963 const CChainParams& chainparams = Params();
ad96e7cc
WL
4964 // Map of disk positions for blocks with unknown parent (only used for reindex)
4965 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
51ed9ec9 4966 int64_t nStart = GetTimeMillis();
8d655683 4967
1d740055 4968 int nLoaded = 0;
421218d3 4969 try {
c9fb27da 4970 // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
b8add6a4 4971 //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
0e32bd33 4972 CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
51ed9ec9 4973 uint64_t nRewind = blkdat.GetPos();
eb0b56b1 4974 while (!blkdat.eof()) {
21eb5ada 4975 boost::this_thread::interruption_point();
8d655683 4976
05d97268
PW
4977 blkdat.SetPos(nRewind);
4978 nRewind++; // start one byte further next time, in case of failure
4979 blkdat.SetLimit(); // remove former limit
7fea4846 4980 unsigned int nSize = 0;
05d97268
PW
4981 try {
4982 // locate a header
0caf2b18 4983 unsigned char buf[MESSAGE_START_SIZE];
0e4b3175 4984 blkdat.FindByte(Params().MessageStart()[0]);
05d97268
PW
4985 nRewind = blkdat.GetPos()+1;
4986 blkdat >> FLATDATA(buf);
0caf2b18 4987 if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
05d97268
PW
4988 continue;
4989 // read size
1d740055 4990 blkdat >> nSize;
05d97268
PW
4991 if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
4992 continue;
27df4123 4993 } catch (const std::exception&) {
7fea4846
PW
4994 // no valid block header found; don't complain
4995 break;
4996 }
4997 try {
05d97268 4998 // read block
51ed9ec9 4999 uint64_t nBlockPos = blkdat.GetPos();
ad96e7cc
WL
5000 if (dbp)
5001 dbp->nPos = nBlockPos;
7fea4846 5002 blkdat.SetLimit(nBlockPos + nSize);
16d51941
PW
5003 blkdat.SetPos(nBlockPos);
5004 CBlock block;
5005 blkdat >> block;
ad96e7cc 5006 nRewind = blkdat.GetPos();
8d655683 5007
16d51941
PW
5008 // detect out of order blocks, and store them for later
5009 uint256 hash = block.GetHash();
4e382177 5010 if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
ad96e7cc 5011 LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
8d655683 5012 block.hashPrevBlock.ToString());
ad96e7cc 5013 if (dbp)
16d51941 5014 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
ad96e7cc
WL
5015 continue;
5016 }
8d655683 5017
16d51941 5018 // process in case the block isn't known yet
8375e221 5019 if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
16d51941 5020 CValidationState state;
7bb789bb 5021 if (ProcessNewBlock(0,0,state, NULL, &block, true, dbp))
16d51941
PW
5022 nLoaded++;
5023 if (state.IsError())
5024 break;
4e382177 5025 } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
50b43fda 5026 LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
16d51941 5027 }
8d655683 5028
ad96e7cc
WL
5029 // Recursively process earlier encountered successors of this block
5030 deque<uint256> queue;
5031 queue.push_back(hash);
5032 while (!queue.empty()) {
5033 uint256 head = queue.front();
5034 queue.pop_front();
5035 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5036 while (range.first != range.second) {
5037 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
b8add6a4 5038 if (ReadBlockFromDisk(mapBlockIndex[hash]!=0?mapBlockIndex[hash]->nHeight:0,block, it->second,1))
ad96e7cc
WL
5039 {
5040 LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
8d655683 5041 head.ToString());
ad96e7cc 5042 CValidationState dummy;
7bb789bb 5043 if (ProcessNewBlock(0,0,dummy, NULL, &block, true, &it->second))
ad96e7cc
WL
5044 {
5045 nLoaded++;
5046 queue.push_back(block.GetHash());
5047 }
5048 }
5049 range.first++;
5050 mapBlocksUnknownParent.erase(it);
5051 }
1d740055 5052 }
27df4123 5053 } catch (const std::exception& e) {
7ff9d122 5054 LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
1d740055
PW
5055 }
5056 }
27df4123 5057 } catch (const std::runtime_error& e) {
b9b2e3fa 5058 AbortNode(std::string("System error: ") + e.what());
1d740055 5059 }
7fea4846 5060 if (nLoaded > 0)
f48742c2 5061 LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
1d740055
PW
5062 return nLoaded > 0;
5063}
0a61b0df 5064
3fcfbc8a
PW
5065void static CheckBlockIndex()
5066{
4e382177 5067 const Consensus::Params& consensusParams = Params().GetConsensus();
3fcfbc8a
PW
5068 if (!fCheckBlockIndex) {
5069 return;
5070 }
8d655683 5071
3fcfbc8a 5072 LOCK(cs_main);
8d655683 5073
0421c18f 5074 // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
5075 // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
5076 // iterating the block tree require that chainActive has been initialized.)
5077 if (chainActive.Height() < 0) {
5078 assert(mapBlockIndex.size() <= 1);
5079 return;
5080 }
8d655683 5081
3fcfbc8a
PW
5082 // Build forward-pointing map of the entire block tree.
5083 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5084 for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
8d655683 5085 forward.insert(std::make_pair(it->second->pprev, it->second));
3fcfbc8a 5086 }
8d655683 5087
3fcfbc8a 5088 assert(forward.size() == mapBlockIndex.size());
8d655683 5089
3fcfbc8a
PW
5090 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
5091 CBlockIndex *pindex = rangeGenesis.first->second;
5092 rangeGenesis.first++;
5093 assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
8d655683 5094
3fcfbc8a
PW
5095 // Iterate over the entire block tree, using depth-first search.
5096 // Along the way, remember whether there are blocks on the path from genesis
5097 // block being explored which are the first to have certain properties.
5098 size_t nNodes = 0;
5099 int nHeight = 0;
5100 CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
5101 CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
f9ec3f0f 5102 CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
3fcfbc8a 5103 CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
ede379f7 5104 CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
3fcfbc8a
PW
5105 CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
5106 CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
5107 while (pindex != NULL) {
5108 nNodes++;
5109 if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
5110 if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
f9ec3f0f 5111 if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
3fcfbc8a 5112 if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
ede379f7 5113 if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
3fcfbc8a
PW
5114 if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
5115 if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
8d655683 5116
3fcfbc8a
PW
5117 // Begin: actual consistency checks.
5118 if (pindex->pprev == NULL) {
5119 // Genesis block checks.
4e382177 5120 assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
3fcfbc8a
PW
5121 assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
5122 }
c1ecee8f 5123 if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
f9ec3f0f 5124 // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
5125 // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
5126 if (!fHavePruned) {
5127 // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
5128 assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
5129 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5130 } else {
5131 // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
5132 if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
5133 }
5134 if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
5135 assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
5136 // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
5137 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 5138 assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
3fcfbc8a
PW
5139 assert(pindex->nHeight == nHeight); // nHeight must be consistent.
5140 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.
5141 assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
5142 assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
5143 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
5144 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
5145 if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
5146 if (pindexFirstInvalid == NULL) {
5147 // Checks for not-invalid blocks.
5148 assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
5149 }
f9ec3f0f 5150 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
5151 if (pindexFirstInvalid == NULL) {
5152 // If this block sorts at least as good as the current tip and
5153 // is valid and we have all data for its parents, it must be in
5154 // setBlockIndexCandidates. chainActive.Tip() must also be there
5155 // even if some data has been pruned.
5156 if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
5157 assert(setBlockIndexCandidates.count(pindex));
5158 }
5159 // If some parent is missing, then it could be that this block was in
5160 // setBlockIndexCandidates but had to be removed because of the missing data.
5161 // In this case it must be in mapBlocksUnlinked -- see test below.
3fcfbc8a 5162 }
f9ec3f0f 5163 } 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
5164 assert(setBlockIndexCandidates.count(pindex) == 0);
5165 }
5166 // Check whether this block is in mapBlocksUnlinked.
5167 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
5168 bool foundInUnlinked = false;
5169 while (rangeUnlinked.first != rangeUnlinked.second) {
5170 assert(rangeUnlinked.first->first == pindex->pprev);
5171 if (rangeUnlinked.first->second == pindex) {
5172 foundInUnlinked = true;
5173 break;
5174 }
5175 rangeUnlinked.first++;
5176 }
f9ec3f0f 5177 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
5178 // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
5179 assert(foundInUnlinked);
5180 }
5181 if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
5182 if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
5183 if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
5184 // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
5185 assert(fHavePruned); // We must have pruned.
5186 // This block may have entered mapBlocksUnlinked if:
5187 // - it has a descendant that at some point had more work than the
5188 // tip, and
5189 // - we tried switching to that descendant but were missing
5190 // data for some intermediate block between chainActive and the
5191 // tip.
5192 // So if this block is itself better than chainActive.Tip() and it wasn't in
5193 // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
5194 if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5195 if (pindexFirstInvalid == NULL) {
5196 assert(foundInUnlinked);
5197 }
3fcfbc8a 5198 }
3fcfbc8a
PW
5199 }
5200 // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
5201 // End: actual consistency checks.
8d655683 5202
3fcfbc8a
PW
5203 // Try descending into the first subnode.
5204 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5205 if (range.first != range.second) {
5206 // A subnode was found.
5207 pindex = range.first->second;
5208 nHeight++;
5209 continue;
5210 }
5211 // This is a leaf node.
5212 // Move upwards until we reach a node of which we have not yet visited the last child.
5213 while (pindex) {
5214 // We are going to either move to a parent or a sibling of pindex.
5215 // If pindex was the first with a certain property, unset the corresponding variable.
5216 if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
5217 if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
f9ec3f0f 5218 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
3fcfbc8a 5219 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
ede379f7 5220 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
3fcfbc8a
PW
5221 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
5222 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
5223 // Find our parent.
5224 CBlockIndex* pindexPar = pindex->pprev;
5225 // Find which child we just visited.
5226 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
5227 while (rangePar.first->second != pindex) {
5228 assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
5229 rangePar.first++;
5230 }
5231 // Proceed to the next one.
5232 rangePar.first++;
5233 if (rangePar.first != rangePar.second) {
5234 // Move to the sibling.
5235 pindex = rangePar.first->second;
5236 break;
5237 } else {
5238 // Move up further.
5239 pindex = pindexPar;
5240 nHeight--;
5241 continue;
5242 }
5243 }
5244 }
8d655683 5245
3fcfbc8a
PW
5246 // Check that we actually traversed the entire map.
5247 assert(nNodes == forward.size());
5248}
5249
0a61b0df 5250//////////////////////////////////////////////////////////////////////////////
5251//
5252// CAlert
5253//
5254
db954a65 5255std::string GetWarnings(const std::string& strFor)
0a61b0df 5256{
5257 int nPriority = 0;
5258 string strStatusBar;
5259 string strRPC;
8d655683 5260
62e21fb5
WL
5261 if (!CLIENT_VERSION_IS_RELEASE)
5262 strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
8d655683 5263
73578933 5264 if (GetBoolArg("-testsafemode", false))
5265 strStatusBar = strRPC = "testsafemode enabled";
8d655683 5266
0a61b0df 5267 // Misc warnings like out of disk space and clock is wrong
5268 if (strMiscWarning != "")
5269 {
5270 nPriority = 1000;
5271 strStatusBar = strMiscWarning;
5272 }
8d655683 5273
b8585384 5274 if (fLargeWorkForkFound)
0a61b0df 5275 {
5276 nPriority = 2000;
f65e7092
MC
5277 strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
5278 }
5279 else if (fLargeWorkInvalidChainFound)
0a61b0df 5280 {
5281 nPriority = 2000;
f65e7092 5282 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 5283 }
8d655683 5284
0a61b0df 5285 // Alerts
0a61b0df 5286 {
f8dcd5ca 5287 LOCK(cs_mapAlerts);
223b6f1b 5288 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
0a61b0df 5289 {
5290 const CAlert& alert = item.second;
5291 if (alert.AppliesToMe() && alert.nPriority > nPriority)
5292 {
5293 nPriority = alert.nPriority;
5294 strStatusBar = alert.strStatusBar;
a40034f7
JG
5295 if (alert.nPriority >= ALERT_PRIORITY_SAFE_MODE) {
5296 strRPC = alert.strRPCError;
5297 }
0a61b0df 5298 }
5299 }
5300 }
8d655683 5301
0a61b0df 5302 if (strFor == "statusbar")
5303 return strStatusBar;
5304 else if (strFor == "rpc")
5305 return strRPC;
5262fde0 5306 assert(!"GetWarnings(): invalid parameter");
0a61b0df 5307 return "error";
5308}
5309
0a61b0df 5310
5311
5312
5313
5314
5315
5316
5317//////////////////////////////////////////////////////////////////////////////
5318//
5319// Messages
5320//
5321
5322
72b25b0f 5323bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
0a61b0df 5324{
5325 switch (inv.type)
5326 {
8d655683 5327 case MSG_TX:
8deb9822 5328 {
5094a81d 5329 assert(recentRejects);
ec9b6c33
PT
5330 if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
5331 {
5332 // If the chain tip has changed previously rejected transactions
5333 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
5334 // or a double-spend. Reset the rejects filter and give those
5335 // txs a second chance.
5336 hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
5337 recentRejects->reset();
5338 }
8d655683 5339
ec9b6c33 5340 return recentRejects->contains(inv.hash) ||
8d655683 5341 mempool.exists(inv.hash) ||
5342 mapOrphanTransactions.count(inv.hash) ||
5343 pcoinsTip->HaveCoins(inv.hash);
8deb9822 5344 }
8d655683 5345 case MSG_BLOCK:
5346 return mapBlockIndex.count(inv.hash);
0a61b0df 5347 }
5348 // Don't know what it is, just say we already got one
5349 return true;
5350}
5351
c7f039b6
PW
5352void static ProcessGetData(CNode* pfrom)
5353{
5354 std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
8d655683 5355
c7f039b6 5356 vector<CInv> vNotFound;
8d655683 5357
7d38af3c 5358 LOCK(cs_main);
8d655683 5359
c7f039b6
PW
5360 while (it != pfrom->vRecvGetData.end()) {
5361 // Don't bother if send buffer is too full to respond anyway
5362 if (pfrom->nSendSize >= SendBufferSize())
5363 break;
8d655683 5364
c7f039b6
PW
5365 const CInv &inv = *it;
5366 {
b31499ec 5367 boost::this_thread::interruption_point();
c7f039b6 5368 it++;
8d655683 5369
c7f039b6
PW
5370 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5371 {
d8b4b496 5372 bool send = false;
145d5be8 5373 BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
c7f039b6
PW
5374 if (mi != mapBlockIndex.end())
5375 {
85da07a5 5376 if (chainActive.Contains(mi->second)) {
2b45345a 5377 send = true;
85da07a5 5378 } else {
f7303f97 5379 static const int nOneMonth = 30 * 24 * 60 * 60;
85da07a5 5380 // To prevent fingerprinting attacks, only send blocks outside of the active
f7303f97
PW
5381 // chain if they are valid, and no more than a month older (both in time, and in
5382 // best equivalent proof of work) than the best header chain we know about.
85da07a5 5383 send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
8d655683 5384 (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
5385 (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
85da07a5 5386 if (!send) {
30c1db1c 5387 LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
85da07a5 5388 }
d8b4b496
AH
5389 }
5390 }
f9ec3f0f 5391 // Pruned nodes may have deleted the block, so check whether
5392 // it's available before trying to send.
5393 if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
d8b4b496
AH
5394 {
5395 // Send block from disk
c7f039b6 5396 CBlock block;
b8add6a4 5397 if (!ReadBlockFromDisk(block, (*mi).second,1))
13931733 5398 {
b34b7b31 5399 assert(!"cannot load block from disk");
13931733 5400 }
5401 else
c7f039b6 5402 {
13931733 5403 if (inv.type == MSG_BLOCK)
c2b0ec2e 5404 {
37782e4e 5405 //uint256 hash; int32_t z;
5406 //hash = block.GetHash();
5407 //for (z=31; z>=0; z--)
5408 // fprintf(stderr,"%02x",((uint8_t *)&hash)[z]);
5409 //fprintf(stderr," send block %d\n",komodo_block2height(&block));
13931733 5410 pfrom->PushMessage("block", block);
c2b0ec2e 5411 }
13931733 5412 else // MSG_FILTERED_BLOCK)
c7f039b6 5413 {
13931733 5414 LOCK(pfrom->cs_filter);
5415 if (pfrom->pfilter)
5416 {
5417 CMerkleBlock merkleBlock(block, *pfrom->pfilter);
5418 pfrom->PushMessage("merkleblock", merkleBlock);
5419 // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
5420 // This avoids hurting performance by pointlessly requiring a round-trip
5421 // Note that there is currently no way for a node to request any single transactions we didn't send here -
5422 // they must either disconnect and retry or request the full block.
5423 // Thus, the protocol spec specified allows for us to provide duplicate txn here,
5424 // however we MUST always provide at least what the remote peer needs
5425 typedef std::pair<unsigned int, uint256> PairType;
5426 BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
c7f039b6
PW
5427 if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
5428 pfrom->PushMessage("tx", block.vtx[pair.first]);
13931733 5429 }
5430 // else
c7f039b6 5431 // no response
13931733 5432 }
c7f039b6 5433 }
b05a89b2 5434 // Trigger the peer node to send a getblocks request for the next batch of inventory
c7f039b6
PW
5435 if (inv.hash == pfrom->hashContinue)
5436 {
5437 // Bypass PushInventory, this must send even if redundant,
5438 // and we want it right after the last block so they don't
5439 // wait for other stuff first.
5440 vector<CInv> vInv;
4c6d41b8 5441 vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
c7f039b6 5442 pfrom->PushMessage("inv", vInv);
4f152496 5443 pfrom->hashContinue.SetNull();
c7f039b6
PW
5444 }
5445 }
5446 }
5447 else if (inv.IsKnownType())
5448 {
5449 // Send stream from relay memory
5450 bool pushed = false;
5451 {
5452 LOCK(cs_mapRelay);
5453 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
5454 if (mi != mapRelay.end()) {
5455 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
5456 pushed = true;
5457 }
5458 }
5459 if (!pushed && inv.type == MSG_TX) {
319b1160
GA
5460 CTransaction tx;
5461 if (mempool.lookup(inv.hash, tx)) {
c7f039b6
PW
5462 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
5463 ss.reserve(1000);
5464 ss << tx;
5465 pfrom->PushMessage("tx", ss);
5466 pushed = true;
5467 }
5468 }
5469 if (!pushed) {
5470 vNotFound.push_back(inv);
5471 }
5472 }
8d655683 5473
c7f039b6 5474 // Track requests for our stuff.
26c16d9d 5475 GetMainSignals().Inventory(inv.hash);
8d655683 5476
75ef87dd
PS
5477 if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
5478 break;
c7f039b6
PW
5479 }
5480 }
8d655683 5481
c7f039b6 5482 pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
8d655683 5483
c7f039b6
PW
5484 if (!vNotFound.empty()) {
5485 // Let the peer know that we didn't find what it asked for, so it doesn't
5486 // have to wait around forever. Currently only SPV clients actually care
5487 // about this message: it's needed when they are recursively walking the
5488 // dependencies of relevant unconfirmed transactions. SPV clients want to
5489 // do that because they want to know about (and store and rebroadcast and
5490 // risk analyze) the dependencies of transactions relevant to them, without
5491 // having to download the entire memory pool.
5492 pfrom->PushMessage("notfound", vNotFound);
5493 }
5494}
5495
9f4da19b 5496bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
0a61b0df 5497{
e8e8904d 5498 const CChainParams& chainparams = Params();
28d4cff0 5499 LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
37782e4e 5500 //fprintf(stderr, "recv: %s peer=%d\n", SanitizeString(strCommand).c_str(), (int32_t)pfrom->GetId());
0a61b0df 5501 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
5502 {
881a85a2 5503 LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
0a61b0df 5504 return true;
5505 }
8d655683 5506
5507
5508
5509
0a61b0df 5510 if (strCommand == "version")
5511 {
5512 // Each connection can only send one version message
5513 if (pfrom->nVersion != 0)
806704c2 5514 {
358ce266 5515 pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
b2864d2f 5516 Misbehaving(pfrom->GetId(), 1);
0a61b0df 5517 return false;
806704c2 5518 }
8d655683 5519
51ed9ec9 5520 int64_t nTime;
0a61b0df 5521 CAddress addrMe;
5522 CAddress addrFrom;
51ed9ec9 5523 uint64_t nNonce = 1;
0a61b0df 5524 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
1ce41892 5525 if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
18c0fa97 5526 {
1ce41892 5527 // disconnect from peers older than this proto version
2e36866f 5528 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
358ce266
GA
5529 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
5530 strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
18c0fa97
PW
5531 pfrom->fDisconnect = true;
5532 return false;
5533 }
8d655683 5534
72b21929
S
5535 // When Overwinter is active, reject incoming connections from non-Overwinter nodes
5536 const Consensus::Params& params = Params().GetConsensus();
5537 if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER)
5538 && pfrom->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)
5539 {
5540 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5541 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
8d655683 5542 strprintf("Version must be %d or greater",
5543 params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
72b21929
S
5544 pfrom->fDisconnect = true;
5545 return false;
5546 }
8d655683 5547
0a61b0df 5548 if (pfrom->nVersion == 10300)
5549 pfrom->nVersion = 300;
18c0fa97 5550 if (!vRecv.empty())
0a61b0df 5551 vRecv >> addrFrom >> nNonce;
a946aa8d 5552 if (!vRecv.empty()) {
216e9a44 5553 vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
a946aa8d
MH
5554 pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
5555 }
18c0fa97 5556 if (!vRecv.empty())
0a61b0df 5557 vRecv >> pfrom->nStartingHeight;
4c8fc1a5
MC
5558 if (!vRecv.empty())
5559 vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
5560 else
5561 pfrom->fRelayTxes = true;
8d655683 5562
0a61b0df 5563 // Disconnect if we connected to ourself
5564 if (nNonce == nLocalHostNonce && nNonce > 1)
5565 {
7d9d134b 5566 LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
0a61b0df 5567 pfrom->fDisconnect = true;
5568 return true;
5569 }
8d655683 5570
845c86d1
GM
5571 pfrom->addrLocal = addrMe;
5572 if (pfrom->fInbound && addrMe.IsRoutable())
5573 {
5574 SeenLocal(addrMe);
5575 }
8d655683 5576
cbc920d4
GA
5577 // Be shy and don't send version until we hear
5578 if (pfrom->fInbound)
5579 pfrom->PushVersion();
8d655683 5580
0a61b0df 5581 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
8d655683 5582
b4ee0bdd
PW
5583 // Potentially mark this peer as a preferred download peer.
5584 UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
8d655683 5585
0a61b0df 5586 // Change version
18c0fa97 5587 pfrom->PushMessage("verack");
41b052ad 5588 pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
8d655683 5589
c891967b 5590 if (!pfrom->fInbound)
5591 {
5592 // Advertise our address
53a08815 5593 if (fListen && !IsInitialBlockDownload())
c891967b 5594 {
39857190
PW
5595 CAddress addr = GetLocalAddress(&pfrom->addr);
5596 if (addr.IsRoutable())
845c86d1 5597 {
eb5f63fe 5598 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
845c86d1
GM
5599 pfrom->PushAddress(addr);
5600 } else if (IsPeerAddrLocalGood(pfrom)) {
5601 addr.SetIP(pfrom->addrLocal);
eb5f63fe 5602 LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString());
39857190 5603 pfrom->PushAddress(addr);
845c86d1 5604 }
c891967b 5605 }
8d655683 5606
c891967b 5607 // Get recent addresses
478b01d9 5608 if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
c891967b 5609 {
5610 pfrom->PushMessage("getaddr");
5611 pfrom->fGetAddr = true;
5612 }
5fee401f
PW
5613 addrman.Good(pfrom->addr);
5614 } else {
5615 if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
5616 {
5617 addrman.Add(addrFrom, addrFrom);
5618 addrman.Good(addrFrom);
5619 }
c891967b 5620 }
8d655683 5621
0a61b0df 5622 // Relay alerts
f8dcd5ca
PW
5623 {
5624 LOCK(cs_mapAlerts);
223b6f1b 5625 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
8d655683 5626 item.second.RelayTo(pfrom);
f8dcd5ca 5627 }
8d655683 5628
0a61b0df 5629 pfrom->fSuccessfullyConnected = true;
8d655683 5630
70b9d36a
JG
5631 string remoteAddr;
5632 if (fLogIPs)
5633 remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
8d655683 5634
70b9d36a
JG
5635 LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
5636 pfrom->cleanSubVer, pfrom->nVersion,
5637 pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
5638 remoteAddr);
8d655683 5639
26a6bae7
PJ
5640 int64_t nTimeOffset = nTime - GetTime();
5641 pfrom->nTimeOffset = nTimeOffset;
5642 AddTimeData(pfrom->addr, nTimeOffset);
0a61b0df 5643 }
8d655683 5644
5645
0a61b0df 5646 else if (pfrom->nVersion == 0)
5647 {
5648 // Must have a version message before anything else
b2864d2f 5649 Misbehaving(pfrom->GetId(), 1);
0a61b0df 5650 return false;
5651 }
8d655683 5652
5653
0a61b0df 5654 else if (strCommand == "verack")
5655 {
607dbfde 5656 pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
8d655683 5657
9c273790
PW
5658 // Mark this node as currently connected, so we update its timestamp later.
5659 if (pfrom->fNetworkNode) {
5660 LOCK(cs_main);
5661 State(pfrom->GetId())->fCurrentlyConnected = true;
5662 }
0a61b0df 5663 }
8d655683 5664
5665
72b21929
S
5666 // Disconnect existing peer connection when:
5667 // 1. The version message has been received
5668 // 2. Overwinter is active
5669 // 3. Peer version is pre-Overwinter
5670 else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER)
8d655683 5671 && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion))
72b21929
S
5672 {
5673 LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
5674 pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
8d655683 5675 strprintf("Version must be %d or greater",
5676 chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion));
72b21929
S
5677 pfrom->fDisconnect = true;
5678 return false;
5679 }
8d655683 5680
5681
0a61b0df 5682 else if (strCommand == "addr")
5683 {
5684 vector<CAddress> vAddr;
5685 vRecv >> vAddr;
8d655683 5686
c891967b 5687 // Don't want addr from older versions unless seeding
8b09cd3a 5688 if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
0a61b0df 5689 return true;
5690 if (vAddr.size() > 1000)
806704c2 5691 {
b2864d2f 5692 Misbehaving(pfrom->GetId(), 20);
783b182c 5693 return error("message addr size() = %u", vAddr.size());
806704c2 5694 }
8d655683 5695
0a61b0df 5696 // Store the new addresses
090e5b40 5697 vector<CAddress> vAddrOk;
51ed9ec9
BD
5698 int64_t nNow = GetAdjustedTime();
5699 int64_t nSince = nNow - 10 * 60;
223b6f1b 5700 BOOST_FOREACH(CAddress& addr, vAddr)
0a61b0df 5701 {
b31499ec 5702 boost::this_thread::interruption_point();
8d655683 5703
c891967b 5704 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
5705 addr.nTime = nNow - 5 * 24 * 60 * 60;
0a61b0df 5706 pfrom->AddAddressKnown(addr);
090e5b40 5707 bool fReachable = IsReachable(addr);
c891967b 5708 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
0a61b0df 5709 {
5710 // Relay to a limited number of other nodes
0a61b0df 5711 {
f8dcd5ca 5712 LOCK(cs_vNodes);
5cbf7532 5713 // Use deterministic randomness to send to the same nodes for 24 hours
d81cff32 5714 // at a time so the addrKnowns of the chosen nodes prevent repeats
0a61b0df 5715 static uint256 hashSalt;
4f152496 5716 if (hashSalt.IsNull())
f718aedd 5717 hashSalt = GetRandHash();
51ed9ec9 5718 uint64_t hashAddr = addr.GetHash();
734f85c4 5719 uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
5cbf7532 5720 hashRand = Hash(BEGIN(hashRand), END(hashRand));
0a61b0df 5721 multimap<uint256, CNode*> mapMix;
223b6f1b 5722 BOOST_FOREACH(CNode* pnode, vNodes)
5cbf7532 5723 {
8b09cd3a 5724 if (pnode->nVersion < CADDR_TIME_VERSION)
c891967b 5725 continue;
5cbf7532 5726 unsigned int nPointer;
5727 memcpy(&nPointer, &pnode, sizeof(nPointer));
734f85c4 5728 uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
5cbf7532 5729 hashKey = Hash(BEGIN(hashKey), END(hashKey));
5730 mapMix.insert(make_pair(hashKey, pnode));
5731 }
090e5b40 5732 int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
0a61b0df 5733 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
5734 ((*mi).second)->PushAddress(addr);
5735 }
5736 }
090e5b40
PW
5737 // Do not store addresses outside our network
5738 if (fReachable)
5739 vAddrOk.push_back(addr);
0a61b0df 5740 }
090e5b40 5741 addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
0a61b0df 5742 if (vAddr.size() < 1000)
5743 pfrom->fGetAddr = false;
478b01d9
PW
5744 if (pfrom->fOneShot)
5745 pfrom->fDisconnect = true;
0a61b0df 5746 }
8d655683 5747
5748
0a61b0df 5749 else if (strCommand == "inv")
5750 {
5751 vector<CInv> vInv;
5752 vRecv >> vInv;
05a85b2b 5753 if (vInv.size() > MAX_INV_SZ)
806704c2 5754 {
b2864d2f 5755 Misbehaving(pfrom->GetId(), 20);
783b182c 5756 return error("message inv size() = %u", vInv.size());
806704c2 5757 }
8d655683 5758
7d38af3c 5759 LOCK(cs_main);
8d655683 5760
341735eb 5761 std::vector<CInv> vToFetch;
8d655683 5762
c376ac35 5763 for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
0a61b0df 5764 {
0aa89c08 5765 const CInv &inv = vInv[nInv];
8d655683 5766
b31499ec 5767 boost::this_thread::interruption_point();
0a61b0df 5768 pfrom->AddInventoryKnown(inv);
8d655683 5769
ae8bfd12 5770 bool fAlreadyHave = AlreadyHave(inv);
2e36866f 5771 LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
8d655683 5772
341735eb
PW
5773 if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
5774 pfrom->AskFor(inv);
8d655683 5775
341735eb 5776 if (inv.type == MSG_BLOCK) {
aa815647 5777 UpdateBlockAvailability(pfrom->GetId(), inv.hash);
341735eb 5778 if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
7e6d23b1 5779 // First request the headers preceding the announced block. In the normal fully-synced
341735eb
PW
5780 // case where a new block is announced that succeeds the current tip (no reorganization),
5781 // there are no such headers.
5782 // Secondly, and only when we are close to being synced, we request the announced block directly,
5783 // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
5784 // time the block arrives, the header chain leading up to it is already validated. Not
5785 // doing this will result in the received block being rejected as an orphan in case it is
5786 // not a direct successor.
5787 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
c9077043 5788 CNodeState *nodestate = State(pfrom->GetId());
e8e8904d 5789 if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
c9077043 5790 nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
341735eb
PW
5791 vToFetch.push_back(inv);
5792 // Mark block as in flight already, even though the actual "getdata" message only goes out
5793 // later (within the same cs_main lock, though).
82737933 5794 MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
341735eb 5795 }
4c933229 5796 LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
341735eb
PW
5797 }
5798 }
8d655683 5799
0a61b0df 5800 // Track requests for our stuff
26c16d9d 5801 GetMainSignals().Inventory(inv.hash);
8d655683 5802
540ac451
JG
5803 if (pfrom->nSendSize > (SendBufferSize() * 2)) {
5804 Misbehaving(pfrom->GetId(), 50);
5805 return error("send buffer size() = %u", pfrom->nSendSize);
5806 }
0a61b0df 5807 }
8d655683 5808
341735eb
PW
5809 if (!vToFetch.empty())
5810 pfrom->PushMessage("getdata", vToFetch);
0a61b0df 5811 }
8d655683 5812
5813
0a61b0df 5814 else if (strCommand == "getdata")
5815 {
5816 vector<CInv> vInv;
5817 vRecv >> vInv;
05a85b2b 5818 if (vInv.size() > MAX_INV_SZ)
806704c2 5819 {
b2864d2f 5820 Misbehaving(pfrom->GetId(), 20);
783b182c 5821 return error("message getdata size() = %u", vInv.size());
806704c2 5822 }
8d655683 5823
3b570559 5824 if (fDebug || (vInv.size() != 1))
2e36866f 5825 LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
8d655683 5826
3b570559 5827 if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
2e36866f 5828 LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
8d655683 5829
c7f039b6
PW
5830 pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
5831 ProcessGetData(pfrom);
0a61b0df 5832 }
8d655683 5833
5834
0a61b0df 5835 else if (strCommand == "getblocks")
5836 {
5837 CBlockLocator locator;
5838 uint256 hashStop;
5839 vRecv >> locator >> hashStop;
8d655683 5840
7d38af3c 5841 LOCK(cs_main);
8d655683 5842
f03304a9 5843 // Find the last block the caller has in the main chain
6db83db3 5844 CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
8d655683 5845
0a61b0df 5846 // Send the rest of the chain
5847 if (pindex)
4c6d41b8 5848 pindex = chainActive.Next(pindex);
9d6cd04b 5849 int nLimit = 500;
4f152496 5850 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 5851 for (; pindex; pindex = chainActive.Next(pindex))
0a61b0df 5852 {
5853 if (pindex->GetBlockHash() == hashStop)
5854 {
7d9d134b 5855 LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
0a61b0df 5856 break;
5857 }
5858 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
9d6cd04b 5859 if (--nLimit <= 0)
0a61b0df 5860 {
b05a89b2
LD
5861 // When this block is requested, we'll send an inv that'll
5862 // trigger the peer to getblocks the next batch of inventory.
7d9d134b 5863 LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
0a61b0df 5864 pfrom->hashContinue = pindex->GetBlockHash();
5865 break;
5866 }
5867 }
5868 }
8d655683 5869
5870
f03304a9 5871 else if (strCommand == "getheaders")
5872 {
5873 CBlockLocator locator;
5874 uint256 hashStop;
5875 vRecv >> locator >> hashStop;
8d655683 5876
7d38af3c 5877 LOCK(cs_main);
8d655683 5878
b4bbad18
SD
5879 if (IsInitialBlockDownload())
5880 return true;
8d655683 5881
f03304a9 5882 CBlockIndex* pindex = NULL;
5883 if (locator.IsNull())
5884 {
5885 // If locator is null, return the hashStop block
145d5be8 5886 BlockMap::iterator mi = mapBlockIndex.find(hashStop);
f03304a9 5887 if (mi == mapBlockIndex.end())
5888 return true;
5889 pindex = (*mi).second;
5890 }
5891 else
5892 {
5893 // Find the last block the caller has in the main chain
6db83db3 5894 pindex = FindForkInGlobalIndex(chainActive, locator);
f03304a9 5895 if (pindex)
4c6d41b8 5896 pindex = chainActive.Next(pindex);
f03304a9 5897 }
8d655683 5898
e754cf41 5899 // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
f03304a9 5900 vector<CBlock> vHeaders;
341735eb 5901 int nLimit = MAX_HEADERS_RESULTS;
4c933229 5902 LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
f8a07170 5903 //if ( pfrom->lasthdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pfrom->lasthdrsreq != (int32_t)(pindex ? pindex->nHeight : -1) )// no need to ever suppress this
f03304a9 5904 {
164bbe6c 5905 pfrom->lasthdrsreq = (int32_t)(pindex ? pindex->nHeight : -1);
336a60cf 5906 for (; pindex; pindex = chainActive.Next(pindex))
5907 {
5908 vHeaders.push_back(pindex->GetBlockHeader());
5909 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
5910 break;
5911 }
5912 pfrom->PushMessage("headers", vHeaders);
8dcf7f94 5913 }
f8a07170 5914 /*else if ( NOTARY_PUBKEY33[0] != 0 )
bd901dd7 5915 {
5916 static uint32_t counter;
5917 if ( counter++ < 3 )
5918 fprintf(stderr,"you can ignore redundant getheaders from peer.%d %d prev.%d\n",(int32_t)pfrom->id,(int32_t)(pindex ? pindex->nHeight : -1),pfrom->lasthdrsreq);
f8a07170 5919 }*/
f03304a9 5920 }
8d655683 5921
5922
0a61b0df 5923 else if (strCommand == "tx")
5924 {
5925 vector<uint256> vWorkQueue;
7a15109c 5926 vector<uint256> vEraseQueue;
0a61b0df 5927 CTransaction tx;
5928 vRecv >> tx;
8d655683 5929
805344dc 5930 CInv inv(MSG_TX, tx.GetHash());
0a61b0df 5931 pfrom->AddInventoryKnown(inv);
8d655683 5932
7d38af3c 5933 LOCK(cs_main);
8d655683 5934
0a61b0df 5935 bool fMissingInputs = false;
ef3988ca 5936 CValidationState state;
8d655683 5937
e2190f80 5938 pfrom->setAskFor.erase(inv.hash);
604ee2aa 5939 mapAlreadyAskedFor.erase(inv);
8d655683 5940
60aed954 5941 if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
0a61b0df 5942 {
a0fa20a1 5943 mempool.check(pcoinsTip);
d38da59b 5944 RelayTransaction(tx);
0a61b0df 5945 vWorkQueue.push_back(inv.hash);
8d655683 5946
5262fde0 5947 LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
8d655683 5948 pfrom->id, pfrom->cleanSubVer,
5949 tx.GetHash().ToString(),
5950 mempool.mapTx.size());
5951
0a61b0df 5952 // Recursively process any orphan transactions that depended on this one
c74332c6 5953 set<NodeId> setMisbehaving;
c376ac35 5954 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
0a61b0df 5955 {
89d91f6a
WL
5956 map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
5957 if (itByPrev == mapOrphanTransactionsByPrev.end())
5958 continue;
5959 for (set<uint256>::iterator mi = itByPrev->second.begin();
5960 mi != itByPrev->second.end();
0a61b0df 5961 ++mi)
5962 {
159bc481 5963 const uint256& orphanHash = *mi;
c74332c6
GA
5964 const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
5965 NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
7a15109c 5966 bool fMissingInputs2 = false;
159bc481
GA
5967 // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
5968 // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
5969 // anyone relaying LegitTxX banned)
8c4e4313 5970 CValidationState stateDummy;
8d655683 5971
5972
c74332c6
GA
5973 if (setMisbehaving.count(fromPeer))
5974 continue;
319b1160 5975 if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
0a61b0df 5976 {
7d9d134b 5977 LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
d38da59b 5978 RelayTransaction(orphanTx);
159bc481 5979 vWorkQueue.push_back(orphanHash);
37b4e425 5980 vEraseQueue.push_back(orphanHash);
7a15109c
GA
5981 }
5982 else if (!fMissingInputs2)
5983 {
c74332c6
GA
5984 int nDos = 0;
5985 if (stateDummy.IsInvalid(nDos) && nDos > 0)
5986 {
5987 // Punish peer that gave us an invalid orphan tx
5988 Misbehaving(fromPeer, nDos);
5989 setMisbehaving.insert(fromPeer);
5990 LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
5991 }
37b4e425
AM
5992 // Has inputs but not accepted to mempool
5993 // Probably non-standard or insufficient fee/priority
7d9d134b 5994 LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
37b4e425 5995 vEraseQueue.push_back(orphanHash);
5094a81d 5996 assert(recentRejects);
ec9b6c33 5997 recentRejects->insert(orphanHash);
0a61b0df 5998 }
a0fa20a1 5999 mempool.check(pcoinsTip);
0a61b0df 6000 }
6001 }
8d655683 6002
7a15109c 6003 BOOST_FOREACH(uint256 hash, vEraseQueue)
8d655683 6004 EraseOrphanTx(hash);
0a61b0df 6005 }
b7e4abd6 6006 // TODO: currently, prohibit joinsplits from entering mapOrphans
8675d94b 6007 else if (fMissingInputs && tx.vjoinsplit.size() == 0)
0a61b0df 6008 {
c74332c6 6009 AddOrphanTx(tx, pfrom->GetId());
8d655683 6010
142e6041 6011 // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
aa3c697e
GA
6012 unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
6013 unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
142e6041 6014 if (nEvicted > 0)
881a85a2 6015 LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
ec9b6c33 6016 } else {
36f14bf2 6017 assert(recentRejects);
805344dc 6018 recentRejects->insert(tx.GetHash());
8d655683 6019
ec9b6c33
PT
6020 if (pfrom->fWhitelisted) {
6021 // Always relay transactions received from whitelisted peers, even
60aed954
PW
6022 // if they were already in the mempool or rejected from it due
6023 // to policy, allowing the node to function as a gateway for
6024 // nodes hidden behind it.
ec9b6c33 6025 //
60aed954
PW
6026 // Never relay transactions that we would assign a non-zero DoS
6027 // score for, as we expect peers to do the same with us in that
6028 // case.
6029 int nDoS = 0;
6030 if (!state.IsInvalid(nDoS) || nDoS == 0) {
6031 LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id);
6032 RelayTransaction(tx);
6033 } else {
e63d14fd 6034 LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s (code %d))\n",
8d655683 6035 tx.GetHash().ToString(), pfrom->id, state.GetRejectReason(), state.GetRejectCode());
60aed954 6036 }
ec9b6c33 6037 }
0a61b0df 6038 }
fbed9c9d 6039 int nDoS = 0;
5ea66c54 6040 if (state.IsInvalid(nDoS))
2b45345a 6041 {
805344dc 6042 LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
8d655683 6043 pfrom->id, pfrom->cleanSubVer,
6044 state.GetRejectReason());
358ce266 6045 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
307f7d48 6046 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
5ea66c54 6047 if (nDoS > 0)
b2864d2f 6048 Misbehaving(pfrom->GetId(), nDoS);
358ce266 6049 }
0a61b0df 6050 }
8d655683 6051
6052
341735eb
PW
6053 else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
6054 {
6055 std::vector<CBlockHeader> headers;
8d655683 6056
341735eb
PW
6057 // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
6058 unsigned int nCount = ReadCompactSize(vRecv);
6059 if (nCount > MAX_HEADERS_RESULTS) {
6060 Misbehaving(pfrom->GetId(), 20);
6061 return error("headers message size = %u", nCount);
6062 }
6063 headers.resize(nCount);
6064 for (unsigned int n = 0; n < nCount; n++) {
6065 vRecv >> headers[n];
6066 ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
6067 }
8d655683 6068
341735eb 6069 LOCK(cs_main);
8d655683 6070
341735eb
PW
6071 if (nCount == 0) {
6072 // Nothing interesting. Stop asking this peers for more headers.
6073 return true;
6074 }
8d655683 6075
341735eb
PW
6076 CBlockIndex *pindexLast = NULL;
6077 BOOST_FOREACH(const CBlockHeader& header, headers) {
6078 CValidationState state;
6079 if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
6080 Misbehaving(pfrom->GetId(), 20);
6081 return error("non-continuous headers sequence");
6082 }
531b9293 6083 int32_t futureblock;
66dd02d2 6084 //fprintf(stderr,"headers msg nCount.%d\n",(int32_t)nCount);
531b9293 6085 if (!AcceptBlockHeader(&futureblock,header, state, &pindexLast)) {
341735eb 6086 int nDoS;
6477ad07 6087 if (state.IsInvalid(nDoS))
6088 {
531b9293 6089 if (nDoS > 0 && futureblock == 0)
0d2cefb0 6090 Misbehaving(pfrom->GetId(), nDoS/nDoS);
341735eb
PW
6091 return error("invalid header received");
6092 }
6093 }
6094 }
8d655683 6095
341735eb
PW
6096 if (pindexLast)
6097 UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
8d655683 6098
341735eb
PW
6099 if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
6100 // Headers message had its maximum size; the peer may have more headers.
6101 // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
6102 // from there instead.
8ab425f8 6103 if ( pfrom->sendhdrsreq >= chainActive.Height()-MAX_HEADERS_RESULTS || pindexLast->nHeight != pfrom->sendhdrsreq )
6104 {
6105 pfrom->sendhdrsreq = (int32_t)pindexLast->nHeight;
6106 LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
6107 pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
6108 }
341735eb 6109 }
8d655683 6110
3fcfbc8a 6111 CheckBlockIndex();
341735eb 6112 }
8d655683 6113
7fea4846 6114 else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
0a61b0df 6115 {
f03304a9 6116 CBlock block;
6117 vRecv >> block;
8d655683 6118
f03304a9 6119 CInv inv(MSG_BLOCK, block.GetHash());
341735eb 6120 LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
8d655683 6121
341735eb 6122 pfrom->AddInventoryKnown(inv);
8d655683 6123
ef3988ca 6124 CValidationState state;
93b606ae
SD
6125 // Process all blocks from whitelisted peers, even if not requested,
6126 // unless we're still syncing with the network.
6127 // Such an unrequested block may still be processed, subject to the
6128 // conditions in AcceptBlock().
6129 bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
7bb789bb 6130 ProcessNewBlock(0,0,state, pfrom, &block, forceProcessing, NULL);
40f5cb87
PW
6131 int nDoS;
6132 if (state.IsInvalid(nDoS)) {
6133 pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
307f7d48 6134 state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
40f5cb87
PW
6135 if (nDoS > 0) {
6136 LOCK(cs_main);
6137 Misbehaving(pfrom->GetId(), nDoS);
6138 }
6139 }
8d655683 6140
0a61b0df 6141 }
8d655683 6142
6143
dca799e1
IP
6144 // This asymmetric behavior for inbound and outbound connections was introduced
6145 // to prevent a fingerprinting attack: an attacker can send specific fake addresses
b05a89b2
LD
6146 // to users' AddrMan and later request them by sending getaddr messages.
6147 // Making nodes which are behind NAT and can only make outgoing connections ignore
6148 // the getaddr message mitigates the attack.
dca799e1 6149 else if ((strCommand == "getaddr") && (pfrom->fInbound))
0a61b0df 6150 {
a514cb29
GM
6151 // Only send one GetAddr response per connection to reduce resource waste
6152 // and discourage addr stamping of INV announcements.
6153 if (pfrom->fSentAddr) {
6154 LogPrint("net", "Ignoring repeated \"getaddr\". peer=%d\n", pfrom->id);
6155 return true;
6156 }
6157 pfrom->fSentAddr = true;
8d655683 6158
0a61b0df 6159 pfrom->vAddrToSend.clear();
5fee401f
PW
6160 vector<CAddress> vAddr = addrman.GetAddr();
6161 BOOST_FOREACH(const CAddress &addr, vAddr)
8d655683 6162 pfrom->PushAddress(addr);
0a61b0df 6163 }
8d655683 6164
6165
05a85b2b
JG
6166 else if (strCommand == "mempool")
6167 {
319b1160 6168 LOCK2(cs_main, pfrom->cs_filter);
8d655683 6169
05a85b2b
JG
6170 std::vector<uint256> vtxid;
6171 mempool.queryHashes(vtxid);
6172 vector<CInv> vInv;
c51694eb
MC
6173 BOOST_FOREACH(uint256& hash, vtxid) {
6174 CInv inv(MSG_TX, hash);
319b1160
GA
6175 CTransaction tx;
6176 bool fInMemPool = mempool.lookup(hash, tx);
6177 if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
d38da59b 6178 if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
8d655683 6179 (!pfrom->pfilter))
c51694eb 6180 vInv.push_back(inv);
1f3d3647
GA
6181 if (vInv.size() == MAX_INV_SZ) {
6182 pfrom->PushMessage("inv", vInv);
6183 vInv.clear();
6184 }
05a85b2b
JG
6185 }
6186 if (vInv.size() > 0)
6187 pfrom->PushMessage("inv", vInv);
6188 }
8d655683 6189
6190
0a61b0df 6191 else if (strCommand == "ping")
6192 {
93e447b6
JG
6193 if (pfrom->nVersion > BIP0031_VERSION)
6194 {
51ed9ec9 6195 uint64_t nonce = 0;
93e447b6
JG
6196 vRecv >> nonce;
6197 // Echo the message back with the nonce. This allows for two useful features:
6198 //
6199 // 1) A remote node can quickly check if the connection is operational
6200 // 2) Remote nodes can measure the latency of the network thread. If this node
6201 // is overloaded it won't respond to pings quickly and the remote node can
6202 // avoid sending us more work, like chain download requests.
6203 //
6204 // The nonce stops the remote getting confused between different pings: without
6205 // it, if the remote node sends a ping once per second and this node takes 5
6206 // seconds to respond to each, the 5th ping the remote sends would appear to
6207 // return very quickly.
6208 pfrom->PushMessage("pong", nonce);
6209 }
0a61b0df 6210 }
8d655683 6211
6212
971bb3e9
JL
6213 else if (strCommand == "pong")
6214 {
9f4da19b 6215 int64_t pingUsecEnd = nTimeReceived;
51ed9ec9 6216 uint64_t nonce = 0;
971bb3e9
JL
6217 size_t nAvail = vRecv.in_avail();
6218 bool bPingFinished = false;
6219 std::string sProblem;
8d655683 6220
971bb3e9
JL
6221 if (nAvail >= sizeof(nonce)) {
6222 vRecv >> nonce;
8d655683 6223
971bb3e9
JL
6224 // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
6225 if (pfrom->nPingNonceSent != 0) {
6226 if (nonce == pfrom->nPingNonceSent) {
6227 // Matching pong received, this ping is no longer outstanding
6228 bPingFinished = true;
51ed9ec9 6229 int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
971bb3e9
JL
6230 if (pingUsecTime > 0) {
6231 // Successful ping time measurement, replace previous
6232 pfrom->nPingUsecTime = pingUsecTime;
e279e5f9 6233 pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
971bb3e9
JL
6234 } else {
6235 // This should never happen
6236 sProblem = "Timing mishap";
6237 }
6238 } else {
6239 // Nonce mismatches are normal when pings are overlapping
6240 sProblem = "Nonce mismatch";
6241 if (nonce == 0) {
7e6d23b1 6242 // This is most likely a bug in another implementation somewhere; cancel this ping
971bb3e9
JL
6243 bPingFinished = true;
6244 sProblem = "Nonce zero";
6245 }
6246 }
6247 } else {
6248 sProblem = "Unsolicited pong without ping";
6249 }
6250 } else {
7e6d23b1 6251 // This is most likely a bug in another implementation somewhere; cancel this ping
971bb3e9
JL
6252 bPingFinished = true;
6253 sProblem = "Short payload";
6254 }
8d655683 6255
971bb3e9 6256 if (!(sProblem.empty())) {
2e36866f 6257 LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
8d655683 6258 pfrom->id,
6259 pfrom->cleanSubVer,
6260 sProblem,
6261 pfrom->nPingNonceSent,
6262 nonce,
6263 nAvail);
971bb3e9
JL
6264 }
6265 if (bPingFinished) {
6266 pfrom->nPingNonceSent = 0;
6267 }
6268 }
8d655683 6269
6270
4d9c7fe6 6271 else if (fAlerts && strCommand == "alert")
0a61b0df 6272 {
6273 CAlert alert;
6274 vRecv >> alert;
8d655683 6275
d5a52d9b
GA
6276 uint256 alertHash = alert.GetHash();
6277 if (pfrom->setKnown.count(alertHash) == 0)
0a61b0df 6278 {
f14e687f 6279 if (alert.ProcessAlert(Params().AlertKey()))
f8dcd5ca 6280 {
d5a52d9b
GA
6281 // Relay
6282 pfrom->setKnown.insert(alertHash);
6283 {
6284 LOCK(cs_vNodes);
6285 BOOST_FOREACH(CNode* pnode, vNodes)
8d655683 6286 alert.RelayTo(pnode);
d5a52d9b
GA
6287 }
6288 }
6289 else {
6290 // Small DoS penalty so peers that send us lots of
6291 // duplicate/expired/invalid-signature/whatever alerts
6292 // eventually get banned.
6293 // This isn't a Misbehaving(100) (immediate ban) because the
6294 // peer might be an older or different implementation with
6295 // a different signature key, etc.
b2864d2f 6296 Misbehaving(pfrom->GetId(), 10);
f8dcd5ca 6297 }
0a61b0df 6298 }
6299 }
8d655683 6300
6301
422d1225
MC
6302 else if (strCommand == "filterload")
6303 {
6304 CBloomFilter filter;
6305 vRecv >> filter;
8d655683 6306
422d1225
MC
6307 if (!filter.IsWithinSizeConstraints())
6308 // There is no excuse for sending a too-large filter
b2864d2f 6309 Misbehaving(pfrom->GetId(), 100);
422d1225
MC
6310 else
6311 {
6312 LOCK(pfrom->cs_filter);
6313 delete pfrom->pfilter;
6314 pfrom->pfilter = new CBloomFilter(filter);
a7f533a9 6315 pfrom->pfilter->UpdateEmptyFull();
422d1225 6316 }
4c8fc1a5 6317 pfrom->fRelayTxes = true;
422d1225 6318 }
8d655683 6319
6320
422d1225
MC
6321 else if (strCommand == "filteradd")
6322 {
6323 vector<unsigned char> vData;
6324 vRecv >> vData;
8d655683 6325
422d1225
MC
6326 // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
6327 // and thus, the maximum size any matched object can have) in a filteradd message
192cc910 6328 if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
422d1225 6329 {
b2864d2f 6330 Misbehaving(pfrom->GetId(), 100);
422d1225
MC
6331 } else {
6332 LOCK(pfrom->cs_filter);
6333 if (pfrom->pfilter)
6334 pfrom->pfilter->insert(vData);
6335 else
b2864d2f 6336 Misbehaving(pfrom->GetId(), 100);
422d1225
MC
6337 }
6338 }
8d655683 6339
6340
422d1225
MC
6341 else if (strCommand == "filterclear")
6342 {
6343 LOCK(pfrom->cs_filter);
6344 delete pfrom->pfilter;
37c6389c 6345 pfrom->pfilter = new CBloomFilter();
4c8fc1a5 6346 pfrom->fRelayTxes = true;
422d1225 6347 }
8d655683 6348
6349
358ce266
GA
6350 else if (strCommand == "reject")
6351 {
efad808a
PW
6352 if (fDebug) {
6353 try {
6354 string strMsg; unsigned char ccode; string strReason;
307f7d48 6355 vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
8d655683 6356
efad808a
PW
6357 ostringstream ss;
6358 ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
8d655683 6359
efad808a
PW
6360 if (strMsg == "block" || strMsg == "tx")
6361 {
6362 uint256 hash;
6363 vRecv >> hash;
6364 ss << ": hash " << hash.ToString();
6365 }
6366 LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
27df4123 6367 } catch (const std::ios_base::failure&) {
efad808a
PW
6368 // Avoid feedback loops by preventing reject messages from triggering a new reject message.
6369 LogPrint("net", "Unparseable reject message received\n");
358ce266 6370 }
358ce266
GA
6371 }
6372 }
432bc22a 6373 else if (strCommand == "notfound") {
e496b2e3
WL
6374 // We do not care about the NOTFOUND message, but logging an Unknown Command
6375 // message would be undesirable as we transmit it ourselves.
6376 }
8d655683 6377
e496b2e3 6378 else {
0a61b0df 6379 // Ignore unknown commands for extensibility
6ecf3edf 6380 LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
0a61b0df 6381 }
8d655683 6382
6383
6384
0a61b0df 6385 return true;
6386}
6387
607dbfde 6388// requires LOCK(cs_vRecvMsg)
e89b9f6a
PW
6389bool ProcessMessages(CNode* pfrom)
6390{
e89b9f6a 6391 //if (fDebug)
30c1db1c 6392 // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
8d655683 6393
e89b9f6a
PW
6394 //
6395 // Message format
6396 // (4) message start
6397 // (12) command
6398 // (4) size
6399 // (4) checksum
6400 // (x) data
6401 //
967f2459 6402 bool fOk = true;
8d655683 6403
c7f039b6
PW
6404 if (!pfrom->vRecvGetData.empty())
6405 ProcessGetData(pfrom);
8d655683 6406
75ef87dd
PS
6407 // this maintains the order of responses
6408 if (!pfrom->vRecvGetData.empty()) return fOk;
8d655683 6409
967f2459 6410 std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
41b052ad 6411 while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
9d6cd04b 6412 // Don't bother if send buffer is too full to respond anyway
41b052ad 6413 if (pfrom->nSendSize >= SendBufferSize())
9d6cd04b 6414 break;
8d655683 6415
967f2459
PW
6416 // get next message
6417 CNetMessage& msg = *it;
8d655683 6418
607dbfde 6419 //if (fDebug)
30c1db1c 6420 // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
607dbfde
JG
6421 // msg.hdr.nMessageSize, msg.vRecv.size(),
6422 // msg.complete() ? "Y" : "N");
8d655683 6423
967f2459 6424 // end, if an incomplete message is found
607dbfde 6425 if (!msg.complete())
e89b9f6a 6426 break;
8d655683 6427
967f2459
PW
6428 // at this point, any failure means we can delete the current message
6429 it++;
8d655683 6430
607dbfde 6431 // Scan for message start
0e4b3175 6432 if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
28d4cff0 6433 LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
967f2459
PW
6434 fOk = false;
6435 break;
e89b9f6a 6436 }
8d655683 6437
e89b9f6a 6438 // Read header
607dbfde 6439 CMessageHeader& hdr = msg.hdr;
eec37136 6440 if (!hdr.IsValid(Params().MessageStart()))
e89b9f6a 6441 {
28d4cff0 6442 LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
e89b9f6a
PW
6443 continue;
6444 }
6445 string strCommand = hdr.GetCommand();
8d655683 6446
e89b9f6a
PW
6447 // Message size
6448 unsigned int nMessageSize = hdr.nMessageSize;
8d655683 6449
e89b9f6a 6450 // Checksum
607dbfde 6451 CDataStream& vRecv = msg.vRecv;
18c0fa97 6452 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
556814ec 6453 unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
18c0fa97 6454 if (nChecksum != hdr.nChecksum)
e89b9f6a 6455 {
30c1db1c 6456 LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
8d655683 6457 SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
18c0fa97 6458 continue;
e89b9f6a 6459 }
8d655683 6460
e89b9f6a
PW
6461 // Process message
6462 bool fRet = false;
6463 try
6464 {
9f4da19b 6465 fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
b31499ec 6466 boost::this_thread::interruption_point();
e89b9f6a 6467 }
27df4123 6468 catch (const std::ios_base::failure& e)
e89b9f6a 6469 {
358ce266 6470 pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
e89b9f6a
PW
6471 if (strstr(e.what(), "end of data"))
6472 {
814efd6f 6473 // Allow exceptions from under-length message on vRecv
30c1db1c 6474 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
6475 }
6476 else if (strstr(e.what(), "size too large"))
6477 {
814efd6f 6478 // Allow exceptions from over-long size
30c1db1c 6479 LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
e89b9f6a
PW
6480 }
6481 else
6482 {
5970a0d7 6483 //PrintExceptionContinue(&e, "ProcessMessages()");
e89b9f6a
PW
6484 }
6485 }
27df4123 6486 catch (const boost::thread_interrupted&) {
b31499ec
GA
6487 throw;
6488 }
27df4123 6489 catch (const std::exception& e) {
ea591ead 6490 PrintExceptionContinue(&e, "ProcessMessages()");
e89b9f6a 6491 } catch (...) {
ea591ead 6492 PrintExceptionContinue(NULL, "ProcessMessages()");
e89b9f6a 6493 }
8d655683 6494
e89b9f6a 6495 if (!fRet)
30c1db1c 6496 LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
8d655683 6497
75ef87dd 6498 break;
e89b9f6a 6499 }
8d655683 6500
41b052ad
PW
6501 // In case the connection got shut down, its receive buffer was wiped
6502 if (!pfrom->fDisconnect)
6503 pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
8d655683 6504
967f2459 6505 return fOk;
e89b9f6a 6506}
0a61b0df 6507
6508
0a61b0df 6509bool SendMessages(CNode* pto, bool fSendTrickle)
6510{
e8e8904d 6511 const Consensus::Params& consensusParams = Params().GetConsensus();
6055b910 6512 {
b05a89b2 6513 // Don't send anything until we get its version message
0a61b0df 6514 if (pto->nVersion == 0)
6515 return true;
8d655683 6516
971bb3e9
JL
6517 //
6518 // Message: ping
6519 //
6520 bool pingSend = false;
6521 if (pto->fPingQueued) {
6522 // RPC ping request by user
6523 pingSend = true;
6524 }
f1920e86
PW
6525 if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
6526 // Ping automatically sent as a latency probe & keepalive.
971bb3e9
JL
6527 pingSend = true;
6528 }
6529 if (pingSend) {
51ed9ec9 6530 uint64_t nonce = 0;
971bb3e9 6531 while (nonce == 0) {
001a53d7 6532 GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
971bb3e9 6533 }
971bb3e9 6534 pto->fPingQueued = false;
f1920e86 6535 pto->nPingUsecStart = GetTimeMicros();
971bb3e9 6536 if (pto->nVersion > BIP0031_VERSION) {
f1920e86 6537 pto->nPingNonceSent = nonce;
c971112d 6538 pto->PushMessage("ping", nonce);
971bb3e9 6539 } else {
f1920e86
PW
6540 // Peer is too old to support ping command with nonce, pong will never arrive.
6541 pto->nPingNonceSent = 0;
93e447b6 6542 pto->PushMessage("ping");
971bb3e9 6543 }
93e447b6 6544 }
8d655683 6545
55a1db4f
WL
6546 TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
6547 if (!lockMain)
6548 return true;
8d655683 6549
0a61b0df 6550 // Address refresh broadcast
51ed9ec9 6551 static int64_t nLastRebroadcast;
5d1b8f17 6552 if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
0a61b0df 6553 {
845c86d1
GM
6554 LOCK(cs_vNodes);
6555 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 6556 {
d81cff32 6557 // Periodically clear addrKnown to allow refresh broadcasts
845c86d1 6558 if (nLastRebroadcast)
83671efe 6559 pnode->addrKnown.reset();
8d655683 6560
845c86d1
GM
6561 // Rebroadcast our address
6562 AdvertizeLocal(pnode);
0a61b0df 6563 }
845c86d1
GM
6564 if (!vNodes.empty())
6565 nLastRebroadcast = GetTime();
0a61b0df 6566 }
8d655683 6567
0a61b0df 6568 //
6569 // Message: addr
6570 //
6571 if (fSendTrickle)
6572 {
6573 vector<CAddress> vAddr;
6574 vAddr.reserve(pto->vAddrToSend.size());
223b6f1b 6575 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
0a61b0df 6576 {
d81cff32 6577 if (!pto->addrKnown.contains(addr.GetKey()))
0a61b0df 6578 {
d81cff32 6579 pto->addrKnown.insert(addr.GetKey());
0a61b0df 6580 vAddr.push_back(addr);
6581 // receiver rejects addr messages larger than 1000
6582 if (vAddr.size() >= 1000)
6583 {
6584 pto->PushMessage("addr", vAddr);
6585 vAddr.clear();
6586 }
6587 }
6588 }
6589 pto->vAddrToSend.clear();
6590 if (!vAddr.empty())
6591 pto->PushMessage("addr", vAddr);
6592 }
8d655683 6593
75f51f2a
PW
6594 CNodeState &state = *State(pto->GetId());
6595 if (state.fShouldBan) {
dc942e6f
PW
6596 if (pto->fWhitelisted)
6597 LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
b2864d2f
PW
6598 else {
6599 pto->fDisconnect = true;
dc942e6f
PW
6600 if (pto->addr.IsLocal())
6601 LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
6602 else
c74332c6 6603 {
dc942e6f 6604 CNode::Ban(pto->addr);
c74332c6 6605 }
b2864d2f 6606 }
75f51f2a 6607 state.fShouldBan = false;
b2864d2f 6608 }
8d655683 6609
75f51f2a 6610 BOOST_FOREACH(const CBlockReject& reject, state.rejects)
8d655683 6611 pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
75f51f2a 6612 state.rejects.clear();
8d655683 6613
6055b910 6614 // Start block sync
341735eb
PW
6615 if (pindexBestHeader == NULL)
6616 pindexBestHeader = chainActive.Tip();
b4ee0bdd 6617 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 6618 if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
341735eb 6619 // Only actively request headers from a single peer, unless we're close to today.
00dcaf4b 6620 if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
341735eb
PW
6621 state.fSyncStarted = true;
6622 nSyncStarted++;
6623 CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
4c933229 6624 LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
4f152496 6625 pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
341735eb 6626 }
6055b910 6627 }
8d655683 6628
6055b910
PW
6629 // Resend wallet transactions that haven't gotten in a block yet
6630 // Except during reindex, importing and IBD, when old wallet
6631 // transactions become unconfirmed and spams other nodes.
6632 if (!fReindex && !fImporting && !IsInitialBlockDownload())
6633 {
0f5954c4 6634 GetMainSignals().Broadcast(nTimeBestReceived);
6055b910 6635 }
8d655683 6636
0a61b0df 6637 //
6638 // Message: inventory
6639 //
6640 vector<CInv> vInv;
6641 vector<CInv> vInvWait;
0a61b0df 6642 {
f8dcd5ca 6643 LOCK(pto->cs_inventory);
0a61b0df 6644 vInv.reserve(pto->vInventoryToSend.size());
6645 vInvWait.reserve(pto->vInventoryToSend.size());
223b6f1b 6646 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
0a61b0df 6647 {
6648 if (pto->setInventoryKnown.count(inv))
6649 continue;
8d655683 6650
0a61b0df 6651 // trickle out tx inv to protect privacy
6652 if (inv.type == MSG_TX && !fSendTrickle)
6653 {
6654 // 1/4 of tx invs blast to all immediately
6655 static uint256 hashSalt;
4f152496 6656 if (hashSalt.IsNull())
f718aedd 6657 hashSalt = GetRandHash();
734f85c4 6658 uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
0a61b0df 6659 hashRand = Hash(BEGIN(hashRand), END(hashRand));
734f85c4 6660 bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
8d655683 6661
0a61b0df 6662 if (fTrickleWait)
6663 {
6664 vInvWait.push_back(inv);
6665 continue;
6666 }
6667 }
8d655683 6668
0a61b0df 6669 // returns true if wasn't already contained in the set
6670 if (pto->setInventoryKnown.insert(inv).second)
6671 {
6672 vInv.push_back(inv);
6673 if (vInv.size() >= 1000)
6674 {
6675 pto->PushMessage("inv", vInv);
6676 vInv.clear();
6677 }
6678 }
6679 }
6680 pto->vInventoryToSend = vInvWait;
6681 }
6682 if (!vInv.empty())
6683 pto->PushMessage("inv", vInv);
8d655683 6684
341735eb 6685 // Detect whether we're stalling
f59d8f0b 6686 int64_t nNow = GetTimeMicros();
341735eb
PW
6687 if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
6688 // Stalling only triggers when the block download window cannot move. During normal steady state,
6689 // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
6690 // should only happen during initial block download.
6691 LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
f59d8f0b
PW
6692 pto->fDisconnect = true;
6693 }
3ff735c9 6694 // 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
6695 // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
6696 // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
7e6d23b1 6697 // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
91613034 6698 // to unreasonably increase our timeout.
8ba7f842
SD
6699 // We also compare the block download timeout originally calculated against the time at which we'd disconnect
6700 // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
6701 // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
6702 // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
6703 // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
6704 if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
6705 QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
82737933 6706 int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
8ba7f842
SD
6707 if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
6708 LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
6709 queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
6710 }
6711 if (queuedBlock.nTimeDisconnect < nNow) {
6712 LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
6713 pto->fDisconnect = true;
6714 }
91613034 6715 }
8d655683 6716
0a61b0df 6717 //
f59d8f0b 6718 // Message: getdata (blocks)
0a61b0df 6719 //
161f617d 6720 static uint256 zero;
0a61b0df 6721 vector<CInv> vGetData;
00dcaf4b 6722 if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
341735eb
PW
6723 vector<CBlockIndex*> vToDownload;
6724 NodeId staller = -1;
6725 FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
6726 BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
6727 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
82737933 6728 MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
1af838b3 6729 LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
8d655683 6730 pindex->nHeight, pto->id);
341735eb
PW
6731 }
6732 if (state.nBlocksInFlight == 0 && staller != -1) {
1bcee67e 6733 if (State(staller)->nStallingSince == 0) {
341735eb 6734 State(staller)->nStallingSince = nNow;
1bcee67e
B
6735 LogPrint("net", "Stall started peer=%d\n", staller);
6736 }
f59d8f0b
PW
6737 }
6738 }
8d725ab4 6739 /*CBlockIndex *pindex;
bddeaf5e 6740 if ( komodo_requestedhash != zero && komodo_requestedcount < 16 && (pindex= mapBlockIndex[komodo_requestedhash]) != 0 )
161f617d 6741 {
bddeaf5e 6742 LogPrint("net","komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
6743 fprintf(stderr,"komodo_requestedhash.%d request %s to nodeid.%d\n",komodo_requestedcount,komodo_requestedhash.ToString().c_str(),pto->GetId());
161f617d 6744 vGetData.push_back(CInv(MSG_BLOCK, komodo_requestedhash));
6745 MarkBlockAsInFlight(pto->GetId(), komodo_requestedhash, consensusParams, pindex);
bddeaf5e 6746 komodo_requestedcount++;
6747 if ( komodo_requestedcount > 16 )
6748 {
6749 memset(&komodo_requestedhash,0,sizeof(komodo_requestedhash));
6750 komodo_requestedcount = 0;
6751 }
8d725ab4 6752 }*/
161f617d 6753
f59d8f0b
PW
6754 //
6755 // Message: getdata (non-blocks)
6756 //
6757 while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
0a61b0df 6758 {
6759 const CInv& inv = (*pto->mapAskFor.begin()).second;
ae8bfd12 6760 if (!AlreadyHave(inv))
0a61b0df 6761 {
3b570559 6762 if (fDebug)
2e36866f 6763 LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
0a61b0df 6764 vGetData.push_back(inv);
6765 if (vGetData.size() >= 1000)
6766 {
6767 pto->PushMessage("getdata", vGetData);
6768 vGetData.clear();
6769 }
e2190f80
GM
6770 } else {
6771 //If we're not going to ask, don't expect a response.
6772 pto->setAskFor.erase(inv.hash);
0a61b0df 6773 }
6774 pto->mapAskFor.erase(pto->mapAskFor.begin());
6775 }
6776 if (!vGetData.empty())
6777 pto->PushMessage("getdata", vGetData);
8d655683 6778
0a61b0df 6779 }
6780 return true;
6781}
6782
8d655683 6783std::string CBlockFileInfo::ToString() const {
6784 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));
6785}
0a61b0df 6786
6787
6788
3427517d
PW
6789class CMainCleanup
6790{
6791public:
6792 CMainCleanup() {}
6793 ~CMainCleanup() {
6794 // block headers
145d5be8 6795 BlockMap::iterator it1 = mapBlockIndex.begin();
3427517d
PW
6796 for (; it1 != mapBlockIndex.end(); it1++)
6797 delete (*it1).second;
6798 mapBlockIndex.clear();
8d655683 6799
3427517d 6800 // orphan transactions
3427517d 6801 mapOrphanTransactions.clear();
c74332c6 6802 mapOrphanTransactionsByPrev.clear();
3427517d
PW
6803 }
6804} instance_of_cmaincleanup;
431cce98 6805
431cce98 6806extern "C" const char* getDataDir()
6807{
8d655683 6808 return GetDataDir().string().c_str();
431cce98 6809}
6810
072099d7
S
6811
6812// Set default values of new CMutableTransaction based on consensus rules at given height.
6813CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight)
6814{
6815 CMutableTransaction mtx;
8d655683 6816
072099d7
S
6817 bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER);
6818 if (isOverwintered) {
6819 mtx.fOverwintered = true;
6820 mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID;
6821 mtx.nVersion = 3;
6822 // Expiry height is not set. Only fields required for a parser to treat as a valid Overwinter V3 tx.
8d655683 6823
072099d7
S
6824 // TODO: In future, when moving from Overwinter to Sapling, it will be useful
6825 // to set the expiry height to: min(activation_height - 1, default_expiry_height)
6826 }
6827 return mtx;
6828}
This page took 2.589816 seconds and 4 git commands to generate.