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