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