Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2015 The Bitcoin developers
3 : // Copyright (c) 2014-2015 The Dash developers
4 : // Copyright (c) 2011-2013 The PPCoin developers
5 : // Copyright (c) 2013-2014 The NovaCoin Developers
6 : // Copyright (c) 2014-2018 The BlackCoin Developers
7 : // Copyright (c) 2015-2022 The PIVX Core developers
8 : // Distributed under the MIT software license, see the accompanying
9 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
10 :
11 : #include "validation.h"
12 :
13 : #include "addrman.h"
14 : #include "blocksignature.h"
15 : #include "budget/budgetmanager.h"
16 : #include "chainparams.h"
17 : #include "checkpoints.h"
18 : #include "checkqueue.h"
19 : #include "consensus/consensus.h"
20 : #include "consensus/merkle.h"
21 : #include "consensus/tx_verify.h"
22 : #include "consensus/validation.h"
23 : #include "consensus/zerocoin_verify.h"
24 : #include "evo/evodb.h"
25 : #include "evo/specialtx_validation.h"
26 : #include "flatfile.h"
27 : #include "guiinterface.h"
28 : #include "interfaces/handler.h"
29 : #include "invalid.h"
30 : #include "kernel.h"
31 : #include "legacy/validation_zerocoin_legacy.h"
32 : #include "llmq/quorums_chainlocks.h"
33 : #include "masternode-payments.h"
34 : #include "masternodeman.h"
35 : #include "policy/policy.h"
36 : #include "pow.h"
37 : #include "reverse_iterate.h"
38 : #include "script/sigcache.h"
39 : #include "shutdown.h"
40 : #include "spork.h"
41 : #include "sporkdb.h"
42 : #include "tiertwo/tiertwo_sync_state.h"
43 : #include "txdb.h"
44 : #include "undo.h"
45 : #include "util/blockstatecatcher.h"
46 : #include "util/system.h"
47 : #include "util/validation.h"
48 : #include "utilmoneystr.h"
49 : #include "validationinterface.h"
50 : #include "warnings.h"
51 : #include "zpiv/zpivmodule.h"
52 :
53 : #include <future>
54 :
55 : #include <boost/algorithm/string/replace.hpp>
56 : #include <boost/thread.hpp>
57 : #include <atomic>
58 : #include <queue>
59 :
60 :
61 : #if defined(NDEBUG)
62 : #error "PIVX cannot be compiled without assertions."
63 : #endif
64 :
65 : /**
66 : * Global state
67 : */
68 :
69 :
70 : /**
71 : * Mutex to guard access to validation specific variables, such as reading
72 : * or changing the chainstate.
73 : *
74 : * This may also need to be locked when updating the transaction pool, e.g. on
75 : * AcceptToMemoryPool. See CTxMemPool::cs comment for details.
76 : *
77 : * The transaction pool has a separate lock to allow reading from it and the
78 : * chainstate at the same time.
79 : */
80 : RecursiveMutex cs_main;
81 :
82 : BlockMap mapBlockIndex;
83 : PrevBlockMap mapPrevBlockIndex;
84 : CChain chainActive;
85 : CBlockIndex* pindexBestHeader = nullptr;
86 :
87 : // Best block section
88 : Mutex g_best_block_mutex;
89 : std::condition_variable g_best_block_cv;
90 : uint256 g_best_block;
91 : int64_t g_best_block_time = 0;
92 :
93 : int nScriptCheckThreads = 0;
94 : std::atomic<bool> fImporting{false};
95 : std::atomic<bool> fReindex{false};
96 : bool fTxIndex = true;
97 : bool fRequireStandard = true;
98 : bool fCheckBlockIndex = false;
99 : size_t nCoinCacheUsage = 5000 * 300;
100 :
101 : /* If the tip is older than this (in seconds), the node is considered to be in initial block download. */
102 : int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
103 :
104 : /** Fees smaller than this (in upiv) are considered zero fee (for relaying, mining and transaction creation)
105 : * We are ~100 times smaller then bitcoin now (2015-06-23), set minRelayTxFee only 10 times higher
106 : * so it's still 10 times lower comparing to bitcoin.
107 : */
108 : CFeeRate minRelayTxFee = CFeeRate(10000);
109 :
110 : CTxMemPool mempool(::minRelayTxFee);
111 :
112 : std::map<uint256, int64_t> mapRejectedBlocks;
113 :
114 : CMoneySupply MoneySupply;
115 :
116 : static void CheckBlockIndex();
117 :
118 : /** Constant stuff for coinbase transactions we create: */
119 : CScript COINBASE_FLAGS;
120 :
121 : // Internal stuff
122 : namespace
123 : {
124 : struct CBlockIndexWorkComparator {
125 95627680 : bool operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
126 : {
127 : // First sort by most total work, ...
128 95627680 : if (pa->nChainWork > pb->nChainWork) return false;
129 63563720 : if (pa->nChainWork < pb->nChainWork) return true;
130 :
131 : // ... then by earliest time received, ...
132 497686 : if (pa->nSequenceId < pb->nSequenceId) return false;
133 497018 : if (pa->nSequenceId > pb->nSequenceId) return true;
134 :
135 : // Use pointer address as tie breaker (should only happen with blocks
136 : // loaded from disk, as those all have id 0).
137 496556 : if (pa < pb) return false;
138 496451 : if (pa > pb) return true;
139 :
140 : // Identical blocks.
141 : return false;
142 : }
143 : };
144 :
145 : CBlockIndex* pindexBestInvalid;
146 :
147 : /**
148 : * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
149 : * as good as our current tip or better. Entries may be failed, though.
150 : */
151 : std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
152 :
153 : /**
154 : * the ChainState Mutex
155 : * A lock that must be held when modifying this ChainState - held in ActivateBestChain()
156 : */
157 : Mutex m_cs_chainstate;
158 :
159 : /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */
160 : std::multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
161 :
162 : RecursiveMutex cs_LastBlockFile;
163 : std::vector<CBlockFileInfo> vinfoBlockFile;
164 : int nLastBlockFile = 0;
165 :
166 : /**
167 : * Every received block is assigned a unique and increasing identifier, so we
168 : * know which one to give priority in case of a fork.
169 : */
170 : RecursiveMutex cs_nBlockSequenceId;
171 : /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
172 : uint32_t nBlockSequenceId = 1;
173 :
174 : /** Dirty block index entries. */
175 : std::set<CBlockIndex*> setDirtyBlockIndex;
176 :
177 : /** Dirty block file entries. */
178 : std::set<int> setDirtyFileInfo;
179 : } // anon namespace
180 :
181 1531 : CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
182 : {
183 1531 : AssertLockHeld(cs_main);
184 : // Find the first block the caller has in the main chain
185 2872 : for (const uint256& hash : locator.vHave) {
186 2571 : CBlockIndex* pindex = LookupBlockIndex(hash);
187 3874 : if (pindex && chain.Contains(pindex)) {
188 1230 : return pindex;
189 : }
190 : }
191 301 : return chain.Genesis();
192 : }
193 :
194 1055 : CBlockIndex* GetChainTip()
195 : {
196 2110 : LOCK(cs_main);
197 2110 : CBlockIndex* p = chainActive.Tip();
198 1055 : if (!p)
199 : return nullptr;
200 : // Do not pass in the chain active tip, because it can change.
201 : // Instead pass the blockindex directly from mapblockindex, which is const
202 1055 : return mapBlockIndex.at(p->GetBlockHash());
203 : }
204 :
205 : std::unique_ptr<CCoinsViewDB> pcoinsdbview;
206 : std::unique_ptr<CCoinsViewCache> pcoinsTip;
207 : std::unique_ptr<CBlockTreeDB> pblocktree;
208 : std::unique_ptr<CZerocoinDB> zerocoinDB;
209 : std::unique_ptr<CSporkDB> pSporkDB;
210 : std::unique_ptr<AccumulatorCache> accumulatorCache;
211 :
212 : enum FlushStateMode {
213 : FLUSH_STATE_NONE,
214 : FLUSH_STATE_IF_NEEDED,
215 : FLUSH_STATE_PERIODIC,
216 : FLUSH_STATE_ALWAYS
217 : };
218 :
219 : // See definition for documentation
220 : bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode);
221 : static FlatFileSeq BlockFileSeq();
222 : static FlatFileSeq UndoFileSeq();
223 :
224 1222375 : bool CheckFinalTx(const CTransactionRef& tx, int flags)
225 : {
226 1222375 : AssertLockHeld(cs_main);
227 :
228 : // By convention a negative value for flags indicates that the
229 : // current network-enforced consensus rules should be used. In
230 : // a future soft-fork scenario that would mean checking which
231 : // rules would be enforced for the next block and setting the
232 : // appropriate flags. At the present time no soft-forks are
233 : // scheduled, so no flags are set.
234 1222375 : flags = std::max(flags, 0);
235 :
236 : // CheckFinalTx() uses chainActive.Height()+1 to evaluate
237 : // nLockTime because when IsFinalTx() is called within
238 : // CBlock::AcceptBlock(), the height of the block *being*
239 : // evaluated is what is used. Thus if we want to know if a
240 : // transaction can be part of the *next* block, we need to call
241 : // IsFinalTx() with one more than chainActive.Height().
242 1222375 : const int nBlockHeight = chainActive.Height() + 1;
243 :
244 : // BIP113 will require that time-locked transactions have nLockTime set to
245 : // less than the median time of the previous block they're contained in.
246 : // When the next block is created its previous block will be the current
247 : // chain tip, so we use that to calculate the median time passed to
248 : // IsFinalTx() if LOCKTIME_MEDIAN_TIME_PAST is set.
249 1460757 : const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST) ? chainActive.Tip()->GetMedianTimePast() : GetAdjustedTime();
250 :
251 1222375 : return IsFinalTx(tx, nBlockHeight, nBlockTime);
252 : }
253 :
254 119499 : void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) {
255 119499 : int expired = pool.Expire(GetTime() - age);
256 119499 : if (expired != 0)
257 0 : LogPrint(BCLog::MEMPOOL, "Expired %i transactions from the memory pool\n", expired);
258 :
259 119499 : std::vector<COutPoint> vNoSpendsRemaining;
260 119499 : pool.TrimToSize(limit, &vNoSpendsRemaining);
261 119499 : for (const COutPoint& removed: vNoSpendsRemaining)
262 0 : pcoinsTip->Uncache(removed);
263 119499 : }
264 :
265 171155 : CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, unsigned int nBytes)
266 : {
267 171155 : if (tx.IsShieldedTx()) {
268 2179 : return GetShieldedTxMinFee(tx);
269 : }
270 168976 : uint256 hash = tx.GetHash();
271 168976 : CAmount nFeeDelta = 0;
272 168976 : pool.ApplyDelta(hash, nFeeDelta);
273 168976 : if (nFeeDelta > 0)
274 : return 0;
275 :
276 168975 : return GetMinRelayFee(nBytes);
277 : }
278 :
279 272026 : CAmount GetMinRelayFee(unsigned int nBytes)
280 : {
281 272026 : CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
282 272026 : if (!Params().GetConsensus().MoneyRange(nMinFee)) {
283 0 : nMinFee = Params().GetConsensus().nMaxMoneyOut;
284 : }
285 272026 : return nMinFee;
286 : }
287 :
288 5397 : CAmount GetShieldedTxMinFee(const CTransaction& tx)
289 : {
290 5397 : assert (tx.IsShieldedTx());
291 5397 : unsigned int K = DEFAULT_SHIELDEDTXFEE_K; // Fixed (100) for now
292 5397 : CAmount nMinFee = ::minRelayTxFee.GetFee(tx.GetTotalSize()) * K;
293 5397 : if (!Params().GetConsensus().MoneyRange(nMinFee))
294 0 : nMinFee = Params().GetConsensus().nMaxMoneyOut;
295 5397 : return nMinFee;
296 : }
297 :
298 : /* Make mempool consistent after a reorg, by re-adding or recursively erasing
299 : * disconnected block transactions from the mempool, and also removing any
300 : * other transactions from the mempool that are no longer valid given the new
301 : * tip/height.
302 : *
303 : * Note: we assume that disconnectpool only contains transactions that are NOT
304 : * confirmed in the current chain nor already in the mempool (otherwise,
305 : * in-mempool descendants of such transactions would be removed).
306 : *
307 : * Passing fAddToMempool=false will skip trying to add the transactions back,
308 : * and instead just erase from the mempool as needed.
309 : */
310 :
311 66 : static void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
312 : {
313 66 : AssertLockHeld(cs_main);
314 66 : AssertLockHeld(mempool.cs);
315 66 : std::vector<uint256> vHashUpdate;
316 : // disconnectpool's insertion_order index sorts the entries from
317 : // oldest to newest, but the oldest entry will be the last tx from the
318 : // latest mined block that was disconnected.
319 : // Iterate disconnectpool in reverse, so that we add transactions
320 : // back to the mempool starting with the earliest transaction that had
321 : // been previously seen in a block.
322 66 : auto it = disconnectpool.queuedTx.get<insertion_order>().rbegin();
323 58841 : while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
324 : // if we are resurrecting a ProReg tx, we need to evict any special transaction that
325 : // depends on it (which would not be accepted in the mempool, with the current chain)
326 117550 : if ((*it)->IsProRegTx()) {
327 8 : mempool.removeProTxReferences((*it)->GetHash(), MemPoolRemovalReason::REORG);
328 : }
329 : // ignore validation errors in resurrected transactions
330 58775 : CValidationState stateDummy;
331 234501 : if (!fAddToMempool || (*it)->IsCoinBase() || (*it)->IsCoinStake() ||
332 58461 : !AcceptToMemoryPool(mempool, stateDummy, *it, false, nullptr, true)) {
333 : // If the transaction doesn't make it in to the mempool, remove any
334 : // transactions that depend on it (which would now be orphans).
335 14164 : mempool.removeRecursive(**it, MemPoolRemovalReason::REORG);
336 103386 : } else if (mempool.exists((*it)->GetHash())) {
337 103386 : vHashUpdate.emplace_back((*it)->GetHash());
338 : }
339 117550 : ++it;
340 : }
341 66 : disconnectpool.queuedTx.clear();
342 : // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have
343 : // no in-mempool children, which is generally not true when adding
344 : // previously-confirmed transactions back to the mempool.
345 : // UpdateTransactionsFromBlock finds descendants of any transactions in
346 : // the disconnectpool that were added back and cleans up the mempool state.
347 66 : mempool.UpdateTransactionsFromBlock(vHashUpdate);
348 :
349 : // We also need to remove any now-immature transactions
350 132 : mempool.removeForReorg(pcoinsTip.get(), chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
351 : // Re-limit mempool size, in case we added any transactions
352 198 : LimitMempoolSize(mempool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
353 132 : gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
354 66 : }
355 :
356 171131 : static bool IsCurrentForFeeEstimation()
357 : {
358 171131 : AssertLockHeld(cs_main);
359 171131 : if (IsInitialBlockDownload())
360 : return false;
361 342132 : if (chainActive.Tip()->GetBlockTime() < (GetTime() - MAX_FEE_ESTIMATION_TIP_AGE))
362 : return false;
363 170975 : if (chainActive.Height() < pindexBestHeader->nHeight - 1)
364 51597 : return false;
365 : return true;
366 : }
367 :
368 178071 : static bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransactionRef& _tx, bool fLimitFree,
369 : bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool ignoreFees,
370 : std::vector<COutPoint>& coins_to_uncache) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
371 : {
372 178071 : AssertLockHeld(cs_main);
373 178071 : const CTransaction& tx = *_tx;
374 :
375 : // Coinbase is only valid in a block, not as a loose transaction
376 178071 : if (tx.IsCoinBase())
377 0 : return state.DoS(100, false, REJECT_INVALID, "coinbase");
378 :
379 : // Coinstake is also only valid in a block, not as a loose transaction
380 178071 : if (tx.IsCoinStake())
381 0 : return state.DoS(100, false, REJECT_INVALID, "coinstake");
382 :
383 : // LLMQ final commitment too, not valid as a loose transaction
384 178071 : if (tx.IsQuorumCommitmentTx())
385 20 : return state.DoS(100, false, REJECT_INVALID, "llmqcomm");
386 :
387 178061 : if (pfMissingInputs)
388 119580 : *pfMissingInputs = false;
389 :
390 : // Check maintenance mode
391 178061 : if (sporkManager.IsSporkActive(SPORK_20_SAPLING_MAINTENANCE) && tx.IsShieldedTx())
392 3 : return state.DoS(10, error("%s : Shielded transactions are temporarily disabled for maintenance",
393 : __func__), REJECT_INVALID, "bad-tx-sapling-maintenance");
394 :
395 178060 : const CChainParams& params = Params();
396 178060 : const Consensus::Params& consensus = params.GetConsensus();
397 178060 : int chainHeight = chainActive.Height();
398 :
399 : // Check transaction
400 178060 : bool fColdStakingActive = !sporkManager.IsSporkActive(SPORK_19_COLDSTAKING_MAINTENANCE);
401 178060 : if (!CheckTransaction(tx, state, fColdStakingActive))
402 3 : return error("%s : transaction checks for %s failed with %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
403 :
404 178059 : int nextBlockHeight = chainHeight + 1;
405 : // Check transaction contextually against consensus rules at block height
406 178059 : if (!ContextualCheckTransaction(_tx, state, params, nextBlockHeight, false /* isMined */, IsInitialBlockDownload())) {
407 4 : return error("AcceptToMemoryPool: ContextualCheckTransaction failed");
408 : }
409 :
410 178055 : if (pool.existsProviderTxConflict(tx)) {
411 10 : return state.DoS(0, false, REJECT_DUPLICATE, "protx-dup");
412 : }
413 :
414 : // Only accept nLockTime-using transactions that can be mined in the next
415 : // block; we don't want our mempool filled up with transactions that can't
416 : // be mined yet.
417 178050 : if (!CheckFinalTx(_tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
418 4 : return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
419 :
420 : // Rather not work on nonstandard transactions
421 356119 : std::string reason;
422 178048 : if (fRequireStandard && !IsStandardTx(_tx, nextBlockHeight, reason))
423 3 : return state.DoS(0, false, REJECT_NONSTANDARD, reason);
424 : // is it already in the memory pool?
425 178047 : const uint256& hash = tx.GetHash();
426 178047 : if (pool.exists(hash)) {
427 0 : return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool");
428 : }
429 :
430 : // Check for conflicts with in-memory transactions
431 :
432 178047 : {
433 178047 : LOCK(pool.cs); // protect pool.mapNextTx
434 519829 : for (const auto& in : tx.vin) {
435 341783 : COutPoint outpoint = in.prevout;
436 683565 : if (pool.mapNextTx.count(outpoint)) {
437 : // Disable replacement feature for now
438 2 : return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict");
439 : }
440 : }
441 : }
442 :
443 : // Check sapling nullifiers
444 178046 : if (tx.IsShieldedTx()) {
445 2318 : for (const auto& sd : tx.sapData->vShieldedSpend) {
446 138 : if (pool.nullifierExists(sd.nullifier))
447 4 : return state.Invalid(false, REJECT_INVALID, "bad-txns-nullifier-double-spent");
448 : }
449 : }
450 :
451 178044 : {
452 0 : CCoinsView dummy;
453 349173 : CCoinsViewCache view(&dummy);
454 :
455 178044 : CAmount nValueIn = 0;
456 :
457 349173 : LOCK(pool.cs);
458 349173 : CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool);
459 178044 : view.SetBackend(viewMemPool);
460 :
461 : // do we already have it?
462 677592 : for (size_t out = 0; out < tx.vout.size(); out++) {
463 499550 : COutPoint outpoint(hash, out);
464 499550 : bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint);
465 499550 : if (view.HaveCoin(outpoint)) {
466 2 : if (!had_coin_in_cache) {
467 0 : coins_to_uncache.push_back(outpoint);
468 : }
469 4 : return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known");
470 : }
471 : }
472 :
473 : // do all inputs exist?
474 506269 : for (const CTxIn& txin : tx.vin) {
475 335110 : if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
476 38131 : coins_to_uncache.push_back(txin.prevout);
477 : }
478 335110 : if (!view.HaveCoin(txin.prevout)) {
479 6883 : if (pfMissingInputs) {
480 134 : *pfMissingInputs = true;
481 : }
482 6883 : return false; // fMissingInputs and !state.IsInvalid() is used to detect this condition, don't set state.Invalid()
483 : }
484 : }
485 :
486 : // Sapling: are the sapling spends' requirements met in tx(valid anchors/nullifiers)?
487 171159 : if (!view.HaveShieldedRequirements(tx))
488 2 : return state.Invalid(error("AcceptToMemoryPool: shielded requirements not met"),
489 : REJECT_DUPLICATE, "bad-txns-shielded-requirements-not-met");
490 :
491 342316 : if (!CheckSpecialTx(tx, chainActive.Tip(), &view, state)) {
492 : // pass the state returned by the function above
493 : return false;
494 : }
495 :
496 : // Bring the best block into scope
497 171157 : view.GetBestBlock();
498 :
499 171157 : nValueIn = view.GetValueIn(tx);
500 :
501 : // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
502 171157 : view.SetBackend(dummy);
503 :
504 : // Check for non-standard pay-to-script-hash in inputs
505 171157 : if (fRequireStandard && !AreInputsStandard(tx, view))
506 0 : return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs");
507 :
508 : // Check that the transaction doesn't have an excessive number of
509 : // sigops, making it impossible to mine. Since the coinbase transaction
510 : // itself can contain sigops MAX_TX_SIGOPS is less than
511 : // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
512 : // merely non-standard transaction.
513 171157 : unsigned int nSigOps = GetLegacySigOpCount(tx);
514 171157 : unsigned int nMaxSigOps = MAX_TX_SIGOPS_CURRENT;
515 171157 : nSigOps += GetP2SHSigOpCount(tx, view);
516 171157 : if(nSigOps > nMaxSigOps)
517 6 : return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false,
518 4 : strprintf("%d > %d", nSigOps, nMaxSigOps));
519 :
520 171155 : CAmount nValueOut = tx.GetValueOut();
521 171155 : CAmount nFees = nValueIn - nValueOut;
522 171155 : bool fSpendsCoinbaseOrCoinstake = false;
523 :
524 : // Keep track of transactions that spend a coinbase, which we re-scan
525 : // during reorgs to ensure COINBASE_MATURITY is still met.
526 495840 : for (const CTxIn &txin : tx.vin) {
527 327717 : const Coin &coin = view.AccessCoin(txin.prevout);
528 327717 : if (coin.IsCoinBase() || coin.IsCoinStake()) {
529 : fSpendsCoinbaseOrCoinstake = true;
530 : break;
531 : }
532 : }
533 :
534 171155 : CTxMemPoolEntry entry(_tx, nFees, nAcceptTime, chainHeight,
535 342284 : fSpendsCoinbaseOrCoinstake, nSigOps);
536 171155 : unsigned int nSize = entry.GetTxSize();
537 :
538 : // Don't accept it if it can't get into a block
539 171155 : if (!ignoreFees) {
540 171155 : const CAmount txMinFee = GetMinRelayFee(tx, pool, nSize);
541 171155 : if (fLimitFree && nFees < txMinFee) {
542 21 : return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
543 14 : strprintf("%d < %d", nFees, txMinFee));
544 : }
545 :
546 : // No transactions are allowed below minRelayTxFee except from disconnected blocks
547 171148 : if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize)) {
548 0 : return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "min relay fee not met");
549 : }
550 : }
551 :
552 171148 : if (fRejectAbsurdFee) {
553 208254 : const CAmount nMaxFee = tx.IsShieldedTx() ? GetShieldedTxMinFee(tx) * 100 :
554 103049 : GetMinRelayFee(nSize) * 10000;
555 104127 : if (nFees > nMaxFee)
556 0 : return state.Invalid(false, REJECT_HIGHFEE, "absurdly-high-fee",
557 0 : strprintf("%d > %d", nFees, nMaxFee));
558 : }
559 :
560 : // Calculate in-mempool ancestors, up to a limit.
561 342277 : CTxMemPool::setEntries setAncestors;
562 171148 : size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
563 171148 : size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
564 171148 : size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
565 171148 : size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
566 342277 : std::string errString;
567 171148 : if (!pool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
568 15 : return state.DoS(0, error("%s : %s", __func__, errString), REJECT_NONSTANDARD, "too-long-mempool-chain", false);
569 : }
570 :
571 171143 : bool fCLTVIsActivated = consensus.NetworkUpgradeActive(chainHeight, Consensus::UPGRADE_BIP65);
572 171143 : bool exchangeAddrActivated = consensus.NetworkUpgradeActive(chainHeight, Consensus::UPGRADE_V5_6);
573 : // Check against previous transactions
574 : // This is done last to help prevent CPU exhaustion denial-of-service attacks.
575 171143 : int flags = STANDARD_SCRIPT_VERIFY_FLAGS;
576 171143 : if (fCLTVIsActivated)
577 171143 : flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
578 171143 : if (exchangeAddrActivated)
579 154052 : flags |= SCRIPT_VERIFY_EXCHANGEADDR;
580 :
581 :
582 171143 : PrecomputedTransactionData precomTxData(tx);
583 171143 : if (!CheckInputs(tx, state, view, true, flags, true, precomTxData)) {
584 : return false;
585 : }
586 :
587 : // Check again against just the consensus-critical mandatory script
588 : // verification flags, in case of bugs in the standard flags that cause
589 : // transactions to pass as valid when they're actually invalid. For
590 : // instance the STRICTENC flag was incorrectly allowing certain
591 : // CHECKSIG NOT scripts to pass, even though they were invalid.
592 : //
593 : // There is a similar check in CreateNewBlock() to prevent creating
594 : // invalid blocks, however allowing such transactions into the mempool
595 : // can be exploited as a DoS attack.
596 171131 : flags = MANDATORY_SCRIPT_VERIFY_FLAGS;
597 171131 : if (fCLTVIsActivated)
598 171131 : flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
599 171131 : if (exchangeAddrActivated)
600 154051 : flags |= SCRIPT_VERIFY_EXCHANGEADDR;
601 171131 : if (!CheckInputs(tx, state, view, true, flags, true, precomTxData)) {
602 0 : return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s",
603 0 : __func__, hash.ToString(), FormatStateMessage(state));
604 : }
605 : // todo: pool.removeStaged for all conflicting entries
606 :
607 : // This transaction should only count for fee estimation if
608 : // the node is not behind and it is not dependent on any other
609 : // transactions in the mempool
610 171131 : bool validForFeeEstimation = IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx);
611 :
612 : // Store transaction in memory
613 171131 : pool.addUnchecked(hash, entry, setAncestors, validForFeeEstimation);
614 :
615 : // trim mempool and check if tx was trimmed
616 171131 : if (!fOverrideMempoolLimit) {
617 238866 : LimitMempoolSize(pool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
618 119433 : if (!pool.exists(hash))
619 0 : return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full");
620 : }
621 :
622 171131 : pool.TrimToSize(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
623 171131 : if (!pool.exists(tx.GetHash()))
624 4 : return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full");
625 : }
626 :
627 171129 : GetMainSignals().TransactionAddedToMempool(_tx);
628 :
629 : return true;
630 : }
631 :
632 178071 : bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransactionRef& tx, bool fLimitFree,
633 : bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool fIgnoreFees)
634 : {
635 178071 : AssertLockHeld(cs_main);
636 :
637 178071 : std::vector<COutPoint> coins_to_uncache;
638 178071 : bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, fOverrideMempoolLimit, fRejectAbsurdFee, fIgnoreFees, coins_to_uncache);
639 178071 : if (!res) {
640 13845 : for (const COutPoint& outpoint: coins_to_uncache)
641 6903 : pcoinsTip->Uncache(outpoint);
642 : }
643 : // After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
644 356142 : CValidationState stateDummy;
645 178071 : FlushStateToDisk(stateDummy, FLUSH_STATE_PERIODIC);
646 356142 : return res;
647 : }
648 :
649 178048 : bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransactionRef& tx,
650 : bool fLimitFree, bool* pfMissingInputs, bool fOverrideMempoolLimit,
651 : bool fRejectInsaneFee, bool ignoreFees)
652 : {
653 178048 : return AcceptToMemoryPoolWithTime(pool, state, tx, fLimitFree, pfMissingInputs, GetTime(), fOverrideMempoolLimit, fRejectInsaneFee, ignoreFees);
654 : }
655 :
656 0 : bool GetOutput(const uint256& hash, unsigned int index, CValidationState& state, CTxOut& out)
657 : {
658 0 : CTransactionRef txPrev;
659 0 : uint256 hashBlock;
660 0 : if (!GetTransaction(hash, txPrev, hashBlock, true)) {
661 0 : return state.DoS(100, error("Output not found"));
662 : }
663 0 : if (index > txPrev->vout.size()) {
664 0 : return state.DoS(100, error("Output not found, invalid index %d for %s",index, hash.GetHex()));
665 : }
666 0 : out = txPrev->vout[index];
667 0 : return true;
668 : }
669 :
670 : /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
671 204244 : bool GetTransaction(const uint256& hash, CTransactionRef& txOut, uint256& hashBlock, bool fAllowSlow, CBlockIndex* blockIndex)
672 : {
673 204244 : CBlockIndex* pindexSlow = blockIndex;
674 :
675 408488 : LOCK(cs_main);
676 :
677 204244 : if (!blockIndex) {
678 :
679 204241 : CTransactionRef ptx = mempool.get(hash);
680 204241 : if (ptx) {
681 160 : txOut = ptx;
682 204401 : return true;
683 : }
684 :
685 204081 : if (fTxIndex) {
686 204081 : CDiskTxPos postx;
687 204081 : if (pblocktree->ReadTxIndex(hash, postx)) {
688 408140 : CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
689 204070 : if (file.IsNull())
690 0 : return error("%s: OpenBlockFile failed", __func__);
691 204070 : CBlockHeader header;
692 204070 : try {
693 204070 : file >> header;
694 204070 : fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
695 204070 : file >> txOut;
696 0 : } catch (const std::exception& e) {
697 0 : return error("%s : Deserialize or I/O error - %s", __func__, e.what());
698 : }
699 204070 : hashBlock = header.GetHash();
700 204070 : if (txOut->GetHash() != hash)
701 0 : return error("%s : txid mismatch", __func__);
702 : return true;
703 : }
704 :
705 : // transaction not found in the index, nothing more can be done
706 : return false;
707 : }
708 :
709 0 : if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
710 0 : const Coin& coin = AccessByTxid(*pcoinsTip, hash);
711 0 : if (!coin.IsSpent()) pindexSlow = chainActive[coin.nHeight];
712 : }
713 : }
714 :
715 3 : if (pindexSlow) {
716 4 : CBlock block;
717 3 : if (ReadBlockFromDisk(block, pindexSlow)) {
718 6 : for (const auto& tx : block.vtx) {
719 5 : if (tx->GetHash() == hash) {
720 2 : txOut = tx;
721 2 : hashBlock = pindexSlow->GetBlockHash();
722 2 : return true;
723 : }
724 : }
725 : }
726 : }
727 :
728 : return false;
729 : }
730 :
731 :
732 : //////////////////////////////////////////////////////////////////////////////
733 : //
734 : // CBlock and CBlockIndex
735 : //
736 :
737 41132 : bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos)
738 : {
739 : // Open history file to append
740 82264 : CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
741 41132 : if (fileout.IsNull())
742 0 : return error("WriteBlockToDisk : OpenBlockFile failed");
743 :
744 : // Write index header
745 41132 : unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
746 41132 : fileout << Params().MessageStart() << nSize;
747 :
748 : // Write block
749 41132 : long fileOutPos = ftell(fileout.Get());
750 41132 : if (fileOutPos < 0)
751 0 : return error("WriteBlockToDisk : ftell failed");
752 41132 : pos.nPos = (unsigned int)fileOutPos;
753 41132 : fileout << block;
754 :
755 : return true;
756 : }
757 :
758 82942 : bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos)
759 : {
760 82942 : block.SetNull();
761 :
762 : // Open history file to read
763 165884 : CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
764 82942 : if (filein.IsNull())
765 7 : return error("ReadBlockFromDisk : OpenBlockFile failed");
766 :
767 : // Read block
768 82935 : try {
769 82935 : filein >> block;
770 0 : } catch (const std::exception& e) {
771 0 : return error("%s : Deserialize or I/O error - %s", __func__, e.what());
772 : }
773 :
774 : // Check the header
775 82935 : if (block.IsProofOfWork()) {
776 73508 : if (!CheckProofOfWork(block.GetHash(), block.nBits))
777 0 : return error("ReadBlockFromDisk : Errors in block header");
778 : }
779 :
780 : return true;
781 : }
782 :
783 82942 : bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
784 : {
785 248826 : FlatFilePos blockPos = WITH_LOCK(cs_main, return pindex->GetBlockPos(); );
786 82942 : if (!ReadBlockFromDisk(block, blockPos)) {
787 : return false;
788 : }
789 82935 : if (block.GetHash() != pindex->GetBlockHash()) {
790 0 : LogPrintf("%s : block=%s index=%s\n", __func__, block.GetHash().GetHex(), pindex->GetBlockHash().GetHex());
791 0 : return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
792 : }
793 : return true;
794 : }
795 :
796 :
797 0 : double ConvertBitsToDouble(unsigned int nBits)
798 : {
799 0 : int nShift = (nBits >> 24) & 0xff;
800 :
801 0 : double dDiff =
802 0 : (double)0x0000ffff / (double)(nBits & 0x00ffffff);
803 :
804 0 : while (nShift < 29) {
805 0 : dDiff *= 256.0;
806 0 : nShift++;
807 : }
808 0 : while (nShift > 29) {
809 0 : dDiff /= 256.0;
810 0 : nShift--;
811 : }
812 :
813 0 : return dDiff;
814 : }
815 :
816 360598 : CAmount GetBlockValue(int nHeight)
817 : {
818 : // Set V5.5 upgrade block for regtest as well as testnet and mainnet
819 360598 : const int nLast = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight;
820 :
821 : // Regtest block reward reduction schedule
822 360598 : if (Params().IsRegTestNet()) {
823 : // Reduce regtest block value after V5.5 upgrade
824 101390 : if (nHeight > nLast) return 10 * COIN;
825 81378 : return 250 * COIN;
826 : }
827 : // Testnet high-inflation blocks [2, 200] with value 250k PIV
828 259208 : const bool isTestnet = Params().IsTestnet();
829 259208 : if (isTestnet && nHeight < 201 && nHeight > 1) {
830 : return 250000 * COIN;
831 : }
832 : // Mainnet/Testnet block reward reduction schedule
833 259207 : const int nZerocoinV2 = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_ZC_V2].nActivationHeight;
834 259207 : if (nHeight > nLast) return 10 * COIN;
835 259205 : if (nHeight > nZerocoinV2) return 5 * COIN;
836 259201 : if (nHeight > 648000) return 4.5 * COIN;
837 259201 : if (nHeight > 604800) return 9 * COIN;
838 259201 : if (nHeight > 561600) return 13.5 * COIN;
839 259201 : if (nHeight > 518400) return 18 * COIN;
840 259201 : if (nHeight > 475200) return 22.5 * COIN;
841 259201 : if (nHeight > 432000) return 27 * COIN;
842 259201 : if (nHeight > 388800) return 31.5 * COIN;
843 259201 : if (nHeight > 345600) return 36 * COIN;
844 259201 : if (nHeight > 302400) return 40.5 * COIN;
845 259201 : if (nHeight > 151200) return 45 * COIN;
846 151201 : if (nHeight > 86400) return 225 * COIN;
847 86401 : if (nHeight != 1) return 250 * COIN;
848 : // Premine for 6 masternodes at block 1
849 : return 60001 * COIN;
850 : }
851 :
852 15154 : int64_t GetMasternodePayment(int nHeight)
853 : {
854 15154 : if (nHeight > Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight) {
855 10419 : return Params().GetConsensus().nNewMNBlockReward;
856 : }
857 :
858 : // Future: refactor function callers to use this line directly.
859 4735 : return Params().GetConsensus().nMNBlockReward;
860 : }
861 :
862 5020590 : bool IsInitialBlockDownload()
863 : {
864 : // Once this function has returned false, it must remain false.
865 5020590 : static std::atomic<bool> latchToFalse{false};
866 : // Optimization: pre-test latch before taking the lock.
867 5020590 : if (latchToFalse.load(std::memory_order_relaxed))
868 : return false;
869 :
870 5309569 : LOCK(cs_main);
871 288979 : if (latchToFalse.load(std::memory_order_relaxed))
872 : return false;
873 288979 : const int chainHeight = chainActive.Height();
874 288979 : if (fImporting || fReindex || chainHeight < Checkpoints::GetTotalBlocksEstimate())
875 2991 : return true;
876 285988 : bool state = (chainHeight < pindexBestHeader->nHeight - 24 * 6 ||
877 285988 : pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge);
878 284 : if (!state)
879 288979 : latchToFalse.store(true, std::memory_order_relaxed);
880 : return state;
881 : }
882 :
883 : CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr;
884 :
885 2 : static void AlertNotify(const std::string& strMessage)
886 : {
887 2 : uiInterface.NotifyAlertChanged();
888 5 : std::string strCmd = gArgs.GetArg("-alertnotify", "");
889 2 : if (strCmd.empty()) return;
890 :
891 : // Alert text should be plain ascii coming from a trusted source, but to
892 : // be safe we first strip anything not in safeChars, then add single quotes around
893 : // the whole string before passing it to the shell:
894 2 : std::string singleQuote("'");
895 2 : std::string safeStatus = SanitizeString(strMessage);
896 2 : safeStatus = singleQuote+safeStatus+singleQuote;
897 1 : boost::replace_all(strCmd, "%s", safeStatus);
898 :
899 2 : std::thread t(runCommand, strCmd);
900 1 : t.detach(); // thread runs free
901 : }
902 :
903 41646 : void CheckForkWarningConditions()
904 : {
905 41646 : AssertLockHeld(cs_main);
906 : // Before we get past initial download, we cannot reliably alert about forks
907 : // (we assume we don't get stuck on a fork before the last checkpoint)
908 41646 : if (IsInitialBlockDownload())
909 : return;
910 :
911 82510 : const CBlockIndex* pChainTip = chainActive.Tip();
912 40864 : if (!pChainTip)
913 : return;
914 :
915 : // If our best fork is no longer within 72 blocks (+/- 3 hours if no one mines it)
916 : // of our head, drop it
917 40864 : if (pindexBestForkTip && pChainTip->nHeight - pindexBestForkTip->nHeight >= 72)
918 0 : pindexBestForkTip = nullptr;
919 :
920 41438 : if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > pChainTip->nChainWork + (GetBlockProof(*pChainTip) * 6))) {
921 0 : if (!GetfLargeWorkForkFound() && pindexBestForkBase) {
922 0 : if (pindexBestForkBase->phashBlock) {
923 0 : std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
924 0 : pindexBestForkBase->phashBlock->ToString() + std::string("'");
925 0 : AlertNotify(warning);
926 : }
927 : }
928 0 : if (pindexBestForkTip && pindexBestForkBase) {
929 0 : if (pindexBestForkBase->phashBlock) {
930 0 : LogPrintf("CheckForkWarningConditions: 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",
931 0 : pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
932 0 : pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
933 0 : SetfLargeWorkForkFound(true);
934 : }
935 : } else {
936 0 : LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
937 0 : SetfLargeWorkInvalidChainFound(true);
938 : }
939 : } else {
940 40864 : SetfLargeWorkForkFound(false);
941 40864 : SetfLargeWorkInvalidChainFound(false);
942 : }
943 : }
944 :
945 46 : void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
946 : {
947 46 : AssertLockHeld(cs_main);
948 : // If we are on a fork that is sufficiently large, set a warning flag
949 46 : CBlockIndex* pfork = pindexNewForkTip;
950 46 : CBlockIndex* plonger = chainActive.Tip();
951 89 : while (pfork && pfork != plonger) {
952 43 : while (plonger && plonger->nHeight > pfork->nHeight)
953 0 : plonger = plonger->pprev;
954 43 : if (pfork == plonger)
955 : break;
956 43 : pfork = pfork->pprev;
957 : }
958 :
959 : // We define a condition which we should warn the user about as a fork of at least 7 blocks
960 : // who's tip is within 72 blocks (+/- 3 hours if no one mines it) of ours
961 : // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
962 : // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
963 : // hash rate operating on the fork.
964 : // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
965 : // the 7-block condition and from this always have the most-likely-to-cause-warning fork
966 46 : if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
967 92 : pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
968 0 : chainActive.Height() - pindexNewForkTip->nHeight < 72) {
969 0 : pindexBestForkTip = pindexNewForkTip;
970 0 : pindexBestForkBase = pfork;
971 : }
972 :
973 46 : CheckForkWarningConditions();
974 46 : }
975 :
976 123 : void static InvalidChainFound(CBlockIndex* pindexNew)
977 : {
978 123 : if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
979 50 : pindexBestInvalid = pindexNew;
980 :
981 246 : LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.16f date=%s\n",
982 0 : pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
983 246 : log(pindexNew->nChainWork.getdouble()) / log(2.0), FormatISO8601DateTime(pindexNew->GetBlockTime()));
984 :
985 123 : const CBlockIndex* pChainTip = chainActive.Tip();
986 123 : assert(pChainTip);
987 246 : LogPrintf("InvalidChainFound: current best=%s height=%d log2_work=%.16f date=%s\n",
988 246 : pChainTip->GetBlockHash().GetHex(), pChainTip->nHeight, log(pChainTip->nChainWork.getdouble()) / log(2.0),
989 123 : FormatISO8601DateTime(pChainTip->GetBlockTime()));
990 :
991 123 : CheckForkWarningConditions();
992 123 : }
993 :
994 46 : void static InvalidBlockFound(CBlockIndex* pindex, const CValidationState& state)
995 : {
996 46 : if (!state.CorruptionPossible()) {
997 46 : pindex->nStatus |= BLOCK_FAILED_VALID;
998 46 : setDirtyBlockIndex.insert(pindex);
999 46 : setBlockIndexCandidates.erase(pindex);
1000 46 : InvalidChainFound(pindex);
1001 : }
1002 46 : }
1003 :
1004 485349 : static bool SkipInvalidUTXOS(int nHeight)
1005 : {
1006 485349 : const Consensus::Params& consensus = Params().GetConsensus();
1007 485349 : return Params().NetworkIDString() == CBaseChainParams::MAIN &&
1008 485349 : consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZC) &&
1009 485349 : nHeight <= consensus.height_last_invalid_UTXO;
1010 : }
1011 :
1012 3598961 : void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo& txundo, int nHeight, bool fSkipInvalid)
1013 : {
1014 : // mark inputs spent
1015 3598961 : if (!tx.IsCoinBase() && !tx.HasZerocoinSpendInputs()) {
1016 3538459 : txundo.vprevout.reserve(tx.vin.size());
1017 8631203 : for (const CTxIn& txin : tx.vin) {
1018 5092734 : txundo.vprevout.emplace_back();
1019 5092734 : inputs.SpendCoin(txin.prevout, &txundo.vprevout.back());
1020 : }
1021 : }
1022 :
1023 : // update spent nullifiers
1024 3598961 : inputs.SetNullifiers(tx, true);
1025 :
1026 : // add outputs
1027 3598961 : AddCoins(inputs, tx, nHeight, false, fSkipInvalid);
1028 3598961 : }
1029 :
1030 3077690 : void UpdateCoins(const CTransaction& tx, CCoinsViewCache &inputs, int nHeight, bool fSkipInvalid)
1031 : {
1032 3077690 : CTxUndo txundo;
1033 3077690 : UpdateCoins(tx, inputs, txundo, nHeight, fSkipInvalid);
1034 3077690 : }
1035 :
1036 1456383 : bool CScriptCheck::operator()()
1037 : {
1038 1456383 : const CScript& scriptSig = ptxTo->vin[nIn].scriptSig;
1039 2900493 : return VerifyScript(scriptSig, m_tx_out.scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, m_tx_out.nValue, cacheStore, *precomTxData), ptxTo->GetRequiredSigVersion(), &error);
1040 : }
1041 :
1042 3848856 : int GetSpendHeight(const CCoinsViewCache& inputs)
1043 : {
1044 3848856 : LOCK(cs_main);
1045 3848856 : CBlockIndex* pindexPrev = LookupBlockIndex(inputs.GetBestBlock());
1046 7697712 : return pindexPrev->nHeight + 1;
1047 : }
1048 :
1049 : namespace Consensus {
1050 3848856 : bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight)
1051 : {
1052 : // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
1053 : // for an attacker to attempt to split the network.
1054 3848856 : if (!inputs.HaveInputs(tx))
1055 0 : return state.Invalid(false, 0, "", "Inputs unavailable");
1056 :
1057 : // are the Sapling's requirements met?
1058 3848856 : if (!inputs.HaveShieldedRequirements(tx))
1059 0 : return state.Invalid(error("CheckInputs(): %s Sapling requirements not met", tx.GetHash().ToString()));
1060 :
1061 3848856 : const Consensus::Params& consensus = ::Params().GetConsensus();
1062 3848856 : CAmount nValueIn = 0;
1063 3848856 : CAmount nFees = 0;
1064 9566105 : for (unsigned int i = 0; i < tx.vin.size(); i++) {
1065 5717259 : const COutPoint &prevout = tx.vin[i].prevout;
1066 5717259 : const Coin& coin = inputs.AccessCoin(prevout);
1067 5717259 : assert(!coin.IsSpent());
1068 :
1069 : // If prev is coinbase, check that it's matured
1070 5717259 : if (coin.IsCoinBase() || coin.IsCoinStake()) {
1071 23501 : if ((signed long)nSpendHeight - coin.nHeight < (signed long)consensus.nCoinbaseMaturity)
1072 22 : return state.Invalid(false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase-coinstake",
1073 22 : strprintf("tried to spend coinbase/coinstake at depth %d", nSpendHeight - coin.nHeight));
1074 : }
1075 :
1076 : // Check for negative or overflow input values
1077 5717249 : nValueIn += coin.out.nValue;
1078 17151747 : if (!consensus.MoneyRange(coin.out.nValue) || !consensus.MoneyRange(nValueIn))
1079 0 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange");
1080 : }
1081 :
1082 : // Sapling
1083 3848846 : nValueIn += tx.GetShieldedValueIn();
1084 :
1085 3848846 : if (!tx.IsCoinStake()) {
1086 3840292 : if (nValueIn < tx.GetValueOut())
1087 6 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false,
1088 4 : strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())));
1089 :
1090 : // Tally transaction fees
1091 3840292 : CAmount nTxFee = nValueIn - tx.GetValueOut();
1092 3840292 : if (nTxFee < 0)
1093 0 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative");
1094 3840292 : nFees += nTxFee;
1095 3848856 : if (!consensus.MoneyRange(nFees))
1096 0 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange");
1097 : }
1098 : return true;
1099 : }
1100 : }// namespace Consensus
1101 :
1102 3848856 : bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, PrecomputedTransactionData& precomTxData, std::vector<CScriptCheck> *pvChecks)
1103 : {
1104 3848856 : if (!tx.IsCoinBase() && !tx.HasZerocoinSpendInputs()) {
1105 :
1106 3848856 : if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs)))
1107 : return false;
1108 :
1109 3848846 : if (pvChecks)
1110 428890 : pvChecks->reserve(tx.vin.size());
1111 :
1112 : // The first loop above does all the inexpensive checks.
1113 : // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
1114 : // Helps prevent CPU exhaustion attacks.
1115 :
1116 : // Skip ECDSA signature verification when connecting blocks
1117 : // before the last block chain checkpoint. This is safe because block merkle hashes are
1118 : // still computed and checked, and any change will be caught at the next checkpoint.
1119 3848846 : if (fScriptChecks) {
1120 2222975 : for (unsigned int i = 0; i < tx.vin.size(); i++) {
1121 1451819 : const COutPoint& prevout = tx.vin[i].prevout;
1122 1451819 : const Coin& coin = inputs.AccessCoin(prevout);
1123 1451819 : assert(!coin.IsSpent());
1124 :
1125 : // We very carefully only pass in things to CScriptCheck which
1126 : // are clearly committed to by tx' witness hash. This provides
1127 : // a sanity check that our caching is not introducing consensus
1128 : // failures through additional data in, eg, the coins being
1129 : // spent being checked as a part of CScriptCheck.
1130 :
1131 : // Verify signature
1132 2903638 : CScriptCheck check(coin.out, tx, i, flags, cacheStore, &precomTxData);
1133 1451819 : if (pvChecks) {
1134 795427 : pvChecks->emplace_back();
1135 795427 : check.swap(pvChecks->back());
1136 656393 : } else if (!check()) {
1137 3 : if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
1138 : // Check whether the failure was caused by a
1139 : // non-mandatory script verification check, such as
1140 : // non-standard DER encodings or non-null dummy
1141 : // arguments; if so, don't trigger DoS protection to
1142 : // avoid splitting the network between upgraded and
1143 : // non-upgraded nodes.
1144 3 : CScriptCheck check2(coin.out, tx, i,
1145 6 : flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, &precomTxData);
1146 3 : if (check2())
1147 0 : return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
1148 : }
1149 : // Failures of other flags indicate a transaction that is
1150 : // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
1151 : // such nodes as they are not following the protocol. That
1152 : // said during an upgrade careful thought should be taken
1153 : // as to the correct behavior - we may want to continue
1154 : // peering with non-upgraded nodes even after a soft-fork
1155 : // super-majority vote has passed.
1156 9 : return state.DoS(100, false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
1157 : }
1158 : }
1159 : }
1160 : }
1161 :
1162 : return true;
1163 : }
1164 :
1165 : /** Abort with a message */
1166 1 : static bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
1167 : {
1168 1 : SetMiscWarning(strMessage);
1169 1 : LogPrintf("*** %s\n", strMessage);
1170 1 : uiInterface.ThreadSafeMessageBox(
1171 2 : userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
1172 : "", CClientUIInterface::MSG_ERROR);
1173 1 : StartShutdown();
1174 1 : return false;
1175 : }
1176 :
1177 1 : static bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
1178 : {
1179 1 : AbortNode(strMessage, userMessage);
1180 3 : return state.Error(strMessage);
1181 : }
1182 :
1183 : namespace {
1184 :
1185 41065 : bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock)
1186 : {
1187 : // Open history file to append
1188 82130 : CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
1189 41065 : if (fileout.IsNull())
1190 0 : return error("%s : OpenUndoFile failed", __func__);
1191 :
1192 : // Write index header
1193 41065 : unsigned int nSize = GetSerializeSize(blockundo, fileout.GetVersion());
1194 41065 : fileout << Params().MessageStart() << nSize;
1195 :
1196 : // Write undo data
1197 41065 : long fileOutPos = ftell(fileout.Get());
1198 41065 : if (fileOutPos < 0)
1199 0 : return error("%s : ftell failed", __func__);
1200 41065 : pos.nPos = (unsigned int)fileOutPos;
1201 41065 : fileout << blockundo;
1202 :
1203 : // calculate & write checksum
1204 41065 : CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
1205 41065 : hasher << hashBlock;
1206 41065 : hasher << blockundo;
1207 82130 : fileout << hasher.GetHash();
1208 :
1209 41065 : return true;
1210 : }
1211 :
1212 2587 : bool UndoReadFromDisk(CBlockUndo& blockundo, const FlatFilePos& pos, const uint256& hashBlock)
1213 : {
1214 : // Open history file to read
1215 5174 : CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
1216 2587 : if (filein.IsNull())
1217 1 : return error("%s : OpenBlockFile failed", __func__);
1218 :
1219 : // Read block
1220 2586 : uint256 hashChecksum;
1221 2586 : CHashVerifier<CAutoFile> verifier(&filein); // We need a CHashVerifier as reserializing may lose data
1222 2586 : try {
1223 2586 : verifier << hashBlock;
1224 2586 : verifier >> blockundo;
1225 2585 : filein >> hashChecksum;
1226 1 : } catch (const std::exception& e) {
1227 1 : return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1228 : }
1229 :
1230 : // Verify checksum
1231 5170 : if (hashChecksum != verifier.GetHash())
1232 0 : return error("%s : Checksum mismatch", __func__);
1233 :
1234 : return true;
1235 : }
1236 :
1237 : } // anon namespace
1238 :
1239 : enum DisconnectResult
1240 : {
1241 : DISCONNECT_OK, // All good.
1242 : DISCONNECT_UNCLEAN, // Rolled back, but UTXO set was inconsistent with block.
1243 : DISCONNECT_FAILED // Something else went wrong.
1244 : };
1245 :
1246 : /**
1247 : * Restore the UTXO in a Coin at a given COutPoint
1248 : * @param undo The Coin to be restored.
1249 : * @param view The coins view to which to apply the changes.
1250 : * @param out The out point that corresponds to the tx input.
1251 : * @return A DisconnectResult as an int
1252 : */
1253 221306 : int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out)
1254 : {
1255 221306 : bool fClean = true;
1256 :
1257 221306 : if (view.HaveCoin(out)) fClean = false; // overwriting transaction output
1258 :
1259 221306 : if (undo.nHeight == 0) {
1260 : // Missing undo metadata (height and coinbase/coinstake). Older versions included this
1261 : // information only in undo records for the last spend of a transactions'
1262 : // outputs. This implies that it must be present for some other output of the same tx.
1263 0 : const Coin& alternate = AccessByTxid(view, out.hash);
1264 0 : if (!alternate.IsSpent()) {
1265 0 : undo.nHeight = alternate.nHeight;
1266 0 : undo.fCoinBase = alternate.fCoinBase;
1267 0 : undo.fCoinStake = alternate.fCoinStake;
1268 : } else {
1269 : return DISCONNECT_FAILED; // adding output for transaction without known metadata
1270 : }
1271 : }
1272 : // The potential_overwrite parameter to AddCoin is only allowed to be false if we know for
1273 : // sure that the coin did not already exist in the cache. As we have queried for that above
1274 : // using HaveCoin, we don't need to guess. When fClean is false, a coin already existed and
1275 : // it is an overwrite.
1276 221306 : view.AddCoin(out, std::move(undo), !fClean);
1277 :
1278 221306 : return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
1279 : }
1280 :
1281 :
1282 : /** Undo the effects of this block (with given index) on the UTXO set represented by coins.
1283 : * When FAILED is returned, view is left in an indeterminate state. */
1284 1458 : DisconnectResult DisconnectBlock(CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view)
1285 : {
1286 1458 : AssertLockHeld(cs_main);
1287 :
1288 1458 : bool fDIP3Active = Params().GetConsensus().NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_V6_0);
1289 1458 : bool fHasBestBlock = evoDb->VerifyBestBlock(pindex->GetBlockHash());
1290 :
1291 1458 : if (fDIP3Active && !fHasBestBlock) {
1292 0 : AbortNode("Found EvoDB inconsistency, you must reindex to continue");
1293 0 : return DISCONNECT_FAILED;
1294 : }
1295 :
1296 1458 : bool fClean = true;
1297 :
1298 2916 : CBlockUndo blockUndo;
1299 1458 : FlatFilePos pos = pindex->GetUndoPos();
1300 1458 : if (pos.IsNull()) {
1301 0 : error("%s: no undo data available", __func__);
1302 : return DISCONNECT_FAILED;
1303 : }
1304 1458 : if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash())) {
1305 1 : error("%s: failure reading undo data", __func__);
1306 : return DISCONNECT_FAILED;
1307 : }
1308 :
1309 1457 : if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) {
1310 0 : error("%s: block and undo data inconsistent", __func__);
1311 : return DISCONNECT_FAILED;
1312 : }
1313 :
1314 1457 : if (!UndoSpecialTxsInBlock(block, pindex)) {
1315 : return DISCONNECT_FAILED;
1316 : }
1317 :
1318 : // undo transactions in reverse order
1319 112802 : for (int i = block.vtx.size() - 1; i >= 0; i--) {
1320 111345 : const CTransaction& tx = *block.vtx[i];
1321 :
1322 111345 : if (!DisconnectZerocoinTx(tx))
1323 : return DISCONNECT_FAILED;
1324 :
1325 111345 : const uint256& hash = tx.GetHash();
1326 :
1327 : // if tx is a budget collateral tx, remove relative object
1328 111345 : g_budgetman.RemoveByFeeTxId(hash);
1329 :
1330 : // Check that all outputs are available and match the outputs in the block itself
1331 : // exactly.
1332 428820 : for (size_t o = 0; o < tx.vout.size(); o++) {
1333 952417 : if (!tx.vout[o].scriptPubKey.IsUnspendable() && !tx.vout[o].IsZerocoinMint()) {
1334 317467 : COutPoint out(hash, o);
1335 634934 : Coin coin;
1336 317467 : view.SpendCoin(out, &coin);
1337 317467 : if (tx.vout[o] != coin.out) {
1338 1341 : fClean = false; // transaction output mismatch
1339 : }
1340 : }
1341 : }
1342 :
1343 : // not coinbases or zerocoinspend because they dont have traditional inputs
1344 111345 : if (tx.IsCoinBase() || tx.HasZerocoinSpendInputs())
1345 1457 : continue;
1346 :
1347 : // Sapling, update unspent nullifiers
1348 109888 : view.SetNullifiers(tx, false);
1349 :
1350 : // restore inputs
1351 109888 : CTxUndo& txundo = blockUndo.vtxundo[i - 1];
1352 109888 : if (txundo.vprevout.size() != tx.vin.size()) {
1353 0 : error("%s: transaction and undo data inconsistent - txundo.vprevout.siz=%d tx.vin.siz=%d",
1354 0 : __func__, txundo.vprevout.size(), tx.vin.size());
1355 0 : return DISCONNECT_FAILED;
1356 : }
1357 329408 : for (unsigned int j = tx.vin.size(); j-- > 0;) {
1358 219520 : const COutPoint& out = tx.vin[j].prevout;
1359 219520 : int res = ApplyTxInUndo(std::move(txundo.vprevout[j]), view, out);
1360 219520 : if (res == DISCONNECT_FAILED) return DISCONNECT_FAILED;
1361 219520 : fClean = fClean && res != DISCONNECT_UNCLEAN;
1362 : }
1363 : // At this point, all of txundo.vprevout should have been moved out.
1364 : }
1365 :
1366 1457 : const Consensus::Params& consensus = Params().GetConsensus();
1367 :
1368 : // set the old best Sapling anchor back
1369 : // We can get this from the `hashFinalSaplingRoot` of the last block
1370 : // However, this is only reliable if the last block was on or after
1371 : // the Sapling activation height. Otherwise, the last anchor was the
1372 : // empty root.
1373 1457 : if (consensus.NetworkUpgradeActive(pindex->pprev->nHeight, Consensus::UPGRADE_V5_0)) {
1374 281 : view.PopAnchor(pindex->pprev->hashFinalSaplingRoot);
1375 : } else {
1376 2352 : view.PopAnchor(SaplingMerkleTree::empty_root());
1377 : }
1378 :
1379 : // move best block pointer to prevout block
1380 1457 : view.SetBestBlock(pindex->pprev->GetBlockHash());
1381 1457 : evoDb->WriteBestBlock(pindex->pprev->GetBlockHash());
1382 :
1383 1457 : if (consensus.NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_ZC_V2) &&
1384 15 : pindex->nHeight <= consensus.height_last_ZC_AccumCheckpoint) {
1385 : // Legacy Zerocoin DB: If Accumulators Checkpoint is changed, remove changed checksums
1386 0 : CacheAccChecksum(pindex, false);
1387 : }
1388 :
1389 1457 : return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
1390 : }
1391 :
1392 808 : void static FlushBlockFile(bool fFinalize = false)
1393 : {
1394 808 : LOCK(cs_LastBlockFile);
1395 :
1396 808 : FlatFilePos block_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nSize);
1397 808 : FlatFilePos undo_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nUndoSize);
1398 :
1399 808 : bool status = true;
1400 808 : status &= BlockFileSeq().Flush(block_pos_old, fFinalize);
1401 808 : status &= UndoFileSeq().Flush(undo_pos_old, fFinalize);
1402 808 : if (!status) {
1403 0 : AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error.");
1404 : }
1405 808 : }
1406 :
1407 : bool FindUndoPos(CValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize);
1408 :
1409 : static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
1410 :
1411 2868 : void ThreadScriptCheck()
1412 : {
1413 2868 : util::ThreadRename("pivx-scriptch");
1414 2868 : scriptcheckqueue.Thread();
1415 0 : }
1416 :
1417 : static int64_t nTimeVerify = 0;
1418 : static int64_t nTimeProcessSpecial = 0;
1419 : static int64_t nTimeConnect = 0;
1420 : static int64_t nTimeIndex = 0;
1421 : static int64_t nTimeTotal = 0;
1422 :
1423 : /** Apply the effects of this block (with given index) on the UTXO set represented by coins.
1424 : * Validity checks that depend on the UTXO set are also done; ConnectBlock()
1425 : * can fail if those validity checks fail (among other reasons). */
1426 56761 : static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
1427 : {
1428 56761 : AssertLockHeld(cs_main);
1429 : // Check it again in case a previous version let a bad block in
1430 56761 : if (!CheckBlock(block, state, !fJustCheck, !fJustCheck, !fJustCheck)) {
1431 0 : if (state.CorruptionPossible()) {
1432 : // We don't write down blocks to disk if they may have been
1433 : // corrupted, so this should be impossible unless we're having hardware
1434 : // problems.
1435 0 : return AbortNode(state, "Corrupt block found indicating potential hardware failure; shutting down");
1436 : }
1437 0 : return error("%s: CheckBlock failed for %s: %s", __func__, block.GetHash().ToString(), FormatStateMessage(state));
1438 : }
1439 :
1440 56761 : if (pindex->pprev && pindex->phashBlock && llmq::chainLocksHandler->HasConflictingChainLock(pindex->nHeight, pindex->GetBlockHash())) {
1441 0 : return state.DoS(10, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock");
1442 : }
1443 : // verify that the view's current state corresponds to the previous block
1444 56761 : uint256 hashPrevBlock = pindex->pprev == nullptr ? UINT256_ZERO : pindex->pprev->GetBlockHash();
1445 56761 : if (hashPrevBlock != view.GetBestBlock())
1446 0 : LogPrintf("%s: hashPrev=%s view=%s\n", __func__, hashPrevBlock.GetHex(), view.GetBestBlock().GetHex());
1447 56761 : assert(hashPrevBlock == view.GetBestBlock());
1448 :
1449 56761 : const bool isPoSBlock = block.IsProofOfStake();
1450 56761 : const Consensus::Params& consensus = Params().GetConsensus();
1451 56761 : const bool isPoSActive = consensus.NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_POS);
1452 56761 : const bool isV5UpgradeEnforced = consensus.NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_V5_0);
1453 56761 : const bool isV6UpgradeEnforced = consensus.NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_V6_0);
1454 :
1455 : // Coinbase output should be empty if proof-of-stake block (before v6 enforcement)
1456 56761 : if (!isV6UpgradeEnforced && isPoSBlock && (block.vtx[0]->vout.size() != 1 || !block.vtx[0]->vout[0].IsEmpty()))
1457 0 : return state.DoS(100, false, REJECT_INVALID, "bad-cb-pos", false, "coinbase output not empty for proof-of-stake block");
1458 :
1459 56761 : if (pindex->pprev) {
1460 56443 : bool fHasBestBlock = evoDb->VerifyBestBlock(hashPrevBlock);
1461 :
1462 56443 : if (isV6UpgradeEnforced && !fHasBestBlock) {
1463 0 : return AbortNode(state, "Found EvoDB inconsistency, you must reindex to continue");
1464 : }
1465 : }
1466 :
1467 : // Special case for the genesis block, skipping connection of its transactions
1468 : // (its coinbase is unspendable)
1469 56761 : if (block.GetHash() == consensus.hashGenesisBlock) {
1470 318 : if (!fJustCheck) {
1471 318 : view.SetBestBlock(pindex->GetBlockHash());
1472 : }
1473 318 : return true;
1474 : }
1475 :
1476 56443 : if (!isPoSActive && isPoSBlock)
1477 0 : return state.DoS(100, error("ConnectBlock() : PoS period not active"),
1478 : REJECT_INVALID, "PoS-early");
1479 :
1480 56443 : if (isPoSActive && !isPoSBlock)
1481 0 : return state.DoS(100, error("ConnectBlock() : PoW period ended"),
1482 : REJECT_INVALID, "PoW-ended");
1483 :
1484 : // Sapling
1485 : // Reject a block that results in a negative shielded value pool balance.
1486 : // Description under ZIP209 turnstile violation.
1487 :
1488 : // If we've reached ConnectBlock, we have all transactions of
1489 : // parents and can expect nChainSaplingValue not to be boost::none.
1490 : // However, the miner and mining RPCs may not have populated this
1491 : // value and will call `TestBlockValidity`. So, we act
1492 : // conditionally.
1493 56443 : if (pindex->nChainSaplingValue) {
1494 41296 : if (*pindex->nChainSaplingValue < 0) {
1495 0 : return state.DoS(100, error("%s: turnstile violation in Sapling shielded value pool: val: %d", __func__, *pindex->nChainSaplingValue),
1496 : REJECT_INVALID, "turnstile-violation-sapling-shielded-pool");
1497 : }
1498 : }
1499 :
1500 56443 : bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();
1501 :
1502 : // If scripts won't be checked anyways, don't bother seeing if CLTV is activated
1503 56443 : bool fCLTVIsActivated = false;
1504 56443 : bool exchangeAddrActivated = false;
1505 56443 : if (fScriptChecks && pindex->pprev) {
1506 56443 : fCLTVIsActivated = consensus.NetworkUpgradeActive(pindex->pprev->nHeight, Consensus::UPGRADE_BIP65);
1507 56443 : exchangeAddrActivated = consensus.NetworkUpgradeActive(pindex->pprev->nHeight, Consensus::UPGRADE_V5_6);
1508 : }
1509 :
1510 113204 : CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : nullptr);
1511 :
1512 56443 : int64_t nTimeStart = GetTimeMicros();
1513 56443 : CAmount nFees = 0;
1514 56443 : int nInputs = 0;
1515 56443 : unsigned int nSigOps = 0;
1516 56579 : CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
1517 112886 : std::vector<std::pair<uint256, CDiskTxPos> > vPos;
1518 56443 : std::vector<std::pair<CBigNum, uint256> > vSpends;
1519 56443 : vPos.reserve(block.vtx.size());
1520 112886 : CBlockUndo blockundo;
1521 56443 : blockundo.vtxundo.reserve(block.vtx.size() - 1);
1522 56443 : CAmount nValueOut = 0;
1523 56443 : CAmount nValueIn = 0;
1524 56443 : unsigned int nMaxBlockSigOps = MAX_BLOCK_SIGOPS_CURRENT;
1525 :
1526 : // Sapling
1527 112886 : SaplingMerkleTree sapling_tree;
1528 56443 : assert(view.GetSaplingAnchorAt(view.GetBestAnchor(), sapling_tree));
1529 :
1530 112886 : std::vector<PrecomputedTransactionData> precomTxData;
1531 56443 : precomTxData.reserve(block.vtx.size()); // Required so that pointers to individual precomTxData don't get invalidated
1532 56443 : bool fInitialBlockDownload = IsInitialBlockDownload();
1533 56443 : bool fSaplingMaintenance = (block.nTime > sporkManager.GetSporkValue(SPORK_20_SAPLING_MAINTENANCE));
1534 541776 : for (unsigned int i = 0; i < block.vtx.size(); i++) {
1535 485354 : const CTransaction& tx = *block.vtx[i];
1536 :
1537 485354 : nInputs += tx.vin.size();
1538 485354 : nSigOps += GetLegacySigOpCount(tx);
1539 485354 : if (nSigOps > nMaxBlockSigOps)
1540 2 : return state.DoS(100, error("ConnectBlock() : too many sigops"), REJECT_INVALID, "bad-blk-sigops");
1541 :
1542 : // Check maintenance mode
1543 485353 : if (!fInitialBlockDownload && fSaplingMaintenance && tx.IsShieldedTx()) {
1544 2 : return state.DoS(100, error("%s : shielded transactions are currently in maintenance mode", __func__));
1545 : }
1546 :
1547 : // When v5 is enforced ContextualCheckTransaction rejects zerocoin transactions.
1548 : // Therefore no need to call HasZerocoinSpendInputs after the enforcement.
1549 485352 : if (!isV5UpgradeEnforced && tx.HasZerocoinSpendInputs()) {
1550 0 : if (!ParseAndValidateZerocoinSpends(consensus, tx, pindex->nHeight, state, vSpends)) {
1551 : return false; // Invalidity/DoS is handled by the function.
1552 : }
1553 485352 : } else if (!tx.IsCoinBase()) {
1554 428909 : if (!view.HaveInputs(tx)) {
1555 42 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-missingorspent");
1556 : }
1557 : // Sapling: are the sapling spends' requirements met in tx(valid anchors/nullifiers)?
1558 428895 : if (!view.HaveShieldedRequirements(tx))
1559 3 : return state.DoS(100, error("%s: spends requirements not met", __func__),
1560 : REJECT_INVALID, "bad-txns-sapling-requirements-not-met");
1561 :
1562 : // Add in sigops done by pay-to-script-hash inputs;
1563 : // this is to prevent a "rogue miner" from creating
1564 : // an incredibly-expensive-to-validate block.
1565 428894 : nSigOps += GetP2SHSigOpCount(tx, view);
1566 428894 : if (nSigOps > nMaxBlockSigOps)
1567 0 : return state.DoS(100, error("ConnectBlock() : too many sigops"), REJECT_INVALID, "bad-blk-sigops");
1568 :
1569 : }
1570 :
1571 : // Cache the sig ser hashes
1572 485337 : precomTxData.emplace_back(tx);
1573 :
1574 485337 : CAmount txValueOut = tx.GetValueOut();
1575 485337 : if (!tx.IsCoinBase()) {
1576 428894 : CAmount txValueIn = view.GetValueIn(tx);
1577 428894 : if (!tx.IsCoinStake())
1578 420338 : nFees += txValueIn - txValueOut;
1579 428894 : nValueIn += txValueIn;
1580 :
1581 428894 : std::vector<CScriptCheck> vChecks;
1582 428894 : unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG;
1583 428894 : if (fCLTVIsActivated)
1584 428894 : flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
1585 428894 : if (exchangeAddrActivated)
1586 352876 : flags |= SCRIPT_VERIFY_EXCHANGEADDR;
1587 :
1588 428894 : bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
1589 428894 : if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, precomTxData[i], nScriptCheckThreads ? &vChecks : nullptr))
1590 12 : return error("%s: Check inputs on %s failed with %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
1591 857780 : control.Add(vChecks);
1592 : }
1593 485333 : nValueOut += txValueOut;
1594 :
1595 970666 : CTxUndo undoDummy;
1596 485333 : if (i > 0) {
1597 428890 : blockundo.vtxundo.emplace_back();
1598 : }
1599 485333 : const bool fSkipInvalid = SkipInvalidUTXOS(pindex->nHeight);
1600 485333 : UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight, fSkipInvalid);
1601 :
1602 : // Sapling update tree
1603 487485 : if (tx.IsShieldedTx() && !tx.sapData->vShieldedOutput.empty()) {
1604 4571 : for(const OutputDescription &outputDescription : tx.sapData->vShieldedOutput) {
1605 2425 : sapling_tree.append(outputDescription.cmu);
1606 : }
1607 : }
1608 :
1609 485333 : vPos.emplace_back(tx.GetHash(), pos);
1610 485333 : pos.nTxOffset += ::GetSerializeSize(tx, CLIENT_VERSION);
1611 : }
1612 :
1613 : // Push new tree anchor
1614 56422 : view.PushAnchor(sapling_tree);
1615 :
1616 : // Verify header correctness
1617 56422 : if (isV5UpgradeEnforced) {
1618 : // If Sapling is active, block.hashFinalSaplingRoot must be the
1619 : // same as the root of the Sapling tree
1620 24547 : if (block.hashFinalSaplingRoot != sapling_tree.root()) {
1621 0 : return state.DoS(100,
1622 0 : error("ConnectBlock(): block's hashFinalSaplingRoot is incorrect (should be Sapling tree root)"),
1623 : REJECT_INVALID, "bad-sapling-root-in-block");
1624 : }
1625 : }
1626 :
1627 : // track mint amount info
1628 56422 : assert(nFees >= 0);
1629 56422 : const int64_t nMint = (nValueOut - nValueIn) + nFees;
1630 :
1631 56422 : int64_t nTime1 = GetTimeMicros();
1632 56422 : nTimeConnect += nTime1 - nTimeStart;
1633 56422 : LogPrint(BCLog::BENCHMARK, " - 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);
1634 :
1635 : //PoW phase redistributed fees to miner. PoS stage destroys fees.
1636 56422 : CAmount nExpectedMint = GetBlockValue(pindex->nHeight);
1637 56422 : if (!isPoSBlock)
1638 47866 : nExpectedMint += nFees;
1639 :
1640 : //Check that the block does not overmint
1641 56422 : CAmount nBudgetAmt = 0; // If this is a superblock, amount to be paid to the winning proposal, otherwise 0
1642 56422 : if (!IsBlockValueValid(pindex->nHeight, nExpectedMint, nMint, nBudgetAmt)) {
1643 24 : return state.DoS(100, error("%s: reward pays too much (actual=%s vs limit=%s)",
1644 12 : __func__, FormatMoney(nMint), FormatMoney(nExpectedMint)),
1645 : REJECT_INVALID, "bad-blk-amount");
1646 : }
1647 :
1648 : // Masternode/Budget payments
1649 : // !TODO: after transition to DMN is complete, check this also during IBD
1650 56416 : if (!fInitialBlockDownload) {
1651 55624 : if (!IsBlockPayeeValid(block, pindex->pprev)) {
1652 6 : mapRejectedBlocks.emplace(block.GetHash(), GetTime());
1653 18 : return state.DoS(0, false, REJECT_INVALID, "bad-cb-payee", false, "Couldn't find masternode/budget payment");
1654 : }
1655 : }
1656 :
1657 : // After v6 enforcement: Check that the coinbase pays the exact amount
1658 56410 : if (isPoSBlock && isV6UpgradeEnforced && !IsCoinbaseValueValid(block.vtx[0], nBudgetAmt, state)) {
1659 : // pass the state returned by the function above
1660 : return false;
1661 : }
1662 :
1663 112820 : if (!control.Wait())
1664 3 : return state.DoS(100, error("%s: CheckQueue failed", __func__), REJECT_INVALID, "block-validation-failed");
1665 56409 : int64_t nTime2 = GetTimeMicros();
1666 56409 : nTimeVerify += nTime2 - nTimeStart;
1667 56409 : LogPrint(BCLog::BENCHMARK, " - 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);
1668 :
1669 56409 : if (!ProcessSpecialTxsInBlock(block, pindex, &view, state, fJustCheck)) {
1670 27 : return error("%s: Special tx processing failed with %s", __func__, FormatStateMessage(state));
1671 : }
1672 56394 : int64_t nTime3 = GetTimeMicros();
1673 56394 : nTimeProcessSpecial += nTime3 - nTime2;
1674 56394 : LogPrint(BCLog::BENCHMARK, " - Process special tx: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeProcessSpecial * 0.000001);
1675 :
1676 : //IMPORTANT NOTE: Nothing before this point should actually store to disk (or even memory)
1677 56394 : if (fJustCheck)
1678 : return true;
1679 :
1680 : // Write undo information to disk
1681 41250 : if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
1682 41065 : if (pindex->GetUndoPos().IsNull()) {
1683 41065 : FlatFilePos diskPosBlock;
1684 41065 : if (!FindUndoPos(state, pindex->nFile, diskPosBlock, ::GetSerializeSize(blockundo, CLIENT_VERSION) + 40))
1685 0 : return error("ConnectBlock() : FindUndoPos failed");
1686 41065 : if (!UndoWriteToDisk(blockundo, diskPosBlock, pindex->pprev->GetBlockHash()))
1687 0 : return AbortNode(state, "Failed to write undo data");
1688 :
1689 : // update nUndoPos in block index
1690 41065 : pindex->nUndoPos = diskPosBlock.nPos;
1691 41065 : pindex->nStatus |= BLOCK_HAVE_UNDO;
1692 : }
1693 :
1694 41065 : pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
1695 41065 : setDirtyBlockIndex.insert(pindex);
1696 : }
1697 :
1698 : // Flush spend/mint info to disk
1699 41250 : if (!vSpends.empty() && !zerocoinDB->WriteCoinSpendBatch(vSpends))
1700 0 : return AbortNode(state, "Failed to record coin serials to database");
1701 :
1702 41250 : if (fTxIndex)
1703 41250 : if (!pblocktree->WriteTxIndex(vPos))
1704 0 : return AbortNode(state, "Failed to write transaction index");
1705 :
1706 : // add this block to the view's block chain
1707 41250 : view.SetBestBlock(pindex->GetBlockHash());
1708 41250 : evoDb->WriteBestBlock(pindex->GetBlockHash());
1709 :
1710 41250 : int64_t nTime4 = GetTimeMicros();
1711 41250 : nTimeIndex += nTime4 - nTime3;
1712 41250 : LogPrint(BCLog::BENCHMARK, " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeIndex * 0.000001);
1713 :
1714 41250 : if (consensus.NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_ZC_V2) &&
1715 4967 : pindex->nHeight < consensus.height_last_ZC_AccumCheckpoint) {
1716 : // Legacy Zerocoin DB: If Accumulators Checkpoint is changed, cache the checksums
1717 248 : CacheAccChecksum(pindex, true);
1718 : // Clean coinspends cache every 50k blocks, so it does not grow unnecessarily
1719 248 : if (pindex->nHeight % 50000 == 0) {
1720 0 : ZPIVModule::CleanCoinSpendsCache();
1721 : }
1722 41002 : } else if (accumulatorCache && pindex->nHeight > consensus.height_last_ZC_AccumCheckpoint + 100) {
1723 : // 100 blocks After last Checkpoint block, wipe the checksum database and cache
1724 19 : accumulatorCache->Wipe();
1725 19 : accumulatorCache.reset();
1726 19 : ZPIVModule::CleanCoinSpendsCache();
1727 : }
1728 :
1729 : // 100 blocks after the last invalid out, clean the map contents
1730 41250 : if (pindex->nHeight == consensus.height_last_invalid_UTXO + 100) {
1731 56602 : invalid_out::setInvalidOutPoints.clear();
1732 : }
1733 :
1734 : return true;
1735 : }
1736 :
1737 : /**
1738 : * Update the on-disk chain state.
1739 : * The caches and indexes are flushed if either they're too large, forceWrite is set, or
1740 : * fast is not set and it's been a while since the last write.
1741 : * Full flush also updates the money supply from disk (except during shutdown)
1742 : */
1743 262079 : bool static FlushStateToDisk(CValidationState& state, FlushStateMode mode)
1744 : {
1745 262079 : int64_t nMempoolUsage = mempool.DynamicMemoryUsage();
1746 524158 : LOCK(cs_main);
1747 262079 : static int64_t nLastWrite = 0;
1748 262079 : static int64_t nLastFlush = 0;
1749 262079 : static int64_t nLastSetChain = 0;
1750 262079 : try {
1751 262079 : int64_t nNow = GetTimeMicros();
1752 : // Avoid writing/flushing immediately after startup.
1753 262079 : if (nLastWrite == 0) {
1754 390 : nLastWrite = nNow;
1755 : }
1756 262079 : if (nLastFlush == 0) {
1757 390 : nLastFlush = nNow;
1758 : }
1759 262079 : if (nLastSetChain == 0) {
1760 390 : nLastSetChain = nNow;
1761 : }
1762 262079 : int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1763 262079 : int64_t cacheSize = pcoinsTip->DynamicMemoryUsage();
1764 262079 : int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
1765 : // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now
1766 : // (not in the middle of a block processing).
1767 262079 : bool fCacheLarge = mode == FLUSH_STATE_PERIODIC &&
1768 438751 : cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
1769 : // The cache is over the limit, we have to write now.
1770 262079 : bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && (unsigned) cacheSize > nCoinCacheUsage;
1771 : // The evoDB cache is too large, time to write
1772 262079 : bool fEvoDbCacheCritical = mode == FLUSH_STATE_IF_NEEDED && evoDb != nullptr && evoDb->GetMemoryUsage() >= (64 << 20);
1773 : // It's been a while since we wrote the block index to disk.
1774 : // Do this frequently, so we don't need to redownload after a crash.
1775 262079 : bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
1776 : // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
1777 262079 : bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
1778 : // Combine all conditions that result in a full cache flush.
1779 262079 : bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fEvoDbCacheCritical || fPeriodicFlush;
1780 : // Write blocks and block index to disk.
1781 262079 : if (fDoFullFlush || fPeriodicWrite) {
1782 : // Depend on nMinDiskSpace to ensure we can write block index
1783 807 : if (!CheckDiskSpace(GetBlocksDir())) {
1784 0 : return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!"));
1785 : }
1786 : // First make sure all block and undo data is flushed to disk.
1787 807 : FlushBlockFile();
1788 : // Then update all block file information (which may refer to block and undo files).
1789 807 : {
1790 807 : std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
1791 807 : vFiles.reserve(setDirtyFileInfo.size());
1792 1136 : for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
1793 329 : vFiles.emplace_back(*it, &vinfoBlockFile[*it]);
1794 329 : setDirtyFileInfo.erase(it++);
1795 : }
1796 1614 : std::vector<const CBlockIndex*> vBlocks;
1797 807 : vBlocks.reserve(setDirtyBlockIndex.size());
1798 40043 : for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
1799 39236 : vBlocks.push_back(*it);
1800 39236 : setDirtyBlockIndex.erase(it++);
1801 : }
1802 807 : if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
1803 0 : return AbortNode(state, "Files to write to block index database");
1804 : }
1805 : }
1806 : // Flush zerocoin accumulator checkpoints cache
1807 807 : if (accumulatorCache) accumulatorCache->Flush();
1808 :
1809 807 : nLastWrite = nNow;
1810 : }
1811 :
1812 : // Flush best chain related state. This can only be done if the blocks / block index write was also done.
1813 262886 : if (fDoFullFlush && !pcoinsTip->GetBestBlock().IsNull()) {
1814 : // Typical Coin structures on disk are around 48 bytes in size.
1815 : // Pushing a new one to the database can cause it to be written
1816 : // twice (once in the log, and once in the tables). This is already
1817 : // an overestimation, as most will delete an existing entry or
1818 : // overwrite one. Still, use a conservative safety factor of 2.
1819 807 : if (!CheckDiskSpace(GetDataDir(), 48 * 2 * 2 * pcoinsTip->GetCacheSize())) {
1820 0 : return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!"));
1821 : }
1822 : // Flush the chainstate (which may refer to block index entries).
1823 807 : if (!pcoinsTip->Flush())
1824 0 : return AbortNode(state, "Failed to write to coin database");
1825 807 : if (!evoDb->CommitRootTransaction()) {
1826 0 : return AbortNode(state, "Failed to commit EvoDB");
1827 : }
1828 807 : nLastFlush = nNow;
1829 : // Update money supply on memory, reading data from disk
1830 807 : if (!ShutdownRequested() && !IsInitialBlockDownload()) {
1831 92 : MoneySupply.Update(pcoinsTip->GetTotalAmount(), chainActive.Height());
1832 : }
1833 : }
1834 262079 : if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
1835 : // Update best block in wallet (so we can detect restored wallets).
1836 0 : GetMainSignals().SetBestChain(chainActive.GetLocator());
1837 0 : nLastSetChain = nNow;
1838 : }
1839 :
1840 0 : } catch (const std::runtime_error& e) {
1841 0 : return AbortNode(state, std::string("System error while flushing: ") + e.what());
1842 : }
1843 : return true;
1844 : }
1845 :
1846 800 : void FlushStateToDisk()
1847 : {
1848 800 : CValidationState state;
1849 800 : FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
1850 800 : }
1851 :
1852 : /** Update chainActive and related internal data structures. */
1853 41897 : void static UpdateTip(CBlockIndex* pindexNew)
1854 : {
1855 41897 : AssertLockHeld(cs_main);
1856 41897 : chainActive.SetTip(pindexNew);
1857 :
1858 : // New best block
1859 41897 : mempool.AddTransactionsUpdated(1);
1860 :
1861 41897 : {
1862 41897 : LOCK(g_best_block_mutex);
1863 41897 : g_best_block = pindexNew->GetBlockHash();
1864 41897 : g_best_block_time = pindexNew->GetBlockTime();
1865 41897 : g_best_block_cv.notify_all();
1866 : }
1867 :
1868 41897 : const CBlockIndex* pChainTip = chainActive.Tip();
1869 41897 : assert(pChainTip != nullptr);
1870 83794 : LogPrintf("%s: new best=%s height=%d version=%d log2_work=%.16f tx=%lu date=%s progress=%f cache=%.1fMiB(%utxo) evodb_cache=%.1fMiB\n",
1871 : __func__,
1872 83794 : pChainTip->GetBlockHash().GetHex(), pChainTip->nHeight, pChainTip->nVersion, log(pChainTip->nChainWork.getdouble()) / log(2.0), (unsigned long)pChainTip->nChainTx,
1873 41897 : FormatISO8601DateTime(pChainTip->GetBlockTime()),
1874 41897 : Checkpoints::GuessVerificationProgress(pChainTip), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize(),
1875 41897 : evoDb->GetMemoryUsage() * (1.0 / (1<<20)));
1876 :
1877 : // Check the version of the last 100 blocks to see if we need to upgrade:
1878 41897 : static bool fWarned = false;
1879 41897 : if (!IsInitialBlockDownload() && !fWarned) {
1880 41091 : int nUpgraded = 0;
1881 41091 : const CBlockIndex* pindex = pChainTip;
1882 3387253 : for (int i = 0; i < 100 && pindex != nullptr; i++) {
1883 3346165 : if (pindex->nVersion > CBlock::CURRENT_VERSION)
1884 2652 : ++nUpgraded;
1885 3346165 : pindex = pindex->pprev;
1886 : }
1887 41091 : if (nUpgraded > 0)
1888 102 : LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION);
1889 41091 : if (nUpgraded > 100 / 2) {
1890 4 : std::string strWarning = _("Warning: This version is obsolete, upgrade required!");
1891 2 : SetMiscWarning(strWarning);
1892 2 : if (!fWarned) {
1893 2 : AlertNotify(strWarning);
1894 2 : fWarned = true;
1895 : }
1896 : }
1897 : }
1898 41897 : }
1899 :
1900 : /** Disconnect chainActive's tip.
1901 : * After calling, the mempool will be in an inconsistent state, with
1902 : * transactions from disconnected blocks being added to disconnectpool. You
1903 : * should make the mempool consistent again by calling UpdateMempoolForReorg.
1904 : * with cs_main held.
1905 : *
1906 : * If disconnectpool is nullptr, then no disconnected transactions are added to
1907 : * disconnectpool (note that the caller is responsible for mempool consistency
1908 : * in any case).
1909 : */
1910 330 : bool static DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions *disconnectpool)
1911 : {
1912 330 : AssertLockHeld(cs_main);
1913 330 : AssertLockHeld(mempool.cs);
1914 330 : CBlockIndex* pindexDelete = chainActive.Tip();
1915 330 : assert(pindexDelete);
1916 : // Read block from disk.
1917 660 : std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
1918 330 : CBlock& block = *pblock;
1919 330 : if (!ReadBlockFromDisk(block, pindexDelete))
1920 0 : return error("%s: Failed to read block", __func__);
1921 : // Apply the block atomically to the chain state.
1922 330 : const uint256& saplingAnchorBeforeDisconnect = pcoinsTip->GetBestAnchor();
1923 330 : int64_t nStart = GetTimeMicros();
1924 330 : {
1925 659 : auto dbTx = evoDb->BeginTransaction();
1926 :
1927 659 : CCoinsViewCache view(pcoinsTip.get());
1928 330 : assert(view.GetBestBlock() == pindexDelete->GetBlockHash());
1929 330 : if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK)
1930 2 : return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
1931 329 : bool flushed = view.Flush();
1932 329 : assert(flushed);
1933 329 : dbTx->Commit();
1934 : }
1935 329 : LogPrint(BCLog::BENCHMARK, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
1936 329 : const uint256& saplingAnchorAfterDisconnect = pcoinsTip->GetBestAnchor();
1937 : // Write the chain state to disk, if necessary.
1938 329 : if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
1939 : return false;
1940 329 : if (disconnectpool) {
1941 : // Save transactions to re-add to mempool at end of reorg
1942 89004 : for (auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
1943 88675 : disconnectpool->addTransaction(*it);
1944 : }
1945 10176 : while (disconnectpool->DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) {
1946 : // Drop the earliest entry, and remove its children from the mempool.
1947 9847 : auto it = disconnectpool->queuedTx.get<insertion_order>().begin();
1948 9847 : mempool.removeRecursive(**it, MemPoolRemovalReason::REORG);
1949 9847 : disconnectpool->removeEntry(it);
1950 : }
1951 : }
1952 :
1953 : // Evict from mempool if the anchor changes
1954 329 : if (saplingAnchorBeforeDisconnect != saplingAnchorAfterDisconnect) {
1955 : // The anchor may not change between block disconnects,
1956 : // in which case we don't want to evict from the mempool yet!
1957 4 : mempool.removeWithAnchor(saplingAnchorBeforeDisconnect);
1958 : }
1959 : // Update chainActive and related variables.
1960 329 : UpdateTip(pindexDelete->pprev);
1961 : // Let wallets know transactions went from 1-confirmed to
1962 : // 0-confirmed or conflicted:
1963 329 : GetMainSignals().BlockDisconnected(pblock, pindexDelete->GetBlockHash(), pindexDelete->nHeight, pindexDelete->GetBlockTime());
1964 :
1965 : // Update MN manager cache
1966 329 : deterministicMNManager->SetTipIndex(pindexDelete->pprev);
1967 : // replace the cached hash of pindexDelete with the hash of the block
1968 : // at depth CACHED_BLOCK_HASHES if it exists, or empty hash otherwise.
1969 329 : if ((unsigned) pindexDelete->nHeight >= CACHED_BLOCK_HASHES) {
1970 326 : mnodeman.CacheBlockHash(chainActive[pindexDelete->nHeight - CACHED_BLOCK_HASHES]);
1971 : } else {
1972 166 : mnodeman.UncacheBlockHash(pindexDelete);
1973 : }
1974 :
1975 : return true;
1976 : }
1977 :
1978 : static int64_t nTimeReadFromDisk = 0;
1979 : static int64_t nTimeConnectTotal = 0;
1980 : static int64_t nTimeFlush = 0;
1981 : static int64_t nTimeChainState = 0;
1982 : static int64_t nTimePostConnect = 0;
1983 :
1984 166730 : struct PerBlockConnectTrace {
1985 : CBlockIndex* pindex = nullptr;
1986 : std::shared_ptr<const CBlock> pblock;
1987 83568 : PerBlockConnectTrace() {}
1988 : };
1989 : /**
1990 : * Used to track blocks whose transactions were applied to the UTXO state as a
1991 : * part of a single ActivateBestChainStep call.
1992 : *
1993 : * This class is single-use, once you call GetBlocksConnected() you have to throw
1994 : * it away and make a new one.
1995 : */
1996 476 : class ConnectTrace {
1997 : private:
1998 : std::vector<PerBlockConnectTrace> blocksConnected;
1999 :
2000 : public:
2001 84000 : ConnectTrace() : blocksConnected(1) {}
2002 :
2003 41568 : void BlockConnected(CBlockIndex* pindex, std::shared_ptr<const CBlock> pblock) {
2004 41568 : assert(!blocksConnected.back().pindex);
2005 41568 : assert(pindex);
2006 41568 : assert(pblock);
2007 41568 : blocksConnected.back().pindex = pindex;
2008 41568 : blocksConnected.back().pblock = std::move(pblock);
2009 41568 : blocksConnected.emplace_back();
2010 41568 : }
2011 :
2012 41523 : std::vector<PerBlockConnectTrace>& GetBlocksConnected() {
2013 : // We always keep one extra block at the end of our list because
2014 : // blocks are added after all the conflicted transactions have
2015 : // been filled in. Thus, the last entry should always be an empty
2016 : // one waiting for the transactions from the next block. We pop
2017 : // the last entry here to make sure the list we return is sane.
2018 41523 : assert(!blocksConnected.back().pindex);
2019 41523 : blocksConnected.pop_back();
2020 41523 : return blocksConnected;
2021 : }
2022 : };
2023 :
2024 : /**
2025 : * Connect a new block to chainActive. pblock is either nullptr or a pointer to a CBlock
2026 : * corresponding to pindexNew, to bypass loading it again from disk.
2027 : *
2028 : * The block is added to connectTrace if connection succeeds.
2029 : */
2030 41614 : bool static ConnectTip(CValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
2031 : {
2032 41614 : AssertLockHeld(cs_main);
2033 41614 : AssertLockHeld(mempool.cs);
2034 82910 : assert(pindexNew->pprev == chainActive.Tip());
2035 :
2036 : // Read block from disk.
2037 41614 : int64_t nTime1 = GetTimeMicros();
2038 41614 : std::shared_ptr<const CBlock> pthisBlock;
2039 41614 : if (!pblock) {
2040 1182 : std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2041 591 : if (!ReadBlockFromDisk(*pblockNew, pindexNew))
2042 0 : return AbortNode(state, "Failed to read block");
2043 591 : pthisBlock = pblockNew;
2044 : } else {
2045 41023 : pthisBlock = pblock;
2046 : }
2047 41614 : const CBlock& blockConnecting = *pthisBlock;
2048 :
2049 : // Apply the block atomically to the chain state.
2050 41614 : int64_t nTime2 = GetTimeMicros();
2051 41614 : nTimeReadFromDisk += nTime2 - nTime1;
2052 41614 : int64_t nTime3;
2053 41614 : LogPrint(BCLog::BENCHMARK, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
2054 41614 : {
2055 83182 : auto dbTx = evoDb->BeginTransaction();
2056 :
2057 83182 : CCoinsViewCache view(pcoinsTip.get());
2058 41614 : bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, false);
2059 41614 : GetMainSignals().BlockChecked(blockConnecting, state);
2060 41614 : if (!rv) {
2061 46 : if (state.IsInvalid())
2062 46 : InvalidBlockFound(pindexNew, state);
2063 127 : return error("%s: ConnectBlock %s failed, %s", __func__, pindexNew->GetBlockHash().ToString(), FormatStateMessage(state));
2064 : }
2065 41568 : nTime3 = GetTimeMicros();
2066 41568 : nTimeConnectTotal += nTime3 - nTime2;
2067 41568 : LogPrint(BCLog::BENCHMARK, " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
2068 41568 : bool flushed = view.Flush();
2069 41568 : assert(flushed);
2070 41568 : dbTx->Commit();
2071 : }
2072 41568 : int64_t nTime4 = GetTimeMicros();
2073 41568 : nTimeFlush += nTime4 - nTime3;
2074 41568 : LogPrint(BCLog::BENCHMARK, " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
2075 :
2076 : // Write the chain state to disk, if necessary. Always write to disk if this is the first of a new file.
2077 41568 : FlushStateMode flushMode = FLUSH_STATE_IF_NEEDED;
2078 41568 : if (pindexNew->pprev && (pindexNew->GetBlockPos().nFile != pindexNew->pprev->GetBlockPos().nFile))
2079 : flushMode = FLUSH_STATE_ALWAYS;
2080 41568 : if (!FlushStateToDisk(state, flushMode))
2081 : return false;
2082 41568 : int64_t nTime5 = GetTimeMicros();
2083 41568 : nTimeChainState += nTime5 - nTime4;
2084 41568 : LogPrint(BCLog::BENCHMARK, " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
2085 :
2086 : // Remove conflicting transactions from the mempool.
2087 41568 : mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight);
2088 41568 : disconnectpool.removeForBlock(blockConnecting.vtx);
2089 : // Update chainActive & related variables.
2090 41568 : UpdateTip(pindexNew);
2091 : // Update TierTwo managers
2092 41568 : mnodeman.SetBestHeight(pindexNew->nHeight);
2093 41568 : g_budgetman.SetBestHeight(pindexNew->nHeight);
2094 : // Update MN manager cache
2095 41568 : mnodeman.CacheBlockHash(pindexNew);
2096 41568 : mnodeman.CheckSpentCollaterals(blockConnecting.vtx);
2097 41568 : deterministicMNManager->SetTipIndex(pindexNew);
2098 :
2099 41568 : int64_t nTime6 = GetTimeMicros();
2100 41568 : nTimePostConnect += nTime6 - nTime5;
2101 41568 : nTimeTotal += nTime6 - nTime1;
2102 41568 : LogPrint(BCLog::BENCHMARK, " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
2103 41568 : LogPrint(BCLog::BENCHMARK, "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
2104 :
2105 41568 : connectTrace.BlockConnected(pindexNew, std::move(pthisBlock));
2106 41568 : return true;
2107 : }
2108 :
2109 : /**
2110 : * Return the tip of the chain with the most work in it, that isn't
2111 : * known to be invalid (it's however far from certain to be valid).
2112 : */
2113 41834 : static CBlockIndex* FindMostWorkChain()
2114 : {
2115 41840 : do {
2116 41837 : CBlockIndex* pindexNew = nullptr;
2117 :
2118 : // Find the best candidate header.
2119 41837 : {
2120 41837 : std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
2121 41837 : if (it == setBlockIndexCandidates.rend())
2122 : return nullptr;
2123 41837 : pindexNew = *it;
2124 : }
2125 :
2126 : // Check whether all blocks on the path between the currently active chain and the candidate are valid.
2127 : // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
2128 41837 : CBlockIndex* pindexTest = pindexNew;
2129 41837 : bool fInvalidAncestor = false;
2130 166604 : while (pindexTest && !chainActive.Contains(pindexTest)) {
2131 41627 : assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
2132 :
2133 : // Pruned nodes may have entries in setBlockIndexCandidates for
2134 : // which block files have been deleted. Remove those as candidates
2135 : // for the most work chain if we come across them; we can't switch
2136 : // to a chain unless we have all the non-active-chain parent blocks.
2137 41627 : bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
2138 41627 : bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
2139 41627 : if (fFailedChain || fMissingData) {
2140 : // Candidate chain is not usable (either invalid or missing data)
2141 3 : if (fFailedChain && (pindexBestInvalid == nullptr || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
2142 0 : pindexBestInvalid = pindexNew;
2143 3 : CBlockIndex* pindexFailed = pindexNew;
2144 : // Remove the entire chain from the set.
2145 6 : while (pindexTest != pindexFailed) {
2146 3 : if (fFailedChain) {
2147 3 : pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
2148 0 : } else if (fMissingData) {
2149 : // If we're missing data, then add back to mapBlocksUnlinked,
2150 : // so that if the block arrives in the future we can try adding
2151 : // to setBlockIndexCandidates again.
2152 0 : mapBlocksUnlinked.emplace(pindexFailed->pprev, pindexFailed);
2153 : }
2154 3 : setBlockIndexCandidates.erase(pindexFailed);
2155 3 : pindexFailed = pindexFailed->pprev;
2156 : }
2157 3 : setBlockIndexCandidates.erase(pindexTest);
2158 3 : fInvalidAncestor = true;
2159 3 : break;
2160 : }
2161 41624 : pindexTest = pindexTest->pprev;
2162 : }
2163 3 : if (!fInvalidAncestor)
2164 3 : return pindexNew;
2165 : } while (true);
2166 : }
2167 :
2168 : /** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
2169 41725 : static void PruneBlockIndexCandidates()
2170 : {
2171 : // Note that we can't delete the current block itself, as we may need to return to it later in case a
2172 : // reorganization to a better block fails.
2173 41725 : std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
2174 231002 : while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
2175 73776 : setBlockIndexCandidates.erase(it++);
2176 : }
2177 : // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
2178 41725 : assert(!setBlockIndexCandidates.empty());
2179 41725 : }
2180 :
2181 : /**
2182 : * Try to make some progress towards making pindexMostWork the active block.
2183 : * pblock is either nullptr or a pointer to a CBlock corresponding to pindexMostWork.
2184 : */
2185 41524 : static bool ActivateBestChainStep(CValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
2186 : {
2187 41524 : AssertLockHeld(cs_main);
2188 41524 : AssertLockHeld(mempool.cs);
2189 41524 : const CBlockIndex* pindexOldTip = chainActive.Tip();
2190 41524 : const CBlockIndex* pindexFork = chainActive.FindFork(pindexMostWork);
2191 :
2192 : // Disconnect active blocks which are no longer in the best chain.
2193 41524 : bool fBlocksDisconnected = false;
2194 41524 : DisconnectedBlockTransactions disconnectpool;
2195 41621 : while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
2196 98 : if (!DisconnectTip(state, Params(), &disconnectpool)) {
2197 : // This is likely a fatal error, but keep the mempool consistent,
2198 : // just in case. Only remove from the mempool in this case.
2199 1 : UpdateMempoolForReorg(disconnectpool, false);
2200 :
2201 : // If we're unable to disconnect a block during normal operation,
2202 : // then that is a failure of our local system -- we should abort
2203 : // rather than stay on a less work chain.
2204 2 : return AbortNode(state, "Failed to disconnect block; see debug.log for details");
2205 : }
2206 : fBlocksDisconnected = true;
2207 : }
2208 :
2209 : // Build list of new blocks to connect.
2210 83047 : std::vector<CBlockIndex*> vpindexToConnect;
2211 41523 : bool fContinue = true;
2212 41523 : int nHeight = pindexFork ? pindexFork->nHeight : -1;
2213 83046 : while (fContinue && nHeight != pindexMostWork->nHeight) {
2214 : // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
2215 : // a few blocks along the way.
2216 41523 : int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
2217 41523 : vpindexToConnect.clear();
2218 41523 : vpindexToConnect.reserve(nTargetHeight - nHeight);
2219 41523 : CBlockIndex* pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
2220 87096 : while (pindexIter && pindexIter->nHeight != nHeight) {
2221 45573 : vpindexToConnect.push_back(pindexIter);
2222 45573 : pindexIter = pindexIter->pprev;
2223 : }
2224 41523 : nHeight = nTargetHeight;
2225 :
2226 : // Connect new blocks.
2227 41617 : for (CBlockIndex* pindexConnect : reverse_iterate(vpindexToConnect)) {
2228 124251 : if (!ConnectTip(state, pindexConnect, (pindexConnect == pindexMostWork) ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2229 46 : if (state.IsInvalid()) {
2230 : // The block violates a consensus rule.
2231 46 : if (!state.CorruptionPossible()) {
2232 46 : InvalidChainFound(vpindexToConnect.front());
2233 : }
2234 46 : state = CValidationState();
2235 46 : fInvalidFound = true;
2236 46 : fContinue = false;
2237 46 : break;
2238 : } else {
2239 : // A system error occurred (disk space, database error, ...).
2240 : // Make the mempool consistent with the current tip, just in case
2241 : // any observers try to use it before shutdown.
2242 0 : UpdateMempoolForReorg(disconnectpool, false);
2243 0 : return false;
2244 : }
2245 : } else {
2246 41568 : PruneBlockIndexCandidates();
2247 82818 : if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
2248 : // We're in a better position than we were. Return temporarily to release the lock.
2249 : fContinue = false;
2250 : break;
2251 : }
2252 : }
2253 : }
2254 : }
2255 :
2256 41523 : if (fBlocksDisconnected) {
2257 : // If any blocks were disconnected, disconnectpool may be non empty. Add
2258 : // any disconnected transactions back to the mempool.
2259 34 : UpdateMempoolForReorg(disconnectpool, true);
2260 : }
2261 41523 : mempool.check(pcoinsTip.get());
2262 :
2263 : // Callbacks/notifications for a new best chain.
2264 41523 : if (fInvalidFound)
2265 46 : CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
2266 : else
2267 41477 : CheckForkWarningConditions();
2268 :
2269 : return true;
2270 : }
2271 :
2272 : /**
2273 : * Make the best chain active, in multiple steps. The result is either failure
2274 : * or an activated best chain. pblock is either nullptr or a pointer to a block
2275 : * that is already loaded (to avoid loading it again from disk).
2276 : */
2277 :
2278 41788 : bool ActivateBestChain(CValidationState& state, std::shared_ptr<const CBlock> pblock)
2279 : {
2280 : // Note that while we're often called here from ProcessNewBlock, this is
2281 : // far from a guarantee. Things in the P2P/RPC will often end up calling
2282 : // us in the middle of ProcessNewBlock - do not assume pblock is set
2283 : // sanely for performance or correctness!
2284 41788 : AssertLockNotHeld(cs_main);
2285 :
2286 : // ABC maintains a fair degree of expensive-to-calculate internal state
2287 : // because this function periodically releases cs_main so that it does not lock up other threads for too long
2288 : // during large connects - and to allow for e.g. the callback queue to drain
2289 : // we use m_cs_chainstate to enforce mutual exclusion so that only one caller may execute this function at a time
2290 83576 : LOCK(m_cs_chainstate);
2291 :
2292 : CBlockIndex* pindexNewTip = nullptr;
2293 : CBlockIndex* pindexMostWork = nullptr;
2294 41994 : do {
2295 41994 : boost::this_thread::interruption_point();
2296 :
2297 41994 : if (GetMainSignals().CallbacksPending() > 10) {
2298 : // Block until the validation queue drains. This should largely
2299 : // never happen in normal operation, however may happen during
2300 : // reindex, causing memory blowup if we run too far ahead.
2301 186 : SyncWithValidationInterfaceQueue();
2302 : }
2303 :
2304 41994 : {
2305 41994 : LOCK(cs_main);
2306 83511 : LOCK(mempool.cs); // Lock transaction pool for at least as long as it takes for connectTrace to be consumed
2307 41994 : CBlockIndex* starting_tip = chainActive.Tip();
2308 41994 : bool blocks_connected = false;
2309 42000 : do {
2310 : // We absolutely may not unlock cs_main until we've made forward progress
2311 : // (with the exception of shutdown due to hardware issues, low disk space, etc).
2312 42000 : ConnectTrace connectTrace; // Destructed before cs_main is unlocked
2313 :
2314 42000 : if (pindexMostWork == nullptr) {
2315 41834 : pindexMostWork = FindMostWorkChain();
2316 : }
2317 :
2318 : // Whether we have anything to do at all.
2319 84000 : if (pindexMostWork == nullptr || pindexMostWork == chainActive.Tip()) {
2320 : break;
2321 : }
2322 :
2323 41524 : bool fInvalidFound = false;
2324 41523 : std::shared_ptr<const CBlock> nullBlockPtr;
2325 41530 : if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
2326 1 : return false;
2327 41523 : blocks_connected = true;
2328 :
2329 41523 : if (fInvalidFound) {
2330 : // Wipe cache, we may need another branch now.
2331 46 : pindexMostWork = nullptr;
2332 : }
2333 41523 : pindexNewTip = chainActive.Tip();
2334 :
2335 83091 : for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
2336 41568 : assert(trace.pblock && trace.pindex);
2337 41568 : GetMainSignals().BlockConnected(trace.pblock, trace.pindex);
2338 : }
2339 41523 : } while (!chainActive.Tip() || (starting_tip && CBlockIndexWorkComparator()(chainActive.Tip(), starting_tip)));
2340 41993 : if (!blocks_connected) return true;
2341 :
2342 41517 : const CBlockIndex* pindexFork = chainActive.FindFork(starting_tip);
2343 41517 : bool fInitialDownload = IsInitialBlockDownload();
2344 :
2345 : // Notify external listeners about the new tip.
2346 : // Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
2347 41517 : if (pindexFork != pindexNewTip) {
2348 : // Notify ValidationInterface subscribers
2349 41471 : GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
2350 :
2351 : // Always notify the UI if a new block tip was connected
2352 41471 : uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
2353 : }
2354 : }
2355 :
2356 : // We check shutdown only after giving ActivateBestChainStep a chance to run once so that we
2357 : // never shutdown before connecting the genesis block during LoadChainTip(). Previously this
2358 : // caused an assert() failure during shutdown in such cases as the UTXO DB flushing checks
2359 : // that the best block hash is non-null.
2360 41517 : if (ShutdownRequested())
2361 : break;
2362 83032 : } while (pindexMostWork != chainActive.Tip());
2363 :
2364 41311 : CheckBlockIndex();
2365 :
2366 : // Write changes periodically to disk, after relay.
2367 41311 : if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
2368 0 : return false;
2369 : }
2370 :
2371 : return true;
2372 : }
2373 :
2374 31 : bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex)
2375 : {
2376 31 : AssertLockHeld(cs_main);
2377 : // Mark the block itself as invalid.
2378 31 : pindex->nStatus |= BLOCK_FAILED_VALID;
2379 31 : setDirtyBlockIndex.insert(pindex);
2380 31 : setBlockIndexCandidates.erase(pindex);
2381 :
2382 62 : LOCK(mempool.cs); // Lock for as long as disconnectpool is in scope to make sure UpdateMempoolForReorg is called after DisconnectTip without unlocking in between
2383 62 : DisconnectedBlockTransactions disconnectpool;
2384 526 : while (chainActive.Contains(pindex)) {
2385 232 : CBlockIndex* pindexWalk = chainActive.Tip();
2386 232 : pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
2387 232 : setDirtyBlockIndex.insert(pindexWalk);
2388 232 : setBlockIndexCandidates.erase(pindexWalk);
2389 : // ActivateBestChain considers blocks already in chainActive
2390 : // unconditionally valid already, so force disconnect away from it.
2391 232 : if (!DisconnectTip(state, chainparams, &disconnectpool)) {
2392 : // It's probably hopeless to try to make the mempool consistent
2393 : // here if DisconnectTip failed, but we can try.
2394 0 : UpdateMempoolForReorg(disconnectpool, false);
2395 0 : return false;
2396 : }
2397 : }
2398 :
2399 : // DisconnectTip will add transactions to disconnectpool; try to add these
2400 : // back to the mempool.
2401 31 : UpdateMempoolForReorg(disconnectpool, true);
2402 :
2403 : // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
2404 : // add it again.
2405 31 : BlockMap::iterator it = mapBlockIndex.begin();
2406 15516 : while (it != mapBlockIndex.end()) {
2407 30663 : if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
2408 39 : setBlockIndexCandidates.insert(it->second);
2409 : }
2410 15516 : it++;
2411 : }
2412 :
2413 31 : InvalidChainFound(pindex);
2414 : return true;
2415 : }
2416 :
2417 10 : bool ReconsiderBlock(CValidationState& state, CBlockIndex* pindex)
2418 : {
2419 10 : AssertLockHeld(cs_main);
2420 :
2421 10 : int nHeight = pindex->nHeight;
2422 :
2423 : // Remove the invalidity flag from this block and all its descendants.
2424 10 : BlockMap::iterator it = mapBlockIndex.begin();
2425 1730 : while (it != mapBlockIndex.end()) {
2426 1720 : if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
2427 153 : it->second->nStatus &= ~BLOCK_FAILED_MASK;
2428 153 : setDirtyBlockIndex.insert(it->second);
2429 306 : if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
2430 152 : setBlockIndexCandidates.insert(it->second);
2431 : }
2432 153 : if (it->second == pindexBestInvalid) {
2433 : // Reset invalid block marker if it was pointing to one of those.
2434 8 : pindexBestInvalid = nullptr;
2435 : }
2436 : }
2437 1730 : it++;
2438 : }
2439 :
2440 : // Remove the invalidity flag from all ancestors too.
2441 1556 : while (pindex != nullptr) {
2442 1546 : if (pindex->nStatus & BLOCK_FAILED_MASK) {
2443 1 : pindex->nStatus &= ~BLOCK_FAILED_MASK;
2444 1 : setDirtyBlockIndex.insert(pindex);
2445 : }
2446 1546 : pindex = pindex->pprev;
2447 : }
2448 10 : return true;
2449 : }
2450 :
2451 41497 : static CBlockIndex* AddToBlockIndex(const CBlock& block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
2452 : {
2453 41497 : AssertLockHeld(cs_main);
2454 :
2455 : // Check for duplicate
2456 41497 : uint256 hash = block.GetHash();
2457 41497 : CBlockIndex* pindex = LookupBlockIndex(hash);
2458 41497 : if (pindex)
2459 : return pindex;
2460 :
2461 : // Construct new block index object
2462 41497 : CBlockIndex* pindexNew = new CBlockIndex(block);
2463 : // We assign the sequence id to blocks only when the full data is available,
2464 : // to avoid miners withholding blocks but broadcasting headers, to get a
2465 : // competitive advantage.
2466 41497 : pindexNew->nSequenceId = 0;
2467 41497 : BlockMap::iterator mi = mapBlockIndex.emplace(hash, pindexNew).first;
2468 :
2469 41497 : pindexNew->phashBlock = &((*mi).first);
2470 41497 : CBlockIndex* pprev = LookupBlockIndex(block.hashPrevBlock);
2471 41497 : if (pprev) {
2472 41181 : pindexNew->pprev = pprev;
2473 41181 : pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
2474 41181 : pindexNew->BuildSkip();
2475 :
2476 41181 : const Consensus::Params& consensus = Params().GetConsensus();
2477 41181 : if (!consensus.NetworkUpgradeActive(pindexNew->nHeight, Consensus::UPGRADE_V3_4)) {
2478 : // compute and set new V1 stake modifier (entropy bits)
2479 34522 : pindexNew->SetNewStakeModifier();
2480 :
2481 : } else {
2482 : // compute and set new V2 stake modifier (hash of prevout and prevModifier)
2483 6659 : pindexNew->SetNewStakeModifier(block.vtx[1]->vin[0].prevout.hash);
2484 : }
2485 : }
2486 58449 : pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime);
2487 497964 : pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
2488 41497 : pindexNew->RaiseValidity(BLOCK_VALID_TREE);
2489 41497 : if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork)
2490 41253 : pindexBestHeader = pindexNew;
2491 :
2492 41497 : setDirtyBlockIndex.insert(pindexNew);
2493 : // track prevBlockHash -> pindex (multimap)
2494 41497 : if (pindexNew->pprev) {
2495 41181 : mapPrevBlockIndex.emplace(pindexNew->pprev->GetBlockHash(), pindexNew);
2496 : }
2497 :
2498 41497 : return pindexNew;
2499 : }
2500 :
2501 : /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
2502 41476 : bool ReceivedBlockTransactions(const CBlock& block, CValidationState& state, CBlockIndex* pindexNew, const FlatFilePos& pos)
2503 : {
2504 41476 : if (block.IsProofOfStake())
2505 6706 : pindexNew->SetProofOfStake();
2506 41476 : pindexNew->nTx = block.vtx.size();
2507 41476 : pindexNew->nChainTx = 0;
2508 :
2509 : // Sapling
2510 41476 : CAmount saplingValue = 0;
2511 348645 : for (const auto& tx : block.vtx) {
2512 311324 : if (tx->IsShieldedTx()) {
2513 : // Negative valueBalance "takes" money from the transparent value pool
2514 : // and adds it to the Sapling value pool. Positive valueBalance "gives"
2515 : // money to the transparent value pool, removing from the Sapling value
2516 : // pool. So we invert the sign here.
2517 1460 : saplingValue += -tx->sapData->valueBalance;
2518 : }
2519 : }
2520 41476 : pindexNew->nSaplingValue = saplingValue;
2521 41476 : pindexNew->nChainSaplingValue = nullopt;
2522 :
2523 41476 : pindexNew->nFile = pos.nFile;
2524 41476 : pindexNew->nDataPos = pos.nPos;
2525 41476 : pindexNew->nUndoPos = 0;
2526 41476 : pindexNew->nStatus |= BLOCK_HAVE_DATA;
2527 41476 : pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
2528 41476 : setDirtyBlockIndex.insert(pindexNew);
2529 :
2530 41476 : if (pindexNew->pprev == nullptr || pindexNew->pprev->nChainTx) {
2531 : // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
2532 41476 : std::deque<CBlockIndex*> queue;
2533 41476 : queue.push_back(pindexNew);
2534 :
2535 : // Recursively process any descendant blocks that now may be eligible to be connected.
2536 82952 : while (!queue.empty()) {
2537 41476 : CBlockIndex* pindex = queue.front();
2538 41476 : queue.pop_front();
2539 41476 : pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
2540 :
2541 : // Sapling, update chain value
2542 41476 : pindex->SetChainSaplingValue();
2543 :
2544 41476 : {
2545 41476 : LOCK(cs_nBlockSequenceId);
2546 41476 : pindex->nSequenceId = nBlockSequenceId++;
2547 : }
2548 41476 : if (chainActive.Tip() == nullptr || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
2549 41338 : setBlockIndexCandidates.insert(pindex);
2550 : }
2551 41476 : std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
2552 41476 : while (range.first != range.second) {
2553 0 : std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
2554 0 : queue.push_back(it->second);
2555 0 : range.first++;
2556 0 : mapBlocksUnlinked.erase(it);
2557 : }
2558 41476 : }
2559 : } else {
2560 0 : if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
2561 0 : mapBlocksUnlinked.emplace(pindexNew->pprev, pindexNew);
2562 : }
2563 : }
2564 :
2565 41476 : return true;
2566 : }
2567 :
2568 41476 : bool FindBlockPos(CValidationState& state, FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
2569 : {
2570 82952 : LOCK(cs_LastBlockFile);
2571 :
2572 41476 : unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
2573 41476 : if (vinfoBlockFile.size() <= nFile) {
2574 123 : vinfoBlockFile.resize(nFile + 1);
2575 : }
2576 :
2577 41476 : if (!fKnown) {
2578 41133 : while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
2579 1 : nFile++;
2580 1 : if (vinfoBlockFile.size() <= nFile) {
2581 1 : vinfoBlockFile.resize(nFile + 1);
2582 : }
2583 : }
2584 41132 : pos.nFile = nFile;
2585 41132 : pos.nPos = vinfoBlockFile[nFile].nSize;
2586 : }
2587 :
2588 41476 : if ((int)nFile != nLastBlockFile) {
2589 1 : if (!fKnown) {
2590 2 : LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
2591 : }
2592 1 : FlushBlockFile(!fKnown);
2593 1 : nLastBlockFile = nFile;
2594 : }
2595 :
2596 41476 : vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
2597 41476 : if (fKnown)
2598 344 : vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
2599 : else
2600 41132 : vinfoBlockFile[nFile].nSize += nAddSize;
2601 :
2602 41476 : if (!fKnown) {
2603 41132 : bool out_of_space;
2604 41132 : BlockFileSeq().Allocate(pos, nAddSize, out_of_space);
2605 41132 : if (out_of_space) {
2606 0 : return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
2607 : }
2608 : // future: add prunning flag check
2609 : }
2610 :
2611 41476 : setDirtyFileInfo.insert(nFile);
2612 41476 : return true;
2613 : }
2614 :
2615 41065 : bool FindUndoPos(CValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize)
2616 : {
2617 41065 : pos.nFile = nFile;
2618 :
2619 82130 : LOCK(cs_LastBlockFile);
2620 :
2621 41065 : pos.nPos = vinfoBlockFile[nFile].nUndoSize;
2622 41065 : vinfoBlockFile[nFile].nUndoSize += nAddSize;
2623 41065 : setDirtyFileInfo.insert(nFile);
2624 :
2625 41065 : bool out_of_space;
2626 41065 : UndoFileSeq().Allocate(pos, nAddSize, out_of_space);
2627 41065 : if (out_of_space) {
2628 0 : return AbortNode(state, "Disk space is low!", _("Error: Disk space is low!"));
2629 : }
2630 : // future: add prunning flag check
2631 :
2632 : return true;
2633 : }
2634 :
2635 10496 : bool CheckColdStakeFreeOutput(const CTransaction& tx, const int nHeight)
2636 : {
2637 10496 : assert(tx.IsCoinStake());
2638 : // This check applies only to coinstakes spending a P2CS_LOF script.
2639 : // The script-check ensures that all but the first and the last output
2640 : // (if the coinstake has more than 3 outputs) have the same scriptPubKey.
2641 : // If the second script is not a P2CS_LOF, then either this is a "regular"
2642 : // P2PKH stake, or it fails the script verification.
2643 10496 : if (!tx.vout[1].scriptPubKey.IsPayToColdStakingLOF()) {
2644 : return true;
2645 : }
2646 : // If the last output is different, then it can be either a masternode
2647 : // or a budget proposal payment
2648 9 : const unsigned int outs = tx.vout.size();
2649 9 : const CTxOut& lastOut = tx.vout[outs-1];
2650 9 : if (outs >=3 && lastOut.scriptPubKey != tx.vout[outs-2].scriptPubKey) {
2651 1 : if (Params().GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V6_0)) {
2652 : // after v6.0, masternode and budgets are paid in the coinbase. No more free outputs allowed.
2653 : return false;
2654 : }
2655 1 : if (lastOut.nValue == GetMasternodePayment(nHeight))
2656 : return true;
2657 :
2658 : // if mnsync is incomplete, we cannot verify if this is a budget block.
2659 : // so we check that the staker is not transferring value to the free output
2660 1 : if (!g_tiertwo_sync_state.IsSynced()) {
2661 : // First try finding the previous transaction in database
2662 0 : CTransactionRef txPrev; uint256 hashBlock;
2663 0 : if (!GetTransaction(tx.vin[0].prevout.hash, txPrev, hashBlock, true))
2664 0 : return error("%s : read txPrev failed: %s", __func__, tx.vin[0].prevout.hash.GetHex());
2665 0 : CAmount amtIn = txPrev->vout[tx.vin[0].prevout.n].nValue + GetBlockValue(nHeight);
2666 0 : CAmount amtOut = 0;
2667 0 : for (unsigned int i = 1; i < outs-1; i++) amtOut += tx.vout[i].nValue;
2668 0 : if (amtOut != amtIn)
2669 0 : return error("%s: non-free outputs value %d less than required %d", __func__, amtOut, amtIn);
2670 : return true;
2671 : }
2672 :
2673 : // Check that this is indeed a superblock.
2674 1 : if (g_budgetman.IsBudgetPaymentBlock(nHeight)) {
2675 : // if superblocks are not enabled, reject
2676 0 : if (!sporkManager.IsSporkActive(SPORK_13_ENABLE_SUPERBLOCKS))
2677 0 : return error("%s: superblocks are not enabled", __func__);
2678 : return true;
2679 : }
2680 :
2681 : // wrong free output
2682 2 : return error("%s: Wrong cold staking outputs: vout[%d].scriptPubKey (%s) != vout[%d].scriptPubKey (%s) - value: %s",
2683 5 : __func__, outs-1, HexStr(lastOut.scriptPubKey), outs-2, HexStr(tx.vout[outs-2].scriptPubKey), FormatMoney(lastOut.nValue).c_str());
2684 : }
2685 :
2686 : return true;
2687 : }
2688 :
2689 : // cumulative size of all shielded txes inside a block
2690 180 : static unsigned int GetTotalShieldedTxSize(const CBlock& block)
2691 : {
2692 180 : unsigned int nSizeShielded = 0;
2693 573443 : for (const auto& tx : block.vtx) {
2694 573263 : if (tx->IsShieldedTx()) nSizeShielded += tx->GetTotalSize();
2695 : }
2696 180 : return nSizeShielded;
2697 : }
2698 :
2699 166330 : bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig)
2700 : {
2701 166330 : AssertLockHeld(cs_main);
2702 :
2703 166330 : if (block.fChecked)
2704 : return true;
2705 :
2706 : // These are checks that are independent of context.
2707 83584 : const bool IsPoS = block.IsProofOfStake();
2708 :
2709 : // Check that the header is valid (particularly PoW). This is mostly
2710 : // redundant with the call in AcceptBlockHeader.
2711 83584 : if (!IsPoS && fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
2712 3 : return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed");
2713 :
2714 : // All potential-corruption validation must be done before we do any
2715 : // transaction validation, as otherwise we may mark the header as invalid
2716 : // because we receive the wrong transactions for it.
2717 :
2718 : // Check the merkle root.
2719 83583 : if (fCheckMerkleRoot) {
2720 53287 : bool mutated;
2721 53287 : uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
2722 53287 : if (block.hashMerkleRoot != hashMerkleRoot2)
2723 3 : return state.DoS(100, false, REJECT_INVALID, "bad-txnmrklroot", true, "hashMerkleRoot mismatch");
2724 :
2725 : // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
2726 : // of transactions in a block without affecting the merkle root of a block,
2727 : // while still invalidating it.
2728 53286 : if (mutated)
2729 20 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-duplicate", true, "duplicate transaction");
2730 : }
2731 :
2732 : // Size limits
2733 83577 : unsigned int nMaxBlockSize = MAX_BLOCK_SIZE_CURRENT;
2734 83577 : const unsigned int nBlockSize = ::GetSerializeSize(block, PROTOCOL_VERSION);
2735 83577 : if (block.vtx.empty() || block.vtx.size() > nMaxBlockSize || nBlockSize > nMaxBlockSize)
2736 6 : return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");
2737 :
2738 : // Check shielded txes limits (no need to check if the block size is already under 750kB)
2739 83575 : if (nBlockSize > MAX_BLOCK_SHIELDED_TXES_SIZE && GetTotalShieldedTxSize(block) > MAX_BLOCK_SHIELDED_TXES_SIZE)
2740 0 : return state.DoS(100, false, REJECT_INVALID, "bad-blk-shielded-size", false, "shielded size limits failed");
2741 :
2742 : // First transaction must be coinbase, the rest must not be
2743 83575 : if (block.vtx.empty() || !block.vtx[0]->IsCoinBase())
2744 3 : return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false, "first tx is not coinbase");
2745 723963 : for (unsigned int i = 1; i < block.vtx.size(); i++)
2746 640391 : if (block.vtx[i]->IsCoinBase())
2747 6 : return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase");
2748 :
2749 83572 : if (IsPoS) {
2750 : // Second transaction must be coinstake, the rest must not be
2751 10496 : if (block.vtx.empty() || !block.vtx[1]->IsCoinStake())
2752 0 : return state.DoS(100, false, REJECT_INVALID, "bad-cs-missing", false, "second tx is not coinstake");
2753 15003 : for (unsigned int i = 2; i < block.vtx.size(); i++)
2754 4507 : if (block.vtx[i]->IsCoinStake())
2755 0 : return state.DoS(100, false, REJECT_INVALID, "bad-cs-multiple", false, "more than one coinstake");
2756 : }
2757 :
2758 : // Cold Staking enforcement (true during sync - reject P2CS outputs when false)
2759 83572 : bool fColdStakingActive = true;
2760 :
2761 : // masternode payments / budgets
2762 83572 : CBlockIndex* pindexPrev = chainActive.Tip();
2763 156376 : int nHeight = 0;
2764 83254 : if (pindexPrev != nullptr && block.hashPrevBlock != UINT256_ZERO) {
2765 83253 : if (pindexPrev->GetBlockHash() != block.hashPrevBlock) {
2766 : //out of order
2767 11769 : CBlockIndex* pindexPrev = LookupBlockIndex(block.hashPrevBlock);
2768 11769 : if (!pindexPrev) {
2769 31347 : return state.Error("blk-out-of-order");
2770 : }
2771 : }
2772 72804 : nHeight = pindexPrev->nHeight + 1;
2773 :
2774 : // PIVX
2775 : // It is entirely possible that we don't have enough data and this could fail
2776 : // (i.e. the block could indeed be valid). Store the block for later consideration
2777 : // but issue an initial reject message.
2778 : // The case also exists that the sending peer could not have enough data to see
2779 : // that this block is invalid, so don't issue an outright ban.
2780 72804 : if (nHeight != 0 && !IsInitialBlockDownload()) {
2781 : // Last output of Cold-Stake is not abused
2782 70835 : if (IsPoS && !CheckColdStakeFreeOutput(*(block.vtx[1]), nHeight)) {
2783 1 : mapRejectedBlocks.emplace(block.GetHash(), GetTime());
2784 3 : return state.DoS(0, false, REJECT_INVALID, "bad-p2cs-outs", false, "invalid cold-stake output");
2785 : }
2786 :
2787 : // set Cold Staking Spork
2788 70834 : fColdStakingActive = !sporkManager.IsSporkActive(SPORK_19_COLDSTAKING_MAINTENANCE);
2789 :
2790 : } else {
2791 1969 : LogPrintf("%s: Masternode/Budget payment checks skipped on sync\n", __func__);
2792 : }
2793 : }
2794 :
2795 : // Check transactions
2796 785734 : for (const auto& txIn : block.vtx) {
2797 712617 : const CTransaction& tx = *txIn;
2798 712617 : if (!CheckTransaction(tx, state, fColdStakingActive)) {
2799 10 : return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(),
2800 12 : strprintf("Transaction check failed (tx hash %s) %s", tx.GetHash().ToString(), state.GetDebugMessage()));
2801 : }
2802 :
2803 : // Non-contextual checks for special txes
2804 712613 : if (!CheckSpecialTxNoContext(tx, state)) {
2805 : // pass the state returned by the function above
2806 : return false;
2807 : }
2808 : }
2809 :
2810 73117 : unsigned int nSigOps = 0;
2811 785725 : for (const auto& tx : block.vtx) {
2812 712608 : nSigOps += GetLegacySigOpCount(*tx);
2813 : }
2814 73117 : unsigned int nMaxBlockSigOps = block.GetBlockTime() > Params().GetConsensus().ZC_TimeStart ? MAX_BLOCK_SIGOPS_CURRENT : MAX_BLOCK_SIGOPS_LEGACY;
2815 73117 : if (nSigOps > nMaxBlockSigOps)
2816 14 : return state.DoS(100, error("%s : out-of-bounds SigOpCount", __func__),
2817 : REJECT_INVALID, "bad-blk-sigops", true);
2818 :
2819 : // Check PoS signature.
2820 73110 : if (fCheckSig && !CheckBlockSignature(block)) {
2821 0 : return state.DoS(100, error("%s : bad proof-of-stake block signature", __func__),
2822 : REJECT_INVALID, "bad-PoS-sig", true);
2823 : }
2824 :
2825 73110 : if (fCheckPOW && fCheckMerkleRoot && fCheckSig)
2826 42816 : block.fChecked = true;
2827 :
2828 : return true;
2829 : }
2830 :
2831 41515 : bool CheckWork(const CBlock& block, const CBlockIndex* const pindexPrev)
2832 : {
2833 41515 : if (pindexPrev == nullptr)
2834 0 : return error("%s : null pindexPrev for block %s", __func__, block.GetHash().GetHex());
2835 :
2836 41515 : unsigned int nBitsRequired = GetNextWorkRequired(pindexPrev, &block);
2837 :
2838 41515 : if (!Params().IsRegTestNet() && block.IsProofOfWork() && (pindexPrev->nHeight + 1 <= 68589)) {
2839 0 : double n1 = ConvertBitsToDouble(block.nBits);
2840 0 : double n2 = ConvertBitsToDouble(nBitsRequired);
2841 :
2842 0 : if (std::abs(n1 - n2) > n1 * 0.5)
2843 0 : return error("%s : incorrect proof of work (DGW pre-fork) - %f %f %f at %d", __func__, std::abs(n1 - n2), n1, n2, pindexPrev->nHeight + 1);
2844 :
2845 : return true;
2846 : }
2847 :
2848 41515 : if (block.nBits != nBitsRequired) {
2849 : // Pivx Specific reference to the block with the wrong threshold was used.
2850 1 : const Consensus::Params& consensus = Params().GetConsensus();
2851 1 : if ((block.nTime == (uint32_t) consensus.nPivxBadBlockTime) &&
2852 0 : (block.nBits == (uint32_t) consensus.nPivxBadBlockBits)) {
2853 : // accept PIVX block minted with incorrect proof of work threshold
2854 : return true;
2855 : }
2856 :
2857 1 : return error("%s : incorrect proof of work at %d", __func__, pindexPrev->nHeight + 1);
2858 : }
2859 :
2860 : return true;
2861 : }
2862 :
2863 56343 : bool CheckBlockTime(const CBlockHeader& block, CValidationState& state, CBlockIndex* const pindexPrev)
2864 : {
2865 : // Not enforced on RegTest
2866 56343 : if (Params().IsRegTestNet())
2867 : return true;
2868 :
2869 0 : const int64_t blockTime = block.GetBlockTime();
2870 0 : const int blockHeight = pindexPrev->nHeight + 1;
2871 :
2872 : // Check blocktime against future drift (WANT: blk_time <= Now + MaxDrift)
2873 0 : if (blockTime > pindexPrev->MaxFutureBlockTime())
2874 0 : return state.Invalid(error("%s : block timestamp too far in the future", __func__), REJECT_INVALID, "time-too-new");
2875 :
2876 : // Check blocktime against prev (WANT: blk_time > MinPastBlockTime)
2877 0 : if (blockTime <= pindexPrev->MinPastBlockTime())
2878 0 : return state.DoS(50, error("%s : block timestamp too old", __func__), REJECT_INVALID, "time-too-old");
2879 :
2880 : // Check blocktime mask
2881 56343 : if (!Params().GetConsensus().IsValidBlockTimeStamp(blockTime, blockHeight))
2882 0 : return state.DoS(100, error("%s : block timestamp mask not valid", __func__), REJECT_INVALID, "invalid-time-mask");
2883 :
2884 : // All good
2885 : return true;
2886 : }
2887 :
2888 : //! Returns last CBlockIndex* that is a checkpoint
2889 56343 : static const CBlockIndex* GetLastCheckpoint() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
2890 : {
2891 56343 : AssertLockHeld(cs_main);
2892 :
2893 56343 : if (!Checkpoints::fEnabled)
2894 : return nullptr;
2895 :
2896 56216 : const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints;
2897 :
2898 112432 : for (const auto& i : reverse_iterate(checkpoints)) {
2899 56216 : const uint256& hash = i.second;
2900 56216 : CBlockIndex* pindex = LookupBlockIndex(hash);
2901 56216 : if (pindex)
2902 0 : return pindex;
2903 : }
2904 56216 : return nullptr;
2905 : }
2906 :
2907 56348 : bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex* const pindexPrev)
2908 : {
2909 56348 : AssertLockHeld(cs_main);
2910 :
2911 56348 : const Consensus::Params& consensus = Params().GetConsensus();
2912 56348 : uint256 hash = block.GetHash();
2913 :
2914 56348 : if (hash == consensus.hashGenesisBlock)
2915 : return true;
2916 :
2917 56343 : assert(pindexPrev);
2918 :
2919 56343 : const int nHeight = pindexPrev->nHeight + 1;
2920 56343 : const int chainHeight = chainActive.Height();
2921 :
2922 : //If this is a reorg, check that it is not too deep
2923 56343 : int nMaxReorgDepth = gArgs.GetArg("-maxreorg", DEFAULT_MAX_REORG_DEPTH);
2924 56343 : if (chainHeight - nHeight >= nMaxReorgDepth)
2925 0 : return state.DoS(1, error("%s: forked chain older than max reorganization depth (height %d)", __func__, chainHeight - nHeight));
2926 :
2927 : // Check blocktime (past limit, future limit and mask)
2928 56343 : if (!CheckBlockTime(block, state, pindexPrev))
2929 : return false;
2930 :
2931 : // Check that the block chain matches the known block chain up to a checkpoint
2932 56343 : if (!Checkpoints::CheckBlock(nHeight, hash))
2933 0 : return state.DoS(100, error("%s : rejected by checkpoint lock-in at %d", __func__, nHeight),
2934 : REJECT_CHECKPOINT, "checkpoint mismatch");
2935 :
2936 : // Don't accept any forks from the main chain prior to last checkpoint
2937 56343 : const CBlockIndex* pcheckpoint = GetLastCheckpoint();
2938 56343 : if (pcheckpoint && nHeight < pcheckpoint->nHeight)
2939 0 : return state.DoS(0, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight));
2940 :
2941 : // Reject outdated version blocks
2942 56343 : if ((block.nVersion < 3 && nHeight >= 1) ||
2943 0 : (block.nVersion < 4 && consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZC)) ||
2944 56343 : (block.nVersion < 5 && consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BIP65)) ||
2945 56343 : (block.nVersion < 6 && consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_4)) ||
2946 112686 : (block.nVersion < 7 && consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V4_0)) ||
2947 56343 : (block.nVersion < 8 && consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V5_0)))
2948 : {
2949 0 : std::string stringErr = strprintf("rejected block version %d at height %d", block.nVersion, nHeight);
2950 0 : return state.Invalid(false, REJECT_OBSOLETE, "bad-version", stringErr);
2951 : }
2952 :
2953 : return true;
2954 : }
2955 :
2956 56333 : bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex* const pindexPrev)
2957 : {
2958 56333 : const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
2959 56333 : const CChainParams& chainparams = Params();
2960 :
2961 : // Check that all transactions are finalized
2962 541709 : for (const auto& tx : block.vtx) {
2963 :
2964 : // Check transaction contextually against consensus rules at block height
2965 485381 : if (!ContextualCheckTransaction(tx, state, chainparams, nHeight, true /* isMined */, IsInitialBlockDownload())) {
2966 5 : return false;
2967 : }
2968 :
2969 485378 : if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) {
2970 8 : return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false, "non-final transaction");
2971 : }
2972 : }
2973 :
2974 : // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
2975 56328 : if (pindexPrev) { // pindexPrev is only null on the first block which is a version 1 block.
2976 112643 : CScript expect = CScript() << nHeight;
2977 112646 : if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
2978 168969 : !std::equal(expect.begin(), expect.end(), block.vtx[0]->vin[0].scriptSig.begin())) {
2979 9 : return state.DoS(100, false, REJECT_INVALID, "bad-cb-height", false, "block height mismatch in coinbase");
2980 : }
2981 : }
2982 :
2983 56325 : if (block.IsProofOfStake()) {
2984 17176 : CTransactionRef csTx = block.vtx[1];
2985 8589 : if (csTx->vin.size() > 1) {
2986 4 : return state.DoS(100, false, REJECT_INVALID, "bad-cs-multi-inputs", false,
2987 : "invalid multi-inputs coinstake");
2988 : }
2989 :
2990 : // Prevent multi-empty-outputs
2991 17604 : for (size_t i=1; i<csTx->vout.size(); i++ ) {
2992 9017 : if (csTx->vout[i].IsEmpty()) {
2993 3 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-empty");
2994 : }
2995 : }
2996 : }
2997 :
2998 : return true;
2999 : }
3000 :
3001 : // Get the index of previous block of given CBlock
3002 41638 : static bool GetPrevIndex(const CBlock& block, CBlockIndex** pindexPrevRet, CValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
3003 : {
3004 41638 : AssertLockHeld(cs_main);
3005 :
3006 41638 : CBlockIndex*& pindexPrev = *pindexPrevRet;
3007 41638 : pindexPrev = nullptr;
3008 41638 : if (block.GetHash() != Params().GetConsensus().hashGenesisBlock) {
3009 41627 : pindexPrev = LookupBlockIndex(block.hashPrevBlock);
3010 41627 : if (!pindexPrev) {
3011 0 : return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.GetHex()), 0,
3012 : "prevblk-not-found");
3013 : }
3014 41627 : if (pindexPrev->nStatus & BLOCK_FAILED_MASK) {
3015 : //If this "invalid" block is an exact match from the checkpoints, then reconsider it
3016 112 : if (Checkpoints::CheckBlock(pindexPrev->nHeight, block.hashPrevBlock, true)) {
3017 0 : LogPrintf("%s : Reconsidering block %s height %d\n", __func__, block.hashPrevBlock.ToString(), pindexPrev->nHeight);
3018 0 : CValidationState statePrev;
3019 0 : ReconsiderBlock(statePrev, pindexPrev);
3020 0 : if (statePrev.IsValid()) {
3021 0 : ActivateBestChain(statePrev);
3022 0 : return true;
3023 : }
3024 : }
3025 448 : return state.DoS(100, error("%s : prev block %s is invalid, unable to add block %s", __func__, block.hashPrevBlock.GetHex(), block.GetHash().GetHex()),
3026 : REJECT_INVALID, "bad-prevblk");
3027 : }
3028 : }
3029 : return true;
3030 : }
3031 :
3032 41519 : bool AcceptBlockHeader(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, CBlockIndex* pindexPrev)
3033 : {
3034 41519 : AssertLockHeld(cs_main);
3035 : // Check for duplicate
3036 41519 : const uint256& hash = block.GetHash();
3037 41519 : CBlockIndex* pindex = LookupBlockIndex(hash);
3038 :
3039 : // TODO : ENABLE BLOCK CACHE IN SPECIFIC CASES
3040 41519 : if (pindex) {
3041 : // Block header is already known.
3042 320 : if (ppindex)
3043 320 : *ppindex = pindex;
3044 320 : if (pindex->nStatus & BLOCK_FAILED_MASK)
3045 211 : return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
3046 : return true;
3047 : }
3048 :
3049 : // Get prev block index
3050 41199 : if (pindexPrev == nullptr && !GetPrevIndex(block, &pindexPrev, state)) {
3051 : return false;
3052 : }
3053 :
3054 41199 : if (!ContextualCheckBlockHeader(block, state, pindexPrev))
3055 0 : return error("%s: ContextualCheckBlockHeader failed for block %s: %s", __func__, hash.ToString(), FormatStateMessage(state));
3056 :
3057 : // Check for conflicting chainlocks UNLESS that's the genesis block
3058 41199 : if (block.GetHash() != Params().GetConsensus().hashGenesisBlock) {
3059 41194 : if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, hash)) {
3060 26 : return state.DoS(10, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock");
3061 : }
3062 : }
3063 41186 : if (pindex == nullptr)
3064 41186 : pindex = AddToBlockIndex(block);
3065 :
3066 41186 : if (ppindex)
3067 41186 : *ppindex = pindex;
3068 :
3069 41186 : CheckBlockIndex();
3070 :
3071 : // Notify external listeners about accepted block header
3072 41186 : GetMainSignals().AcceptedBlockHeader(pindex);
3073 : return true;
3074 : }
3075 :
3076 : /*
3077 : * Collect the sets of the inputs (either regular utxos or zerocoin serials) spent
3078 : * by in-block txes.
3079 : * Also, check that there are no in-block double spends.
3080 : */
3081 6717 : static bool CheckInBlockDoubleSpends(const CBlock& block, int nHeight, CValidationState& state,
3082 : std::unordered_set<COutPoint, SaltedOutpointHasher>& spent_outpoints,
3083 : std::set<CBigNum>& spent_serials)
3084 : {
3085 6717 : const Consensus::Params& consensus = Params().GetConsensus();
3086 6717 : libzerocoin::ZerocoinParams* params = consensus.Zerocoin_Params(false);
3087 6717 : const bool zpivActive = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZC);
3088 6717 : const bool publicZpivActive = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZC_PUBLIC);
3089 6717 : const bool v5Active = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V5_0);
3090 :
3091 : // First collect the tx inputs, and check double spends
3092 16098 : for (size_t i = 1; i < block.vtx.size(); i++) {
3093 : // skip coinbase
3094 18765 : CTransactionRef tx = block.vtx[i];
3095 18047 : for (const CTxIn& in: tx->vin) {
3096 8666 : bool isPublicSpend = in.IsZerocoinPublicSpend();
3097 8666 : if (isPublicSpend && (!publicZpivActive || v5Active)) {
3098 0 : return state.DoS(100, error("%s: public zerocoin spend at height %d", __func__, nHeight));
3099 : }
3100 8666 : bool isPrivZerocoinSpend = !isPublicSpend && in.IsZerocoinSpend();
3101 0 : if (isPrivZerocoinSpend && (!zpivActive || publicZpivActive)) {
3102 0 : return state.DoS(100, error("%s: private zerocoin spend at height %d", __func__, nHeight));
3103 : }
3104 8666 : if (isPrivZerocoinSpend || isPublicSpend) {
3105 0 : libzerocoin::CoinSpend spend;
3106 0 : if (isPublicSpend) {
3107 0 : PublicCoinSpend publicSpend(params);
3108 0 : if (!ZPIVModule::ParseZerocoinPublicSpend(in, *tx, state, publicSpend)){
3109 0 : return false;
3110 : }
3111 0 : spend = publicSpend;
3112 : } else {
3113 0 : spend = ZPIVModule::TxInToZerocoinSpend(in);
3114 : }
3115 : // Check for serials double spending in the same block
3116 0 : const CBigNum& s = spend.getCoinSerialNumber();
3117 0 : if (spent_serials.find(s) != spent_serials.end()) {
3118 0 : return state.DoS(100, error("%s: serials double spent in the same block", __func__));
3119 : }
3120 0 : spent_serials.insert(s);
3121 : } else {
3122 : // regular utxo
3123 8666 : if (spent_outpoints.find(in.prevout) != spent_outpoints.end()) {
3124 6 : return state.DoS(100, error("%s: inputs double spent in the same block", __func__));
3125 : }
3126 17326 : spent_outpoints.insert(in.prevout);
3127 : }
3128 : }
3129 : }
3130 :
3131 : // Then remove from the coins_spent set, any coin that was created inside this block.
3132 : // In fact, if a transaction inside this block spends an output generated by another in-block tx,
3133 : // such output doesn't exist on chain yet, so we must not access the coins cache, or "walk the fork",
3134 : // to ensure that it was unspent before this block.
3135 : // The coinstake requires special treatment: its input cannot be the output of another in-block
3136 : // transaction (due to nStakeMinDepth), and no in-block tx can spend its outputs (due to nCoinbaseMaturity).
3137 13431 : std::unordered_set<uint256> inblock_txes;
3138 9366 : for (size_t i = 2; i < block.vtx.size(); i++) {
3139 : // coinbase/coinstake outputs cannot be spent inside the same block
3140 2652 : inblock_txes.insert(block.vtx[i]->GetHash());
3141 : }
3142 6714 : for (auto it = spent_outpoints.begin(); it != spent_outpoints.end(); /* no increment */) {
3143 8648 : if (inblock_txes.find(it->hash) != inblock_txes.end()) {
3144 : // the input spent was created as output of another in-block tx
3145 : // this is not allowed for the coinstake input
3146 1 : if (*it == block.vtx[1]->vin[0].prevout) {
3147 0 : return state.DoS(100, error("%s: coinstake input created in the same block", __func__));
3148 : }
3149 1 : it = spent_outpoints.erase(it);
3150 : } else {
3151 24009 : it++;
3152 : }
3153 : }
3154 :
3155 6714 : return true;
3156 : }
3157 :
3158 : /*
3159 : * Check whether ALL the provided inputs (outpoints and zerocoin serials) are UNSPENT on
3160 : * a forked (non currently active) chain.
3161 : * Start from startIndex and go backwards on the forked chain, down to the split block.
3162 : * Return false if any block contains a tx spending an input included in the provided sets
3163 : * 'outpoints' and/or 'serials'.
3164 : * Return false also when the fork is longer than -maxreorg.
3165 : * Return true otherwise.
3166 : * Save in pindexFork the index of the pre-split block (last common block with the active chain).
3167 : * Remove from the outpoints set, any coin that was created in the fork (we don't
3168 : * need to check that it was unspent on the active chain before the split).
3169 : */
3170 58 : static bool IsUnspentOnFork(std::unordered_set<COutPoint, SaltedOutpointHasher>& outpoints,
3171 : const std::set<CBigNum>& serials,
3172 : const CBlockIndex* startIndex, CValidationState& state, const CBlockIndex*& pindexFork)
3173 : {
3174 : // Go backwards on the forked chain up to the split
3175 58 : int readBlock = 0;
3176 58 : pindexFork = startIndex;
3177 540 : for ( ; !chainActive.Contains(pindexFork); pindexFork = pindexFork->pprev) {
3178 : // Check if the forked chain is longer than the max reorg limit
3179 214 : if (++readBlock == gArgs.GetArg("-maxreorg", DEFAULT_MAX_REORG_DEPTH)) {
3180 : // TODO: Remove this chain from disk.
3181 2 : return error("%s: forked chain longer than maximum reorg limit", __func__);
3182 : }
3183 214 : if (pindexFork->pprev == nullptr) {
3184 0 : return error("%s: null pprev for block %s", __func__, pindexFork->GetBlockHash().GetHex());
3185 : }
3186 :
3187 : // if there are no coins left, don't read the block
3188 214 : if (outpoints.empty() && serials.empty()) continue;
3189 :
3190 : // read block
3191 426 : CBlock bl;
3192 214 : if (!ReadBlockFromDisk(bl, pindexFork)) {
3193 0 : return error("%s: block %s not on disk", __func__, pindexFork->GetBlockHash().GetHex());
3194 : }
3195 : // Loop through every tx of this block
3196 : // (reversed because we first check spent outpoints, and then remove created ones)
3197 643 : for (auto it = bl.vtx.rbegin(); it != bl.vtx.rend(); ++it) {
3198 860 : CTransactionRef tx = *it;
3199 : // Loop through every input of this tx
3200 860 : for (const CTxIn& in: tx->vin) {
3201 : // check if any of the provided outpoints/serials is being spent
3202 431 : if (!in.IsZerocoinSpend()) {
3203 : // regular utxo
3204 431 : if (outpoints.find(in.prevout) != outpoints.end()) {
3205 6 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-spent-fork-post-split");
3206 : }
3207 : } else {
3208 : // zerocoin serial
3209 0 : const CBigNum& s = ZPIVModule::TxInToZerocoinSpend(in).getCoinSerialNumber();
3210 0 : if (serials.find(s) != serials.end()) {
3211 0 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-serials-spent-fork-post-split");
3212 : }
3213 : }
3214 : }
3215 : // Then remove from the outpoints set, any coin created by this tx
3216 429 : const uint256& txid = tx->GetHash();
3217 1079 : for (size_t i = 0; i < tx->vout.size(); i++) {
3218 : // erase if present (no-op if not)
3219 650 : outpoints.erase(COutPoint(txid, i));
3220 : }
3221 : }
3222 : }
3223 :
3224 : // All the provided outpoints/serials are not spent on the fork,
3225 : // and this fork is below the max reorg depth
3226 : return true;
3227 : }
3228 :
3229 : /*
3230 : * Check whether ALL the provided inputs (regular utxos) are SPENT on the currently active chain.
3231 : * Start from the block on top of pindexFork, and go upwards on the active chain, up to the tip.
3232 : * Remove from the 'outpoints' set, all the inputs spent by transactions included in the scanned
3233 : * blocks. At the end, return true if the set is empty (all outpoints are spent), and false
3234 : * otherwise (some outpoint is unspent).
3235 : */
3236 6 : static bool IsSpentOnActiveChain(std::unordered_set<COutPoint, SaltedOutpointHasher>& outpoints, const CBlockIndex* pindexFork)
3237 : {
3238 12 : assert(chainActive.Contains(pindexFork));
3239 6 : const int height_start = pindexFork->nHeight + 1;
3240 6 : const int height_end = chainActive.Height();
3241 :
3242 : // Go upwards on the active chain till the tip
3243 29 : for (int height = height_start; height <= height_end && !outpoints.empty(); height++) {
3244 : // read block
3245 46 : const CBlockIndex* pindex = mapBlockIndex.at(chainActive[height]->GetBlockHash());
3246 46 : CBlock bl;
3247 23 : if (!ReadBlockFromDisk(bl, pindex)) {
3248 0 : return error("%s: block %s not on disk", __func__, pindex->GetBlockHash().GetHex());
3249 : }
3250 : // Loop through every tx of this block
3251 78 : for (const auto& tx : bl.vtx) {
3252 : // Loop through every input of this tx
3253 208 : for (const CTxIn& in: tx->vin) {
3254 : // erase if present (no-op if not)
3255 153 : outpoints.erase(in.prevout);
3256 : }
3257 : }
3258 : }
3259 :
3260 6 : return outpoints.empty();
3261 : }
3262 :
3263 41633 : static bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, const FlatFilePos* dbp) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
3264 : {
3265 41633 : AssertLockHeld(cs_main);
3266 :
3267 41633 : CBlockIndex* pindexDummy = nullptr;
3268 41633 : CBlockIndex*& pindex = ppindex ? *ppindex : pindexDummy;
3269 :
3270 41633 : const Consensus::Params& consensus = Params().GetConsensus();
3271 :
3272 : // Get prev block index
3273 41633 : CBlockIndex* pindexPrev = nullptr;
3274 41633 : if (!GetPrevIndex(block, &pindexPrev, state))
3275 : return false;
3276 :
3277 41521 : if (block.GetHash() != consensus.hashGenesisBlock && !CheckWork(block, pindexPrev))
3278 2 : return state.DoS(100, false, REJECT_INVALID);
3279 :
3280 41520 : bool isPoS = block.IsProofOfStake();
3281 41520 : if (isPoS) {
3282 13439 : std::string strError;
3283 6720 : if (!CheckProofOfStake(block, strError, pindexPrev))
3284 2 : return state.DoS(100, error("%s: proof of stake check failed (%s)", __func__, strError));
3285 : }
3286 :
3287 41519 : if (!AcceptBlockHeader(block, state, &pindex, pindexPrev))
3288 : return false;
3289 :
3290 41295 : if (pindex->nStatus & BLOCK_HAVE_DATA) {
3291 : // TODO: deal better with duplicate blocks.
3292 : // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
3293 109 : LogPrintf("%s : already have block %d %s\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString());
3294 109 : return true;
3295 : }
3296 :
3297 41186 : if (!CheckBlock(block, state) || !ContextualCheckBlock(block, state, pindex->pprev)) {
3298 10 : if (state.IsInvalid() && !state.CorruptionPossible()) {
3299 10 : pindex->nStatus |= BLOCK_FAILED_VALID;
3300 10 : setDirtyBlockIndex.insert(pindex);
3301 : }
3302 20 : return error("%s: %s", __func__, FormatStateMessage(state));
3303 : }
3304 :
3305 41176 : int nHeight = pindex->nHeight;
3306 :
3307 41176 : if (isPoS) {
3308 : // Blocks arrives in order, so if prev block is not the tip then we are on a fork.
3309 : // Extra info: duplicated blocks are skipping this checks, so we don't have to worry about those here.
3310 13434 : bool isBlockFromFork = pindexPrev != nullptr && chainActive.Tip() != pindexPrev;
3311 :
3312 : // Collect spent_outpoints and check for in-block double spends
3313 13423 : std::unordered_set<COutPoint, SaltedOutpointHasher> spent_outpoints;
3314 13423 : std::set<CBigNum> spent_serials;
3315 6717 : if (!CheckInBlockDoubleSpends(block, nHeight, state, spent_outpoints, spent_serials)) {
3316 11 : return false;
3317 : }
3318 :
3319 : // If this is a fork, check if all the tx inputs were spent in the fork
3320 : // Start at the block we're adding on to.
3321 : // Also remove from spent_outpoints any coin that was created in the fork
3322 6714 : const CBlockIndex* pindexFork{nullptr}; // index of the split block (last common block between fork and active chain)
3323 6714 : if (isBlockFromFork && !IsUnspentOnFork(spent_outpoints, spent_serials, pindexPrev, state, pindexFork)) {
3324 : return false;
3325 : }
3326 6712 : assert(!isBlockFromFork || pindexFork != nullptr);
3327 :
3328 : // Reject forks below maxdepth
3329 6824 : if (isBlockFromFork && chainActive.Height() - pindexFork->nHeight > gArgs.GetArg("-maxreorg", DEFAULT_MAX_REORG_DEPTH)) {
3330 : // TODO: Remove this chain from disk.
3331 0 : return error("%s: forked chain longer than maximum reorg limit", __func__);
3332 : }
3333 :
3334 : // Check that the serials were unspent on the active chain before the fork
3335 6712 : for (const CBigNum& s : spent_serials) {
3336 0 : int nHeightTx = 0;
3337 0 : if (IsSerialInBlockchain(s, nHeightTx)) {
3338 : // if the height is nHeightTx > chainSplit means that the spent occurred after the chain split
3339 0 : if (nHeightTx <= pindexFork->nHeight)
3340 0 : return state.DoS(100, error("%s: serials double spent on main chain", __func__));
3341 : }
3342 : }
3343 :
3344 : // Check that all tx inputs were unspent on the active chain before the fork
3345 6712 : for (auto it = spent_outpoints.begin(); it != spent_outpoints.end(); /* no increment */) {
3346 8640 : const Coin& coin = pcoinsTip->AccessCoin(*it);
3347 8640 : if (!coin.IsSpent()) {
3348 : // if this is on a fork, then the coin must be created before the split
3349 8631 : if (isBlockFromFork && (int) coin.nHeight > pindexFork->nHeight) {
3350 6 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-created-post-split");
3351 : }
3352 : // unspent on active chain
3353 8629 : it = spent_outpoints.erase(it);
3354 : } else {
3355 : // spent on active chain
3356 9 : if (!isBlockFromFork)
3357 6 : return error("%s: tx inputs spent/not-available on main chain (%s)", __func__, it->ToString());
3358 15353 : it++;
3359 : }
3360 : }
3361 6707 : if (isBlockFromFork && !spent_outpoints.empty()) {
3362 : // Some coins are not spent on the fork post-split, but cannot be found in the coins cache.
3363 : // So they were either created on the fork, or spent on the active chain.
3364 : // Since coins created in the fork are removed by IsUnspentOnFork(), if there are some coins left,
3365 : // they were spent on the active chain.
3366 : // If some of them was not spent after the split, then the block is invalid.
3367 : // Walk the active chain, starting from pindexFork, going upwards till the chain tip, and check if
3368 : // all of these coins were spent by transactions included in the scanned blocks.
3369 : // If ALL of them are spent, then accept the block.
3370 : // Otherwise reject it, as it means that this blocks includes a transaction with an input that is
3371 : // either already spent before the chain split, or non-existent.
3372 6 : if (!IsSpentOnActiveChain(spent_outpoints, pindexFork)) {
3373 3 : return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-spent-fork-pre-split");
3374 : }
3375 : }
3376 :
3377 : // ZPOS contextual checks
3378 6706 : const CTransaction& coinstake = *block.vtx[1];
3379 6706 : const CTxIn& coinstake_in = coinstake.vin[0];
3380 6706 : if (coinstake_in.IsZerocoinSpend()) {
3381 0 : libzerocoin::CoinSpend spend = ZPIVModule::TxInToZerocoinSpend(coinstake_in);
3382 0 : if (!ContextualCheckZerocoinSpend(coinstake, &spend, pindex->nHeight)) {
3383 0 : return state.DoS(100,error("%s: main chain ContextualCheckZerocoinSpend failed for tx %s", __func__,
3384 0 : coinstake.GetHash().GetHex()), REJECT_INVALID, "bad-txns-invalid-zpiv");
3385 : }
3386 : }
3387 :
3388 : }
3389 :
3390 : // Write block to history file
3391 41165 : try {
3392 41165 : unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
3393 41165 : FlatFilePos blockPos;
3394 41165 : if (dbp != nullptr)
3395 344 : blockPos = *dbp;
3396 41165 : if (!FindBlockPos(state, blockPos, nBlockSize + 8, nHeight, block.GetBlockTime(), dbp != nullptr))
3397 0 : return error("%s : FindBlockPos failed", __func__);
3398 41165 : if (dbp == nullptr)
3399 40821 : if (!WriteBlockToDisk(block, blockPos))
3400 0 : return AbortNode(state, "Failed to write block");
3401 41165 : if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
3402 0 : return error("%s : ReceivedBlockTransactions failed", __func__);
3403 0 : } catch (const std::runtime_error& e) {
3404 0 : return AbortNode(state, std::string("System error: ") + e.what());
3405 : }
3406 :
3407 41165 : return true;
3408 : }
3409 :
3410 52105 : bool ProcessNewBlock(const std::shared_ptr<const CBlock>& pblock, const FlatFilePos* dbp)
3411 : {
3412 52105 : AssertLockNotHeld(cs_main);
3413 :
3414 : // Preliminary checks
3415 52105 : int64_t nStartTime = GetTimeMillis();
3416 52105 : int newHeight = 0;
3417 :
3418 52105 : {
3419 : // CheckBlock requires cs_main lock
3420 52105 : LOCK(cs_main);
3421 93379 : CValidationState state;
3422 52105 : if (!CheckBlock(*pblock, state)) {
3423 10472 : GetMainSignals().BlockChecked(*pblock, state);
3424 31410 : return error ("%s : CheckBlock FAILED for block %s, %s", __func__, pblock->GetHash().GetHex(), FormatStateMessage(state));
3425 : }
3426 :
3427 : // Store to disk
3428 41633 : CBlockIndex* pindex = nullptr;
3429 41633 : bool ret = AcceptBlock(*pblock, state, &pindex, dbp);
3430 41633 : CheckBlockIndex();
3431 41633 : if (!ret) {
3432 359 : GetMainSignals().BlockChecked(*pblock, state);
3433 359 : return error("%s : AcceptBlock FAILED", __func__);
3434 : }
3435 41274 : newHeight = pindex->nHeight;
3436 : }
3437 :
3438 82548 : CValidationState state; // Only used to report errors, not invalidity - ignore it
3439 82548 : if (!ActivateBestChain(state, pblock))
3440 1 : return error("%s : ActivateBestChain failed", __func__);
3441 :
3442 82546 : LogPrintf("%s : ACCEPTED Block %ld in %ld milliseconds with size=%d\n", __func__, newHeight, GetTimeMillis() - nStartTime,
3443 41273 : GetSerializeSize(*pblock, CLIENT_VERSION));
3444 :
3445 41273 : return true;
3446 : }
3447 :
3448 15149 : bool TestBlockValidity(CValidationState& state, const CBlock& block, CBlockIndex* const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckBlockSig)
3449 : {
3450 15149 : AssertLockHeld(cs_main);
3451 15149 : assert(pindexPrev);
3452 30298 : if (pindexPrev != chainActive.Tip()) {
3453 0 : LogPrintf("%s : No longer working on chain tip\n", __func__);
3454 0 : return false;
3455 : }
3456 15149 : if (llmq::chainLocksHandler->HasConflictingChainLock(pindexPrev->nHeight + 1, block.GetHash())) {
3457 0 : return state.DoS(10, error("%s: conflicting with chainlock", __func__), REJECT_INVALID, "bad-chainlock");
3458 : }
3459 :
3460 15149 : CCoinsViewCache viewNew(pcoinsTip.get());
3461 30298 : CBlockIndex indexDummy(block);
3462 15149 : indexDummy.pprev = pindexPrev;
3463 15149 : indexDummy.nHeight = pindexPrev->nHeight + 1;
3464 :
3465 : // begin tx and let it rollback
3466 30298 : auto dbTx = evoDb->BeginTransaction();
3467 :
3468 : // NOTE: CheckBlockHeader is called by CheckBlock
3469 15149 : if (!ContextualCheckBlockHeader(block, state, pindexPrev))
3470 0 : return error("%s: ContextualCheckBlockHeader failed: %s", __func__, FormatStateMessage(state));
3471 15149 : if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot, fCheckBlockSig))
3472 3 : return error("%s: CheckBlock failed: %s", __func__, FormatStateMessage(state));
3473 15147 : if (!ContextualCheckBlock(block, state, pindexPrev))
3474 0 : return error("%s: ContextualCheckBlock failed: %s", __func__, FormatStateMessage(state));
3475 15147 : if (!ConnectBlock(block, state, &indexDummy, viewNew, true))
3476 : return false;
3477 15144 : assert(state.IsValid());
3478 :
3479 : return true;
3480 : }
3481 :
3482 370258 : static FlatFileSeq BlockFileSeq()
3483 : {
3484 740516 : return FlatFileSeq(GetBlocksDir(), "blk", BLOCKFILE_CHUNK_SIZE);
3485 : }
3486 :
3487 85525 : static FlatFileSeq UndoFileSeq()
3488 : {
3489 171050 : return FlatFileSeq(GetBlocksDir(), "rev", UNDOFILE_CHUNK_SIZE);
3490 : }
3491 :
3492 328308 : FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly)
3493 : {
3494 656616 : return BlockFileSeq().Open(pos, fReadOnly);
3495 : }
3496 :
3497 43652 : FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly)
3498 : {
3499 87304 : return UndoFileSeq().Open(pos, fReadOnly);
3500 : }
3501 :
3502 10 : fs::path GetBlockPosFilename(const FlatFilePos &pos)
3503 : {
3504 20 : return BlockFileSeq().FileName(pos);
3505 : }
3506 :
3507 65612 : CBlockIndex* InsertBlockIndex(const uint256& hash)
3508 : {
3509 65612 : AssertLockHeld(cs_main);
3510 :
3511 131224 : if (hash.IsNull())
3512 : return nullptr;
3513 :
3514 : // Return existing
3515 65453 : BlockMap::iterator mi = mapBlockIndex.find(hash);
3516 65453 : if (mi != mapBlockIndex.end())
3517 32647 : return (*mi).second;
3518 :
3519 : // Create new
3520 32806 : CBlockIndex* pindexNew = new CBlockIndex();
3521 32806 : mi = mapBlockIndex.emplace(hash, pindexNew).first;
3522 :
3523 32806 : pindexNew->phashBlock = &((*mi).first);
3524 :
3525 32806 : return pindexNew;
3526 : }
3527 :
3528 352 : bool static LoadBlockIndexDB(std::string& strError) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
3529 : {
3530 352 : AssertLockHeld(cs_main);
3531 :
3532 704 : if (!pblocktree->LoadBlockIndexGuts(InsertBlockIndex))
3533 : return false;
3534 :
3535 352 : boost::this_thread::interruption_point();
3536 :
3537 : // Calculate nChainWork
3538 704 : std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
3539 352 : vSortedByHeight.reserve(mapBlockIndex.size());
3540 33158 : for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex) {
3541 32806 : CBlockIndex* pindex = item.second;
3542 32806 : vSortedByHeight.emplace_back(pindex->nHeight, pindex);
3543 : // build mapPrevBlockIndex
3544 32806 : if (pindex->pprev) {
3545 32647 : mapPrevBlockIndex.emplace(pindex->pprev->GetBlockHash(), pindex);
3546 : }
3547 : }
3548 352 : std::sort(vSortedByHeight.begin(), vSortedByHeight.end());
3549 33158 : for (const std::pair<int, CBlockIndex*>& item : vSortedByHeight) {
3550 : // Stop if shutdown was requested
3551 32806 : if (ShutdownRequested()) return false;
3552 :
3553 32806 : CBlockIndex* pindex = item.second;
3554 393672 : pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
3555 54930 : pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime);
3556 32806 : if (pindex->nStatus & BLOCK_HAVE_DATA) {
3557 32806 : if (pindex->pprev) {
3558 32647 : if (pindex->pprev->nChainTx) {
3559 32647 : pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
3560 : // Sapling, calculate chain index value
3561 32647 : if (pindex->pprev->nChainSaplingValue) {
3562 32647 : pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
3563 : } else {
3564 0 : pindex->nChainSaplingValue = nullopt;
3565 : }
3566 :
3567 : } else {
3568 0 : pindex->nChainTx = 0;
3569 0 : pindex->nChainSaplingValue = nullopt;
3570 0 : mapBlocksUnlinked.emplace(pindex->pprev, pindex);
3571 : }
3572 : } else {
3573 159 : pindex->nChainTx = pindex->nTx;
3574 159 : pindex->nChainSaplingValue = pindex->nSaplingValue;
3575 : }
3576 : }
3577 32806 : if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == nullptr))
3578 32801 : setBlockIndexCandidates.insert(pindex);
3579 32806 : if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
3580 5 : pindexBestInvalid = pindex;
3581 32806 : if (pindex->pprev)
3582 32647 : pindex->BuildSkip();
3583 32806 : if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == nullptr || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
3584 32700 : pindexBestHeader = pindex;
3585 : }
3586 :
3587 : // Load block file info
3588 352 : pblocktree->ReadLastBlockFile(nLastBlockFile);
3589 352 : vinfoBlockFile.resize(nLastBlockFile + 1);
3590 352 : LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
3591 704 : for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
3592 352 : pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
3593 : }
3594 352 : LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
3595 352 : for (int nFile = nLastBlockFile + 1; true; nFile++) {
3596 352 : CBlockFileInfo info;
3597 352 : if (pblocktree->ReadBlockFileInfo(nFile, info)) {
3598 0 : vinfoBlockFile.push_back(info);
3599 : } else {
3600 : break;
3601 : }
3602 0 : }
3603 :
3604 : // Check presence of blk files
3605 352 : LogPrintf("Checking all blk files are present...\n");
3606 704 : std::set<int> setBlkDataFiles;
3607 33158 : for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex) {
3608 32806 : CBlockIndex* pindex = item.second;
3609 32806 : if (pindex->nStatus & BLOCK_HAVE_DATA) {
3610 65612 : setBlkDataFiles.insert(pindex->nFile);
3611 : }
3612 : }
3613 511 : for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) {
3614 159 : FlatFilePos pos(*it, 0);
3615 318 : if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
3616 0 : return false;
3617 : }
3618 : }
3619 :
3620 : //Check if the shutdown procedure was followed on last client exit
3621 352 : bool fLastShutdownWasPrepared = true;
3622 352 : pblocktree->ReadFlag("shutdown", fLastShutdownWasPrepared);
3623 352 : LogPrintf("%s: Last shutdown was prepared: %s\n", __func__, fLastShutdownWasPrepared);
3624 :
3625 : // Check whether we need to continue reindexing
3626 352 : bool fReindexing = false;
3627 352 : pblocktree->ReadReindexing(fReindexing);
3628 352 : if (fReindexing) fReindex = true;
3629 :
3630 : // Check whether we have a transaction index
3631 352 : pblocktree->ReadFlag("txindex", fTxIndex);
3632 352 : LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
3633 :
3634 : // If this is written true before the next client init, then we know the shutdown process failed
3635 352 : pblocktree->WriteFlag("shutdown", false);
3636 :
3637 352 : return true;
3638 : }
3639 :
3640 157 : bool LoadChainTip(const CChainParams& chainparams)
3641 : {
3642 157 : AssertLockHeld(cs_main);
3643 :
3644 157 : if (chainActive.Tip() && chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) return true;
3645 :
3646 314 : if (pcoinsTip->GetBestBlock().IsNull() && mapBlockIndex.size() == 1) {
3647 : // In case we just added the genesis block, connect it now, so
3648 : // that we always have a chainActive.Tip() when we return.
3649 0 : LogPrintf("%s: Connecting genesis block...\n", __func__);
3650 0 : CValidationState state;
3651 0 : if (!ActivateBestChain(state)) {
3652 0 : return false;
3653 : }
3654 : }
3655 :
3656 : // Load pointer to end of best chain
3657 157 : CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock());
3658 157 : if (!pindex) {
3659 : return false;
3660 : }
3661 157 : chainActive.SetTip(pindex);
3662 :
3663 157 : PruneBlockIndexCandidates();
3664 :
3665 157 : const CBlockIndex* pChainTip = chainActive.Tip();
3666 :
3667 157 : LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
3668 314 : pChainTip->GetBlockHash().GetHex(), pChainTip->nHeight,
3669 157 : FormatISO8601DateTime(pChainTip->GetBlockTime()),
3670 157 : Checkpoints::GuessVerificationProgress(pChainTip));
3671 157 : return true;
3672 : }
3673 :
3674 158 : CVerifyDB::CVerifyDB()
3675 : {
3676 158 : uiInterface.ShowProgress(_("Verifying blocks..."), 0);
3677 158 : }
3678 :
3679 158 : CVerifyDB::~CVerifyDB()
3680 : {
3681 158 : uiInterface.ShowProgress("", 100);
3682 158 : }
3683 :
3684 158 : bool CVerifyDB::VerifyDB(CCoinsView* coinsview, int nCheckLevel, int nCheckDepth)
3685 : {
3686 316 : LOCK(cs_main);
3687 296 : if (chainActive.Tip() == nullptr || chainActive.Tip()->pprev == nullptr)
3688 : return true;
3689 :
3690 138 : const int chainHeight = chainActive.Height();
3691 :
3692 : // begin tx and let it rollback
3693 276 : auto dbTx = evoDb->BeginTransaction();
3694 :
3695 : // Verify blocks in the best chain
3696 138 : if (nCheckDepth <= 0)
3697 1 : nCheckDepth = 1000000000; // suffices until the year 19000
3698 138 : if (nCheckDepth > chainHeight)
3699 6 : nCheckDepth = chainHeight;
3700 276 : nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3701 138 : LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
3702 276 : CCoinsViewCache coins(coinsview);
3703 138 : CBlockIndex* pindexState = chainActive.Tip();
3704 138 : CBlockIndex* pindexFailure = nullptr;
3705 138 : int nGoodTransactions = 0;
3706 138 : int reportDone = 0;
3707 138 : LogPrintf("[0%%]...");
3708 276 : CValidationState state;
3709 1404 : for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
3710 1261 : boost::this_thread::interruption_point();
3711 3517 : int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
3712 1261 : if (reportDone < percentageDone/10) {
3713 : // report every 10% step
3714 801 : LogPrintf("[%d%%]...", percentageDone);
3715 801 : reportDone = percentageDone/10;
3716 : }
3717 1261 : uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone);
3718 1261 : if (pindex->nHeight < chainHeight - nCheckDepth)
3719 : break;
3720 2257 : CBlock block;
3721 : // check level 0: read from disk
3722 1129 : if (!ReadBlockFromDisk(block, pindex))
3723 0 : return error("%s: *** ReadBlockFromDisk failed at %d, hash=%s", __func__, pindex->nHeight, pindex->GetBlockHash().ToString());
3724 : // check level 1: verify block validity
3725 1129 : if (nCheckLevel >= 1 && !CheckBlock(block, state))
3726 0 : return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state));
3727 : // check level 2: verify undo validity
3728 1129 : if (nCheckLevel >= 2 && pindex) {
3729 2257 : CBlockUndo undo;
3730 1129 : FlatFilePos pos = pindex->GetUndoPos();
3731 1129 : if (!pos.IsNull()) {
3732 1129 : if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
3733 2 : return error("%s: *** found bad undo data at %d, hash=%s\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString());
3734 : }
3735 : }
3736 : // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
3737 1128 : if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
3738 1117 : assert(coins.GetBestBlock() == pindex->GetBlockHash());
3739 1117 : DisconnectResult res = DisconnectBlock(block, pindex, coins);
3740 1117 : if (res == DISCONNECT_FAILED) {
3741 0 : return error("%s: *** irrecoverable inconsistency in block data at %d, hash=%s", __func__,
3742 0 : pindex->nHeight, pindex->GetBlockHash().ToString());
3743 : }
3744 1117 : pindexState = pindex->pprev;
3745 1117 : if (res == DISCONNECT_UNCLEAN) {
3746 0 : nGoodTransactions = 0;
3747 0 : pindexFailure = pindex;
3748 : } else {
3749 1117 : nGoodTransactions += block.vtx.size();
3750 : }
3751 : }
3752 1128 : if (ShutdownRequested())
3753 : return true;
3754 : }
3755 137 : if (pindexFailure)
3756 0 : return error("%s: *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", __func__, chainHeight - pindexFailure->nHeight + 1, nGoodTransactions);
3757 :
3758 : // check level 4: try reconnecting blocks
3759 137 : if (nCheckLevel >= 4) {
3760 : CBlockIndex* pindex = pindexState;
3761 0 : while (pindex != chainActive.Tip()) {
3762 0 : boost::this_thread::interruption_point();
3763 0 : uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainHeight - pindex->nHeight)) / (double)nCheckDepth * 50))));
3764 0 : pindex = chainActive.Next(pindex);
3765 0 : CBlock block;
3766 0 : if (!ReadBlockFromDisk(block, pindex))
3767 0 : return error("%s: *** ReadBlockFromDisk failed at %d, hash=%s", __func__, pindex->nHeight, pindex->GetBlockHash().ToString());
3768 0 : if (!ConnectBlock(block, state, pindex, coins, false))
3769 0 : return error("%s: *** found unconnectable block at %d, hash=%s", __func__, pindex->nHeight, pindex->GetBlockHash().ToString());
3770 : }
3771 : }
3772 137 : LogPrintf("[DONE].\n");
3773 137 : LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainHeight - pindexState->nHeight, nGoodTransactions);
3774 :
3775 137 : return true;
3776 : }
3777 :
3778 : /** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
3779 16 : static bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
3780 : {
3781 16 : AssertLockHeld(cs_main);
3782 :
3783 : // TODO: merge with ConnectBlock
3784 32 : CBlock block;
3785 16 : if (!ReadBlockFromDisk(block, pindex)) {
3786 0 : return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3787 : }
3788 :
3789 16 : const bool fSkipInvalid = SkipInvalidUTXOS(pindex->nHeight);
3790 :
3791 23972 : for (const CTransactionRef& tx : block.vtx) {
3792 23956 : if (!tx->IsCoinBase()) {
3793 71820 : for (const CTxIn &txin : tx->vin) {
3794 47880 : inputs.SpendCoin(txin.prevout);
3795 : }
3796 : }
3797 :
3798 : // Pass check = true as every addition may be an overwrite.
3799 23956 : AddCoins(inputs, *tx, pindex->nHeight, true, fSkipInvalid);
3800 : }
3801 :
3802 32 : CValidationState state;
3803 16 : if (!ProcessSpecialTxsInBlock(block, pindex, &inputs, state, false /*fJustCheck*/)) {
3804 0 : return error("%s: Special tx processing failed for block %s with %s",
3805 0 : __func__, pindex->GetBlockHash().ToString(), FormatStateMessage(state));
3806 : }
3807 :
3808 : return true;
3809 : }
3810 :
3811 357 : bool ReplayBlocks(const CChainParams& params, CCoinsView* view)
3812 : {
3813 714 : LOCK(cs_main);
3814 :
3815 714 : CCoinsViewCache cache(view);
3816 :
3817 714 : std::vector<uint256> hashHeads = view->GetHeadBlocks();
3818 357 : if (hashHeads.empty()) return true; // We're already in a consistent state.
3819 3 : if (hashHeads.size() != 2) return error("%s: unknown inconsistent state", __func__);
3820 :
3821 3 : uiInterface.ShowProgress(_("Replaying blocks..."), 0);
3822 3 : LogPrintf("Replaying blocks\n");
3823 :
3824 3 : const CBlockIndex* pindexOld = nullptr; // Old tip during the interrupted flush.
3825 3 : const CBlockIndex* pindexNew; // New tip during the interrupted flush.
3826 3 : const CBlockIndex* pindexFork = nullptr; // Latest block common to both the old and the new tip.
3827 :
3828 3 : pindexNew = LookupBlockIndex(hashHeads[0]);
3829 3 : if (!pindexNew) {
3830 0 : return error("%s: reorganization to unknown block requested", __func__);
3831 : }
3832 :
3833 6 : if (!hashHeads[1].IsNull()) { // The old tip is allowed to be 0, indicating it's the first flush.
3834 3 : pindexOld = LookupBlockIndex(hashHeads[1]);
3835 3 : if (!pindexOld) {
3836 0 : return error("%s: reorganization from unknown block requested", __func__);
3837 : }
3838 3 : pindexFork = LastCommonAncestor(pindexOld, pindexNew);
3839 3 : assert(pindexFork != nullptr);
3840 : }
3841 :
3842 : // Rollback along the old branch.
3843 14 : while (pindexOld != pindexFork) {
3844 11 : if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
3845 22 : CBlock block;
3846 11 : if (!ReadBlockFromDisk(block, pindexOld)) {
3847 0 : return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
3848 : }
3849 11 : LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
3850 11 : DisconnectResult res = DisconnectBlock(block, pindexOld, cache);
3851 11 : if (res == DISCONNECT_FAILED) {
3852 0 : return error("RollbackBlock(): DisconnectBlock failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
3853 : }
3854 : // If DISCONNECT_UNCLEAN is returned, it means a non-existing UTXO was deleted, or an existing UTXO was
3855 : // overwritten. It corresponds to cases where the block-to-be-disconnect never had all its operations
3856 : // applied to the UTXO set. However, as both writing a UTXO and deleting a UTXO are idempotent operations,
3857 : // the result is still a version of the UTXO set with the effects of that block undone.
3858 : }
3859 11 : pindexOld = pindexOld->pprev;
3860 : }
3861 :
3862 : // Roll forward from the forking point to the new tip.
3863 3 : int nForkHeight = pindexFork ? pindexFork->nHeight : 0;
3864 19 : for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; ++nHeight) {
3865 16 : const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight);
3866 16 : LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight);
3867 16 : if (!RollforwardBlock(pindex, cache, params)) return false;
3868 : }
3869 :
3870 3 : cache.SetBestBlock(pindexNew->GetBlockHash());
3871 3 : evoDb->WriteBestBlock(pindexNew->GetBlockHash());
3872 3 : cache.Flush();
3873 3 : uiInterface.ShowProgress("", 100);
3874 3 : return true;
3875 : }
3876 :
3877 : // May NOT be used after any connections are up as much
3878 : // of the peer-processing logic assumes a consistent
3879 : // block index state
3880 475 : void UnloadBlockIndex()
3881 : {
3882 475 : LOCK(cs_main);
3883 475 : setBlockIndexCandidates.clear();
3884 475 : chainActive.SetTip(nullptr);
3885 475 : pindexBestInvalid = nullptr;
3886 475 : pindexBestHeader = nullptr;
3887 475 : mempool.clear();
3888 475 : mapBlocksUnlinked.clear();
3889 475 : vinfoBlockFile.clear();
3890 475 : nLastBlockFile = 0;
3891 475 : nBlockSequenceId = 1;
3892 475 : setDirtyBlockIndex.clear();
3893 475 : setDirtyFileInfo.clear();
3894 :
3895 3201 : for (BlockMap::value_type& entry : mapBlockIndex) {
3896 5452 : delete entry.second;
3897 : }
3898 475 : mapBlockIndex.clear();
3899 475 : }
3900 :
3901 357 : bool LoadBlockIndex(std::string& strError)
3902 : {
3903 357 : AssertLockHeld(cs_main);
3904 :
3905 357 : bool needs_init = fReindex;
3906 357 : if (!fReindex) {
3907 352 : if (!LoadBlockIndexDB(strError))
3908 : return false;
3909 352 : needs_init = mapBlockIndex.empty();
3910 : }
3911 :
3912 357 : if (needs_init) {
3913 : // Everything here is for *new* reindex/DBs. Thus, though
3914 : // LoadBlockIndexDB may have set fReindex if we shut down
3915 : // mid-reindex previously, we don't check fReindex and
3916 : // instead only check it prior to LoadBlockIndexDB to set
3917 : // needs_init.
3918 :
3919 198 : LogPrintf("Initializing databases...\n");
3920 : // Use the provided setting for -txindex in the new database
3921 198 : fTxIndex = gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX);
3922 396 : pblocktree->WriteFlag("txindex", fTxIndex);
3923 : }
3924 : return true;
3925 : }
3926 :
3927 :
3928 475 : bool LoadGenesisBlock()
3929 : {
3930 950 : LOCK(cs_main);
3931 :
3932 : // Check whether we're already initialized by checking for genesis in
3933 : // mapBlockIndex. Note that we can't use chainActive here, since it is
3934 : // set based on the coins db, not the block index db, which is the only
3935 : // thing loaded at this point.
3936 950 : if (mapBlockIndex.count(Params().GenesisBlock().GetHash()))
3937 : return true;
3938 :
3939 311 : try {
3940 311 : CBlock& block = const_cast<CBlock&>(Params().GenesisBlock());
3941 : // Start new block file
3942 311 : unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
3943 311 : FlatFilePos blockPos;
3944 622 : CValidationState state;
3945 311 : if (!FindBlockPos(state, blockPos, nBlockSize + 8, 0, block.GetBlockTime()))
3946 0 : return error("%s: FindBlockPos failed", __func__);
3947 311 : if (!WriteBlockToDisk(block, blockPos))
3948 0 : return error("%s: writing genesis block to disk failed", __func__);
3949 311 : CBlockIndex *pindex = AddToBlockIndex(block);
3950 311 : if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
3951 0 : return error("%s: genesis block not accepted", __func__);
3952 0 : } catch (const std::runtime_error& e) {
3953 0 : return error("%s: failed to write genesis block: %s", __func__, e.what());
3954 : }
3955 :
3956 311 : return true;
3957 : }
3958 :
3959 :
3960 5 : bool LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
3961 : {
3962 : // Map of disk positions for blocks with unknown parent (only used for reindex)
3963 5 : static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
3964 5 : int64_t nStart = GetTimeMillis();
3965 :
3966 : // Block checked event listener
3967 5 : BlockStateCatcherWrapper stateCatcher(UINT256_ZERO);
3968 5 : stateCatcher.registerEvent();
3969 :
3970 5 : int nLoaded = 0;
3971 5 : try {
3972 : // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
3973 5 : CBufferedFile blkdat(fileIn, 2 * MAX_BLOCK_SIZE_CURRENT, MAX_BLOCK_SIZE_CURRENT + 8, SER_DISK, CLIENT_VERSION);
3974 5 : uint64_t nRewind = blkdat.GetPos();
3975 354 : while (!blkdat.eof()) {
3976 349 : boost::this_thread::interruption_point();
3977 :
3978 349 : blkdat.SetPos(nRewind);
3979 349 : nRewind++; // start one byte further next time, in case of failure
3980 349 : blkdat.SetLimit(); // remove former limit
3981 349 : unsigned int nSize = 0;
3982 349 : try {
3983 : // locate a header
3984 349 : unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
3985 349 : blkdat.FindByte(Params().MessageStart()[0]);
3986 344 : nRewind = blkdat.GetPos()+1;
3987 344 : blkdat >> buf;
3988 344 : if (memcmp(buf, Params().MessageStart(), CMessageHeader::MESSAGE_START_SIZE))
3989 0 : continue;
3990 : // read size
3991 344 : blkdat >> nSize;
3992 344 : if (nSize < 80 || nSize > MAX_BLOCK_SIZE_CURRENT)
3993 0 : continue;
3994 5 : } catch (const std::exception&) {
3995 : // no valid block header found; don't complain
3996 5 : break;
3997 : }
3998 344 : try {
3999 : // read block
4000 344 : uint64_t nBlockPos = blkdat.GetPos();
4001 344 : if (dbp)
4002 344 : dbp->nPos = nBlockPos;
4003 344 : blkdat.SetLimit(nBlockPos + nSize);
4004 344 : blkdat.SetPos(nBlockPos);
4005 344 : CBlock block;
4006 344 : blkdat >> block;
4007 344 : nRewind = blkdat.GetPos();
4008 :
4009 344 : uint256 hash = block.GetHash();
4010 344 : CBlockIndex* pindex{nullptr};
4011 344 : {
4012 344 : LOCK(cs_main);
4013 : // detect out of order blocks, and store them for later
4014 344 : if (hash != Params().GetConsensus().hashGenesisBlock && !LookupBlockIndex(block.hashPrevBlock)) {
4015 0 : LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__,
4016 : hash.ToString(), block.hashPrevBlock.ToString());
4017 0 : if (dbp)
4018 0 : mapBlocksUnknownParent.emplace(block.hashPrevBlock, *dbp);
4019 0 : continue;
4020 : }
4021 :
4022 344 : pindex = LookupBlockIndex(hash);
4023 : }
4024 :
4025 : // process in case the block isn't known yet
4026 344 : if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
4027 688 : std::shared_ptr<const CBlock> block_ptr = std::make_shared<const CBlock>(block);
4028 344 : stateCatcher.get().setBlockHash(block_ptr->GetHash());
4029 344 : if (ProcessNewBlock(block_ptr, dbp)) {
4030 344 : nLoaded++;
4031 : }
4032 688 : if (stateCatcher.get().stateErrorFound()) {
4033 : break;
4034 : }
4035 0 : } else if (hash != Params().GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
4036 0 : LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
4037 : }
4038 :
4039 : // Recursively process earlier encountered successors of this block
4040 688 : std::deque<uint256> queue;
4041 344 : queue.push_back(hash);
4042 688 : while (!queue.empty()) {
4043 344 : uint256 head = queue.front();
4044 344 : queue.pop_front();
4045 344 : std::pair<std::multimap<uint256, FlatFilePos>::iterator, std::multimap<uint256, FlatFilePos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
4046 344 : while (range.first != range.second) {
4047 0 : std::multimap<uint256, FlatFilePos>::iterator it = range.first;
4048 0 : if (ReadBlockFromDisk(block, it->second)) {
4049 0 : LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
4050 : head.ToString());
4051 0 : std::shared_ptr<const CBlock> block_ptr = std::make_shared<const CBlock>(block);
4052 0 : if (ProcessNewBlock(block_ptr, &it->second)) {
4053 0 : nLoaded++;
4054 0 : queue.emplace_back(block.GetHash());
4055 : }
4056 : }
4057 0 : range.first++;
4058 0 : mapBlocksUnknownParent.erase(it);
4059 : }
4060 : }
4061 0 : } catch (const std::exception& e) {
4062 0 : LogPrintf("%s : Deserialize or I/O error - %s\n", __func__, e.what());
4063 : }
4064 : }
4065 0 : } catch (const std::runtime_error& e) {
4066 0 : AbortNode(std::string("System error: ") + e.what());
4067 : }
4068 5 : if (nLoaded > 0)
4069 5 : LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
4070 5 : return nLoaded > 0;
4071 : }
4072 :
4073 124130 : void static CheckBlockIndex()
4074 : {
4075 124130 : if (!fCheckBlockIndex) {
4076 10 : return;
4077 : }
4078 :
4079 248250 : LOCK(cs_main);
4080 :
4081 : // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
4082 : // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
4083 : // iterating the block tree require that chainActive has been initialized.)
4084 124130 : if (chainActive.Height() < 0) {
4085 10 : assert(mapBlockIndex.size() <= 1);
4086 20 : return;
4087 : }
4088 :
4089 : // Build forward-pointing map of the entire block tree.
4090 248240 : std::multimap<CBlockIndex*, CBlockIndex*> forward;
4091 31726400 : for (auto& entry : mapBlockIndex) {
4092 31602280 : forward.emplace(entry.second->pprev, entry.second);
4093 : }
4094 :
4095 124120 : assert(forward.size() == mapBlockIndex.size());
4096 :
4097 124120 : std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr);
4098 124120 : CBlockIndex* pindex = rangeGenesis.first->second;
4099 124120 : rangeGenesis.first++;
4100 124120 : assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent nullptr.
4101 :
4102 : // Iterate over the entire block tree, using depth-first search.
4103 : // Along the way, remember whether there are blocks on the path from genesis
4104 : // block being explored which are the first to have certain properties.
4105 : size_t nNodes = 0;
4106 : int nHeight = 0;
4107 : CBlockIndex* pindexFirstInvalid = nullptr; // Oldest ancestor of pindex which is invalid.
4108 : CBlockIndex* pindexFirstMissing = nullptr; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
4109 : CBlockIndex* pindexFirstNotTreeValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
4110 : CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
4111 : CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
4112 31726400 : while (pindex != nullptr) {
4113 31602280 : nNodes++;
4114 31602280 : if (pindexFirstInvalid == nullptr && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
4115 31602280 : if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
4116 31602280 : if (pindex->pprev != nullptr && pindexFirstNotTreeValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
4117 31602280 : if (pindex->pprev != nullptr && pindexFirstNotChainValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
4118 31602280 : if (pindex->pprev != nullptr && pindexFirstNotScriptsValid == nullptr && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
4119 :
4120 : // Begin: actual consistency checks.
4121 31602280 : if (pindex->pprev == nullptr) {
4122 : // Genesis block checks.
4123 124120 : assert(pindex->GetBlockHash() == Params().GetConsensus().hashGenesisBlock); // Genesis block's hash must match.
4124 248240 : assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
4125 : }
4126 : // HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block)
4127 31602280 : assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
4128 31602280 : assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0));
4129 31602280 : if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
4130 : // All parents having data is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
4131 31602280 : assert((pindexFirstMissing != nullptr) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available.
4132 31602280 : assert(pindex->nHeight == nHeight); // nHeight must be consistent.
4133 31602280 : assert(pindex->pprev == nullptr || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
4134 31602280 : assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
4135 31602280 : assert(pindexFirstNotTreeValid == nullptr); // All mapBlockIndex entries must at least be TREE valid
4136 31602280 : if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == nullptr); // TREE valid implies all parents are TREE valid
4137 31602280 : if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == nullptr); // CHAIN valid implies all parents are CHAIN valid
4138 31602280 : if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == nullptr); // SCRIPTS valid implies all parents are SCRIPTS valid
4139 31602280 : if (pindexFirstInvalid == nullptr) {
4140 : // Checks for not-invalid blocks.
4141 31590930 : assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
4142 : }
4143 63204470 : if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstMissing == nullptr) {
4144 166745 : if (pindexFirstInvalid == nullptr) { // If this block sorts at least as good as the current tip and is valid, it must be in setBlockIndexCandidates.
4145 330284 : assert(setBlockIndexCandidates.count(pindex));
4146 : }
4147 : } else { // If this block sorts worse than the current tip, it cannot be in setBlockIndexCandidates.
4148 62871050 : assert(setBlockIndexCandidates.count(pindex) == 0);
4149 : }
4150 : // Check whether this block is in mapBlocksUnlinked.
4151 31602280 : std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
4152 31602280 : bool foundInUnlinked = false;
4153 31602280 : while (rangeUnlinked.first != rangeUnlinked.second) {
4154 0 : assert(rangeUnlinked.first->first == pindex->pprev);
4155 0 : if (rangeUnlinked.first->second == pindex) {
4156 : foundInUnlinked = true;
4157 : break;
4158 : }
4159 31602280 : rangeUnlinked.first++;
4160 : }
4161 31602280 : if (pindex->pprev && pindex->nStatus & BLOCK_HAVE_DATA && pindexFirstMissing != nullptr) {
4162 0 : if (pindexFirstInvalid == nullptr) { // If this block has block data available, some parent doesn't, and has no invalid parents, it must be in mapBlocksUnlinked.
4163 0 : assert(foundInUnlinked);
4164 : }
4165 : } else { // If this block does not have block data available, or all parents do, it cannot be in mapBlocksUnlinked.
4166 31602280 : assert(!foundInUnlinked);
4167 : }
4168 : // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
4169 : // End: actual consistency checks.
4170 :
4171 : // Try descending into the first subnode.
4172 31602280 : std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4173 31602280 : if (range.first != range.second) {
4174 : // A subnode was found.
4175 31469140 : pindex = range.first->second;
4176 31469140 : nHeight++;
4177 31469140 : continue;
4178 : }
4179 : // This is a leaf node.
4180 : // Move upwards until we reach a node of which we have not yet visited the last child.
4181 31726400 : while (pindex) {
4182 : // We are going to either move to a parent or a sibling of pindex.
4183 : // If pindex was the first with a certain property, unset the corresponding variable.
4184 31602280 : if (pindex == pindexFirstInvalid) pindexFirstInvalid = nullptr;
4185 31602280 : if (pindex == pindexFirstMissing) pindexFirstMissing = nullptr;
4186 31602280 : if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = nullptr;
4187 31602280 : if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr;
4188 31602280 : if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr;
4189 : // Find our parent.
4190 31602280 : CBlockIndex* pindexPar = pindex->pprev;
4191 : // Find which child we just visited.
4192 31602280 : std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4193 31614700 : while (rangePar.first->second != pindex) {
4194 12416 : assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
4195 31614700 : rangePar.first++;
4196 : }
4197 : // Proceed to the next one.
4198 31602280 : rangePar.first++;
4199 31602280 : if (rangePar.first != rangePar.second) {
4200 : // Move to the sibling.
4201 8987 : pindex = rangePar.first->second;
4202 8987 : break;
4203 : } else {
4204 : // Move up further.
4205 31593260 : pindex = pindexPar;
4206 31593260 : nHeight--;
4207 31593260 : continue;
4208 : }
4209 : }
4210 : }
4211 :
4212 : // Check that we actually traversed the entire map.
4213 124120 : assert(nNodes == forward.size());
4214 : }
4215 :
4216 : // Note: whenever a protocol update is needed toggle between both implementations (comment out the formerly active one)
4217 : // so we can leave the existing clients untouched (old SPORK will stay on so they don't see even older clients).
4218 : // Those old clients won't react to the changes of the other (new) SPORK because at the time of their implementation
4219 : // it was the one which was commented out
4220 86306 : int ActiveProtocol()
4221 : {
4222 : // SPORK_14 is used for 70926 (v5.5.0), commented out now.
4223 : //if (sporkManager.IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT))
4224 : // return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;
4225 :
4226 : // SPORK_15 is used for 70927 (v5.6.0), commented out now.
4227 86306 : if (sporkManager.IsSporkActive(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2))
4228 0 : return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT;
4229 :
4230 : return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT;
4231 : }
4232 :
4233 353 : std::string CBlockFileInfo::ToString() const
4234 : {
4235 706 : return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
4236 : }
4237 :
4238 1 : CBlockFileInfo* GetBlockFileInfo(size_t n)
4239 : {
4240 1 : return &vinfoBlockFile.at(n);
4241 : }
4242 :
4243 : static const uint64_t MEMPOOL_DUMP_VERSION = 1;
4244 :
4245 347 : bool LoadMempool(CTxMemPool& pool)
4246 : {
4247 347 : int64_t nExpiryTimeout = gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
4248 694 : FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "r");
4249 694 : CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
4250 347 : if (file.IsNull()) {
4251 271 : LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n");
4252 : return false;
4253 : }
4254 :
4255 76 : int64_t count = 0;
4256 76 : int64_t skipped = 0;
4257 76 : int64_t failed = 0;
4258 76 : int64_t nNow = GetTime();
4259 :
4260 76 : try {
4261 76 : uint64_t version;
4262 76 : file >> version;
4263 76 : if (version != MEMPOOL_DUMP_VERSION) {
4264 0 : return false;
4265 : }
4266 76 : uint64_t num;
4267 76 : file >> num;
4268 99 : while (num--) {
4269 23 : CTransactionRef tx;
4270 23 : int64_t nTime;
4271 23 : int64_t nFeeDelta;
4272 23 : file >> tx;
4273 23 : file >> nTime;
4274 23 : file >> nFeeDelta;
4275 :
4276 23 : CAmount amountdelta = nFeeDelta;
4277 23 : if (amountdelta) {
4278 0 : pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
4279 : }
4280 46 : CValidationState state;
4281 23 : if (nTime + nExpiryTimeout > nNow) {
4282 46 : LOCK(cs_main);
4283 23 : AcceptToMemoryPoolWithTime(pool, state, tx, true, nullptr, nTime);
4284 23 : if (state.IsValid()) {
4285 21 : ++count;
4286 : } else {
4287 2 : ++failed;
4288 : }
4289 : } else {
4290 0 : ++skipped;
4291 : }
4292 23 : if (ShutdownRequested())
4293 0 : return false;
4294 : }
4295 76 : std::map<uint256, CAmount> mapDeltas;
4296 76 : file >> mapDeltas;
4297 :
4298 76 : for (const auto& i : mapDeltas) {
4299 0 : pool.PrioritiseTransaction(i.first, i.second);
4300 : }
4301 0 : } catch (const std::exception& e) {
4302 0 : LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
4303 0 : return false;
4304 : }
4305 :
4306 76 : LogPrintf("Imported mempool transactions from disk: %i successes, %i failed, %i expired\n", count, failed, skipped);
4307 : return true;
4308 : }
4309 :
4310 347 : bool DumpMempool(const CTxMemPool& pool)
4311 : {
4312 347 : int64_t start = GetTimeMicros();
4313 :
4314 694 : std::map<uint256, CAmount> mapDeltas;
4315 694 : std::vector<TxMempoolInfo> vinfo;
4316 :
4317 347 : static Mutex dump_mutex;
4318 694 : LOCK(dump_mutex);
4319 :
4320 347 : {
4321 347 : LOCK(pool.cs);
4322 347 : for (const auto &i : pool.mapDeltas) {
4323 0 : mapDeltas[i.first] = i.second;
4324 : }
4325 694 : vinfo = pool.infoAll();
4326 : }
4327 :
4328 347 : int64_t mid = GetTimeMicros();
4329 :
4330 347 : try {
4331 694 : FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "w");
4332 347 : if (!filestr) {
4333 0 : return false;
4334 : }
4335 :
4336 347 : CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
4337 :
4338 347 : uint64_t version = MEMPOOL_DUMP_VERSION;
4339 347 : file << version;
4340 :
4341 347 : file << (uint64_t)vinfo.size();
4342 1192 : for (const auto& i : vinfo) {
4343 845 : file << i.tx;
4344 845 : file << (int64_t)i.nTime;
4345 845 : file << (int64_t)i.nFeeDelta;
4346 845 : mapDeltas.erase(i.tx->GetHash());
4347 : }
4348 :
4349 347 : file << mapDeltas;
4350 347 : if (!FileCommit(file.Get()))
4351 0 : throw std::runtime_error("FileCommit failed");
4352 347 : file.fclose();
4353 1388 : if (!RenameOver(GetDataDir() / "mempool.dat.new", GetDataDir() / "mempool.dat")) {
4354 0 : throw std::runtime_error("Rename failed");
4355 : }
4356 347 : int64_t last = GetTimeMicros();
4357 347 : LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*0.000001, (last-mid)*0.000001);
4358 0 : } catch (const std::exception& e) {
4359 0 : LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
4360 0 : return false;
4361 : }
4362 347 : return true;
4363 : }
4364 :
4365 : class CMainCleanup
4366 : {
4367 : public:
4368 : CMainCleanup() {}
4369 479 : ~CMainCleanup()
4370 : {
4371 : // block headers
4372 479 : BlockMap::iterator it1 = mapBlockIndex.begin();
4373 72058 : for (; it1 != mapBlockIndex.end(); it1++)
4374 143158 : delete (*it1).second;
4375 479 : mapBlockIndex.clear();
4376 479 : }
4377 : } instance_of_cmaincleanup;
4378 :
|