55 #include <boost/algorithm/string/replace.hpp> 56 #include <boost/thread.hpp> 62 #define MICRO 0.000001 125 std::vector<CBlockFileInfo> vinfoBlockFile;
126 int nLastBlockFile = 0;
132 bool fCheckForPruning =
false;
135 std::set<const CBlockIndex *> setDirtyBlockIndex;
138 std::set<int> setDirtyFileInfo;
142 : excessiveBlockSize(config.GetMaxBlockSize()), checkPoW(true),
143 checkMerkleRoot(true) {}
147 BlockMap::const_iterator it = g_chainman.
BlockIndex().find(hash);
148 return it == g_chainman.
BlockIndex().end() ? nullptr : it->second;
175 std::set<int> &setFilesToPrune,
176 int nManualPruneHeight);
178 std::set<int> &setFilesToPrune,
179 uint64_t nPruneAfterHeight);
208 assert(tip !=
nullptr);
219 std::pair<int, int64_t> lockPair;
220 if (useExistingLockPoints) {
222 lockPair.first = lp->
height;
223 lockPair.second = lp->
time;
227 std::vector<int> prevheights;
228 prevheights.resize(tx.
vin.size());
229 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
230 const CTxIn &txin = tx.
vin[txinIndex];
233 return error(
"%s: Missing input", __func__);
237 prevheights[txinIndex] = tip->
nHeight + 1;
239 prevheights[txinIndex] = coin.
GetHeight();
244 lp->
height = lockPair.first;
245 lp->
time = lockPair.second;
259 int maxInputHeight = 0;
260 for (
const int height : prevheights) {
263 if (height != tip->
nHeight + 1) {
264 maxInputHeight = std::max(maxInputHeight, height);
278 int64_t nMedianTimePast) {
279 return nMedianTimePast >=
gArgs.
GetArg(
"-replayprotectionactivationtime",
285 if (pindexPrev ==
nullptr) {
306 assert(!tx.IsCoinBase());
307 for (
const CTxIn &txin : tx.vin) {
324 const Coin &coinFromDisk =
326 assert(!coinFromDisk.
IsSpent());
340 class MemPoolAccept {
343 : m_pool(mempool), m_view(&m_dummy),
347 m_limit_ancestor_size(
352 m_limit_descendant_size(
gArgs.
GetArg(
"-limitdescendantsize",
361 const int64_t m_accept_time;
362 const bool m_bypass_limits;
363 const Amount &m_absurd_fee;
371 std::vector<COutPoint> &m_coins_to_uncache;
372 const bool m_test_accept;
376 bool AcceptSingleTransaction(
const CTransactionRef &ptx, ATMPArgs &args)
384 const uint32_t next_block_script_verify_flags)
386 m_next_block_script_verify_flags(next_block_script_verify_flags) {
389 std::unique_ptr<CTxMemPoolEntry> m_entry;
397 const uint32_t m_next_block_script_verify_flags;
398 int m_sig_checks_standard;
406 bool PreChecks(ATMPArgs &args, Workspace &ws)
413 bool ConsensusScriptChecks(ATMPArgs &args, Workspace &ws,
420 bool Finalize(ATMPArgs &args, Workspace &ws)
430 const size_t m_limit_ancestors;
431 const size_t m_limit_ancestor_size;
434 size_t m_limit_descendants;
435 size_t m_limit_descendant_size;
438 bool MemPoolAccept::PreChecks(ATMPArgs &args, Workspace &ws) {
441 const TxId &txid = ws.m_ptx->GetId();
445 const int64_t nAcceptTime = args.m_accept_time;
446 const bool bypass_limits = args.m_bypass_limits;
447 const Amount &nAbsurdFee = args.m_absurd_fee;
448 std::vector<COutPoint> &coins_to_uncache = args.m_coins_to_uncache;
452 std::unique_ptr<CTxMemPoolEntry> &entry = ws.m_entry;
453 Amount &nModifiedFees = ws.m_modified_fees;
472 args.m_config.GetChainParams().GetConsensus(), tx, ctxState,
477 ctxState.GetRejectReason(),
478 ctxState.GetDebugMessage());
482 if (m_pool.exists(txid)) {
484 "txn-already-in-mempool");
489 auto itConflicting = m_pool.mapNextTx.find(txin.
prevout);
490 if (itConflicting != m_pool.mapNextTx.end()) {
493 "txn-mempool-conflict");
498 m_view.SetBackend(m_viewmempool);
504 coins_to_uncache.push_back(txin.
prevout);
511 if (!m_view.HaveCoin(txin.
prevout)) {
513 for (
size_t out = 0; out < tx.
vout.size(); out++) {
518 "txn-already-known");
525 "bad-txns-inputs-missingorspent");
530 if (!m_view.HaveInputs(tx)) {
532 "bad-txns-inputs-spent");
536 m_view.GetBestBlock();
541 m_view.SetBackend(m_dummy);
556 return error(
"%s: Consensus::CheckTxInputs: %s, %s", __func__,
564 "bad-txns-nonstandard-inputs");
568 nModifiedFees = nFees;
569 m_pool.ApplyDelta(txid, nModifiedFees);
573 bool fSpendsCoinbase =
false;
575 const Coin &coin = m_view.AccessCoin(txin.
prevout);
577 fSpendsCoinbase =
true;
588 if (!bypass_limits && nModifiedFees < minRelayTxFee.
GetFee(nSize)) {
594 if (nAbsurdFee !=
Amount::zero() && nFees > nAbsurdFee) {
597 strprintf(
"%d > %d", nFees, nAbsurdFee));
601 const uint32_t scriptVerifyFlags =
605 txdata, ws.m_sig_checks_standard)) {
612 ws.m_sig_checks_standard, lp));
614 unsigned int nVirtualSize = entry->GetTxVirtualSize();
621 if (!bypass_limits && mempoolRejectFee >
Amount::zero() &&
622 nModifiedFees < mempoolRejectFee) {
625 strprintf(
"%d < %d", nModifiedFees, mempoolRejectFee));
629 std::string errString;
630 if (!m_pool.CalculateMemPoolAncestors(
631 *entry, setAncestors, m_limit_ancestors, m_limit_ancestor_size,
632 m_limit_descendants, m_limit_descendant_size, errString)) {
634 "too-long-mempool-chain", errString);
639 bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs &args, Workspace &ws,
657 int nSigChecksConsensus;
659 ws.m_next_block_script_verify_flags,
660 txdata, nSigChecksConsensus)) {
664 return error(
"%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed " 665 "against next-block but not STANDARD flags %s, %s",
669 if (ws.m_sig_checks_standard != nSigChecksConsensus) {
674 "%s: BUG! PLEASE REPORT THIS! SigChecks count differed between " 675 "standard and consensus flags in %s",
681 bool MemPoolAccept::Finalize(ATMPArgs &args, Workspace &ws) {
682 const TxId &txid = ws.m_ptx->GetId();
684 const bool bypass_limits = args.m_bypass_limits;
687 std::unique_ptr<CTxMemPoolEntry> &entry = ws.m_entry;
690 m_pool.addUnchecked(*entry, setAncestors);
693 if (!bypass_limits) {
698 if (!m_pool.exists(txid)) {
706 bool MemPoolAccept::AcceptSingleTransaction(
const CTransactionRef &ptx,
714 args.m_config.GetChainParams().GetConsensus(),
717 if (!PreChecks(args, workspace)) {
727 if (!ConsensusScriptChecks(args, workspace, txdata)) {
732 if (args.m_test_accept) {
736 if (!Finalize(args, workspace)) {
752 int64_t nAcceptTime,
bool bypass_limits,
753 const Amount nAbsurdFee,
bool test_accept)
756 std::vector<COutPoint> coins_to_uncache;
757 MemPoolAccept::ATMPArgs args{config, state, nAcceptTime,
758 bypass_limits, nAbsurdFee, coins_to_uncache,
760 bool res = MemPoolAccept(pool).AcceptSingleTransaction(tx, args);
768 for (
const COutPoint &outpoint : coins_to_uncache) {
783 bool bypass_limits,
const Amount nAbsurdFee,
786 bypass_limits, nAbsurdFee, test_accept);
799 if (block_index ==
nullptr) {
807 return g_txindex->FindTx(txid, hashBlock, txOut);
812 for (
const auto &tx : block.
vtx) {
813 if (tx->GetId() == txid) {
835 return error(
"WriteBlockToDisk: OpenBlockFile failed");
840 fileout << messageStart << nSize;
843 long fileOutPos = ftell(fileout.
Get());
844 if (fileOutPos < 0) {
845 return error(
"WriteBlockToDisk: ftell failed");
848 pos.
nPos = (
unsigned int)fileOutPos;
857 if (halvings >= 64) {
868 bool in_memory,
bool should_wipe)
869 : m_dbview(
GetDataDir() / ldb_name, cache_size_bytes, in_memory,
871 m_catcherview(&m_dbview) {}
873 void CoinsViews::InitCache() {
874 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
879 : m_blockman(blockman), m_from_snapshot_blockhash(from_snapshot_blockhash) {
883 bool should_wipe, std::string leveldb_name) {
887 m_coins_views = std::make_unique<CoinsViews>(leveldb_name, cache_size_bytes,
888 in_memory, should_wipe);
891 void CChainState::InitCoinsCache() {
923 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
933 return g_chainman.m_blockman.m_block_index;
938 #if defined(HAVE_SYSTEM) 939 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
940 if (strCmd.empty()) {
947 std::string singleQuote(
"'");
949 safeStatus = singleQuote + safeStatus + singleQuote;
950 boost::replace_all(strCmd,
"%s", safeStatus);
952 std::thread t(runCommand, strCmd);
969 if (pindexBestForkTip &&
971 pindexBestForkTip =
nullptr;
974 if (pindexBestForkTip ||
975 (pindexBestInvalid &&
976 pindexBestInvalid->nChainWork >
980 std::string warning =
981 std::string(
"'Warning: Large-work fork detected, forking after " 987 if (pindexBestForkTip && pindexBestForkBase) {
988 LogPrintf(
"%s: Warning: Large fork found\n forking the " 989 "chain at height %d (%s)\n lasting to height %d " 990 "(%s).\nChain state database corruption likely.\n",
991 __func__, pindexBestForkBase->
nHeight,
997 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks " 998 "longer than our best chain.\nChain state database " 999 "corruption likely.\n",
1024 (!pindexBestForkTip ||
1028 ::
ChainActive().Height() - pindexNewForkTip->nHeight < 72) {
1029 pindexBestForkTip = pindexNewForkTip;
1030 pindexBestForkBase = pfork;
1039 if (!pindexBestInvalid ||
1040 pindexNew->
nChainWork > pindexBestInvalid->nChainWork) {
1041 pindexBestInvalid = pindexNew;
1043 if (pindexBestHeader !=
nullptr &&
1051 m_finalizedBlockIndex = pindexNew->
pprev;
1054 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%.8g date=%s\n",
1061 LogPrintf(
"%s: current best=%s height=%d log2_work=%.8g date=%s\n",
1075 setDirtyBlockIndex.insert(pindex);
1115 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1116 if (!
VerifyScript(scriptSig, m_tx_out.scriptPubKey, nFlags,
1118 ptxTo, nIn, m_tx_out.nValue, cacheStore, txdata),
1122 if ((pTxLimitSigChecks &&
1123 !pTxLimitSigChecks->consume_and_check(metrics.nSigChecks)) ||
1124 (pBlockLimitSigChecks &&
1125 !pBlockLimitSigChecks->consume_and_check(metrics.nSigChecks))) {
1138 return pindexPrev->
nHeight + 1;
1143 bool sigCacheStore,
bool scriptCacheStore,
1147 std::vector<CScriptCheck> *pvChecks) {
1152 pvChecks->reserve(tx.
vin.size());
1162 (pBlockLimitSigChecks &&
1165 "too-many-sigchecks");
1170 int nSigChecksTotal = 0;
1172 for (
size_t i = 0; i < tx.
vin.size(); i++) {
1185 &txLimitSigChecks, pBlockLimitSigChecks);
1189 pvChecks->push_back(std::move(check));
1199 uint32_t mandatoryFlags =
1201 if (flags != mandatoryFlags) {
1208 sigCacheStore, txdata);
1212 strprintf(
"non-mandatory-script-verify-flag (%s)",
1216 scriptError = check2.GetScriptError();
1228 strprintf(
"mandatory-script-verify-flag-failed (%s)",
1232 nSigChecksTotal += check.GetScriptExecutionMetrics().nSigChecks;
1235 nSigChecksOut = nSigChecksTotal;
1237 if (scriptCacheStore && !pvChecks) {
1252 return error(
"%s: OpenUndoFile failed", __func__);
1257 fileout << messageStart << nSize;
1260 long fileOutPos = ftell(fileout.
Get());
1261 if (fileOutPos < 0) {
1262 return error(
"%s: ftell failed", __func__);
1264 pos.
nPos = (
unsigned int)fileOutPos;
1265 fileout << blockundo;
1269 hasher << hashBlock;
1270 hasher << blockundo;
1279 return error(
"%s: no undo data available", __func__);
1285 return error(
"%s: OpenUndoFile failed", __func__);
1294 verifier >> blockundo;
1295 filein >> hashChecksum;
1296 }
catch (
const std::exception &e) {
1297 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1301 if (hashChecksum != verifier.
GetHash()) {
1302 return error(
"%s: Checksum mismatch", __func__);
1313 if (!user_message.empty()) {
1315 _(
"A fatal internal error occurred, see debug.log for details");
1323 const std::string &strMessage,
1326 return state.
Error(strMessage);
1362 view.
AddCoin(out, std::move(undo), !fClean);
1376 error(
"DisconnectBlock(): failure reading undo data");
1388 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1389 error(
"DisconnectBlock(): block and undo data inconsistent");
1394 for (
size_t i = 1; i < block.
vtx.size(); i++) {
1398 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1402 for (
size_t j = 0; j < tx.
vin.size(); j++) {
1414 for (
const auto &ptx : block.
vtx) {
1421 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1422 if (tx.
vout[o].scriptPubKey.IsUnspendable()) {
1428 bool is_spent = view.
SpendCoin(out, &coin);
1445 LOCK(cs_LastBlockFile);
1448 vinfoBlockFile[nLastBlockFile].nSize);
1450 vinfoBlockFile[nLastBlockFile].nUndoSize);
1456 AbortNode(
"Flushing block file to disk failed. This is likely the " 1457 "result of an I/O error.");
1473 return error(
"ConnectBlock(): FindUndoPos failed");
1477 return AbortNode(state,
"Failed to write undo data");
1483 setDirtyBlockIndex.insert(pindex);
1493 scriptcheckqueue.
Thread();
1505 pindexPrev, params, static_cast<Consensus::DeploymentPos>(i),
1510 params, static_cast<Consensus::DeploymentPos>(i));
1515 return nVersion & ~uint32_t(0x0f);
1626 if (!
CheckBlock(block, state, consensusParams,
1633 return AbortNode(state,
"Corrupt block found indicating potential " 1634 "hardware failure; shutting down");
1636 return error(
"%s: Consensus::CheckBlock: %s", __func__,
1657 bool fScriptChecks =
true;
1658 if (!hashAssumeValid.
IsNull()) {
1666 BlockMap::const_iterator it =
1667 m_blockman.m_block_index.find(hashAssumeValid);
1669 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
1693 *pindexBestHeader, *pindex, *pindexBestHeader,
1694 consensusParams) <= 60 * 60 * 24 * 7 * 2);
1700 nTimeCheck += nTime1 - nTimeStart;
1702 MILLI * (nTime1 - nTimeStart), nTimeCheck *
MICRO,
1703 nTimeCheck *
MILLI / nBlocksTotal);
1718 bool fEnforceBIP30 = !((pindex->
nHeight == 91842 &&
1720 uint256S(
"0x00000000000a4d0a398161ffc163c503763" 1721 "b1f4360639393e0e4c8e300e0caec")) ||
1724 uint256S(
"0x00000000000743f190a18c5577a3c2d2a1f" 1725 "610ae9601ac046a38084ccb7cd721")));
1756 static constexpr
int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
1786 assert(pindex->
pprev);
1793 (!pindexBIP34height ||
1799 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
1800 for (
const auto &tx : block.
vtx) {
1801 for (
size_t o = 0; o < tx->vout.size(); o++) {
1803 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite " 1813 int nLockTimeFlags = 0;
1818 const uint32_t
flags =
1822 nTimeForks += nTime2 - nTime1;
1824 MILLI * (nTime2 - nTime1), nTimeForks * MICRO,
1825 nTimeForks *
MILLI / nBlocksTotal);
1827 std::vector<int> prevheights;
1839 std::vector<TxSigCheckLimiter> nSigChecksTxLimiters;
1840 nSigChecksTxLimiters.resize(block.
vtx.size() - 1);
1843 blockundo.
vtxundo.resize(block.
vtx.size() - 1);
1850 for (
const auto &ptx : block.
vtx) {
1853 }
catch (
const std::logic_error &e) {
1862 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
1868 for (
const auto &ptx : block.
vtx) {
1871 nInputs += tx.
vin.size();
1885 return error(
"%s: Consensus::CheckTxInputs: %s, %s", __func__,
1892 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n",
1895 "bad-txns-accumulated-fee-outofrange");
1906 prevheights.resize(tx.
vin.size());
1907 for (
size_t j = 0; j < tx.
vin.size(); j++) {
1911 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
1912 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n",
1915 "bad-txns-nonfinal");
1920 bool fCacheResults = fJustCheck;
1923 if (!fEnforceSigCheck) {
1930 std::vector<CScriptCheck> vChecks;
1935 if (fScriptChecks &&
1938 nSigChecksRet, nSigChecksTxLimiters[txIndex],
1939 &nSigChecksBlockLimiter, &vChecks)) {
1946 "ConnectBlock(): CheckInputScripts on %s failed with %s",
1950 control.
Add(vChecks);
1962 nTimeConnect += nTime3 - nTime2;
1964 " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) " 1965 "[%.2fs (%.2fms/blk)]\n",
1966 (
unsigned)block.
vtx.size(),
MILLI * (nTime3 - nTime2),
1967 MILLI * (nTime3 - nTime2) / block.
vtx.size(),
1968 nInputs <= 1 ? 0 :
MILLI * (nTime3 - nTime2) / (nInputs - 1),
1973 if (block.
vtx[0]->GetValueOut() > blockReward) {
1974 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs " 1976 block.
vtx[0]->GetValueOut(), blockReward);
1981 const std::vector<CTxDestination> whitelist =
1983 if (!whitelist.empty()) {
1986 for (
auto &o : block.
vtx[0]->vout) {
1987 if (o.nValue < required) {
1998 if (std::find(whitelist.begin(), whitelist.end(), address) !=
2000 goto MinerFundSuccess;
2006 "bad-cb-minerfund");
2011 if (!control.
Wait()) {
2013 "blk-bad-inputs",
"parallel script check failed");
2017 nTimeVerify += nTime4 - nTime2;
2020 " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n",
2021 nInputs - 1,
MILLI * (nTime4 - nTime2),
2022 nInputs <= 1 ? 0 :
MILLI * (nTime4 - nTime2) / (nInputs - 1),
2023 nTimeVerify * MICRO, nTimeVerify *
MILLI / nBlocksTotal);
2035 setDirtyBlockIndex.insert(pindex);
2043 nTimeIndex += nTime5 - nTime4;
2045 MILLI * (nTime5 - nTime4), nTimeIndex * MICRO,
2046 nTimeIndex *
MILLI / nBlocksTotal);
2049 nTimeCallbacks += nTime6 - nTime5;
2051 MILLI * (nTime6 - nTime5), nTimeCallbacks * MICRO,
2052 nTimeCallbacks *
MILLI / nBlocksTotal);
2058 CChainState::GetCoinsCacheSizeState(
const CTxMemPool &tx_pool) {
2059 return this->GetCoinsCacheSizeState(
2065 CChainState::GetCoinsCacheSizeState(
const CTxMemPool &tx_pool,
2066 size_t max_coins_cache_size_bytes,
2067 size_t max_mempool_size_bytes) {
2070 int64_t nTotalSpace =
2071 max_coins_cache_size_bytes +
2072 std::max<int64_t>(max_mempool_size_bytes - nMempoolUsage, 0);
2075 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES =
2077 int64_t large_threshold = std::max(
2078 (9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2080 if (cacheSize > nTotalSpace) {
2081 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize,
2084 }
else if (cacheSize > large_threshold) {
2093 int nManualPruneHeight) {
2095 assert(this->CanFlushToDisk());
2096 static int64_t nLastWrite = 0;
2097 static int64_t nLastFlush = 0;
2098 std::set<int> setFilesToPrune;
2099 bool full_flush_completed =
false;
2106 bool fFlushForPrune =
false;
2107 bool fDoFullFlush =
false;
2109 GetCoinsCacheSizeState(::g_mempool);
2110 LOCK(cs_LastBlockFile);
2111 if (
fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) &&
2113 if (nManualPruneHeight > 0) {
2117 nManualPruneHeight);
2122 fCheckForPruning =
false;
2124 if (!setFilesToPrune.empty()) {
2125 fFlushForPrune =
true;
2127 pblocktree->WriteFlag(
"prunedblockfiles",
true);
2134 if (nLastWrite == 0) {
2137 if (nLastFlush == 0) {
2149 bool fPeriodicWrite =
2154 bool fPeriodicFlush =
2159 fCacheCritical || fPeriodicFlush || fFlushForPrune;
2161 if (fDoFullFlush || fPeriodicWrite) {
2164 return AbortNode(state,
"Disk space is too low!",
2165 _(
"Disk space is too low!"));
2181 std::vector<std::pair<int, const CBlockFileInfo *>> vFiles;
2182 vFiles.reserve(setDirtyFileInfo.size());
2183 for (
int i : setDirtyFileInfo) {
2184 vFiles.push_back(std::make_pair(i, &vinfoBlockFile[i]));
2187 setDirtyFileInfo.clear();
2189 std::vector<const CBlockIndex *> vBlocks;
2190 vBlocks.reserve(setDirtyBlockIndex.size());
2191 for (
const CBlockIndex *cbi : setDirtyBlockIndex) {
2192 vBlocks.push_back(cbi);
2195 setDirtyBlockIndex.clear();
2197 if (!
pblocktree->WriteBatchSync(vFiles, nLastBlockFile,
2200 state,
"Failed to write to block index database");
2205 if (fFlushForPrune) {
2214 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2216 strprintf(
"write coins cache to disk (%d coins, %.2fkB)",
2217 coins_count, coins_mem_usage / 1000));
2226 48 * 2 * 2 *
CoinsTip().GetCacheSize())) {
2227 return AbortNode(state,
"Disk space is too low!",
2228 _(
"Disk space is too low!"));
2234 return AbortNode(state,
"Failed to write to coin database");
2237 full_flush_completed =
true;
2241 if (full_flush_completed) {
2245 }
catch (
const std::runtime_error &e) {
2246 return AbortNode(state, std::string(
"System error while flushing: ") +
2256 LogPrintf(
"%s: failed to flush state (%s)\n", __func__,
2263 fCheckForPruning =
true;
2266 LogPrintf(
"%s: failed to flush state (%s)\n", __func__,
2278 LOCK(g_best_block_mutex);
2279 g_best_block = pindexNew->GetBlockHash();
2283 LogPrintf(
"%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%ld " 2284 "date='%s' progress=%f cache=%.1fMiB(%utxo)\n",
2285 __func__, pindexNew->GetBlockHash().ToString(),
2286 pindexNew->nHeight, pindexNew->nVersion,
2287 log(pindexNew->nChainWork.getdouble()) / log(2.0),
2288 pindexNew->GetChainTxCount(),
2314 assert(pindexDelete);
2317 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2320 return error(
"DisconnectTip(): Failed to read block");
2330 return error(
"DisconnectTip(): DisconnectBlock %s failed",
2334 bool flushed = view.
Flush();
2349 if (pindexDelete->
pprev !=
nullptr &&
2353 "Disconnecting mempool due to rewind of upgrade block\n");
2354 if (disconnectpool) {
2360 if (disconnectpool) {
2361 disconnectpool->
addForBlock(block.vtx, g_mempool);
2365 if (m_finalizedBlockIndex == pindexDelete) {
2366 m_finalizedBlockIndex = pindexDelete->
pprev;
2406 std::shared_ptr<const CBlock> pblock) {
2407 assert(!blocksConnected.back().pindex);
2410 blocksConnected.back().pindex = pindex;
2411 blocksConnected.back().pblock = std::move(pblock);
2412 blocksConnected.emplace_back();
2421 assert(!blocksConnected.back().pindex);
2422 blocksConnected.pop_back();
2423 return blocksConnected;
2432 LogPrintf(
"ERROR: %s: Trying to finalize invalid block %s\n", __func__,
2435 "finalize-invalid-block");
2439 if (m_finalizedBlockIndex &&
2441 LogPrintf(
"ERROR: %s: Trying to finalize block %s which conflicts with " 2442 "already finalized block\n",
2445 "bad-fork-prior-finalized");
2454 m_finalizedBlockIndex = pindex;
2462 const int32_t maxreorgdepth =
2465 const int64_t finalizationdelay =
2472 pindexNew->
GetAncestor(pindexNew->nHeight - maxreorgdepth);
2495 if (now >= (headerReceivedTime + finalizationdelay)) {
2499 pindex = pindex->
pprev;
2515 const std::shared_ptr<const CBlock> &pblock,
2527 std::shared_ptr<const CBlock> pthisBlock;
2529 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2531 return AbortNode(state,
"Failed to read block");
2533 pthisBlock = pblockNew;
2535 pthisBlock = pblock;
2538 const CBlock &blockConnecting = *pthisBlock;
2542 nTimeReadFromDisk += nTime2 - nTime1;
2545 (nTime2 - nTime1) *
MILLI, nTimeReadFromDisk *
MICRO);
2548 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view, params,
2556 return error(
"%s: ConnectBlock %s failed, %s", __func__,
2564 return error(
"ConnectTip(): MarkBlockAsFinal %s failed (%s)",
2570 nTimeConnectTotal += nTime3 - nTime2;
2571 assert(nBlocksTotal > 0);
2573 " - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n",
2574 (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO,
2575 nTimeConnectTotal * MILLI / nBlocksTotal);
2576 bool flushed = view.
Flush();
2581 nTimeFlush += nTime4 - nTime3;
2583 (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO,
2584 nTimeFlush * MILLI / nBlocksTotal);
2593 nTimeChainState += nTime5 - nTime4;
2595 " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n",
2596 (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO,
2597 nTimeChainState * MILLI / nBlocksTotal);
2606 if (pindexNew->
pprev !=
nullptr &&
2610 "Disconnecting mempool due to acceptance of upgrade block\n");
2619 nTimePostConnect += nTime6 - nTime5;
2620 nTimeTotal += nTime6 - nTime1;
2622 " - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n",
2623 (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO,
2624 nTimePostConnect * MILLI / nBlocksTotal);
2626 (nTime6 - nTime1) * MILLI, nTimeTotal * MICRO,
2627 nTimeTotal * MILLI / nBlocksTotal);
2644 std::set<CBlockIndex *, CBlockIndexWorkComparator>::reverse_iterator
2654 if (m_finalizedBlockIndex &&
2656 LogPrintf(
"Mark block %s invalid because it forks prior to the " 2657 "finalization point %d.\n",
2659 m_finalizedBlockIndex->nHeight);
2664 const bool fAvalancheEnabled =
2666 const bool fAutoUnpark =
2675 bool hasValidAncestor =
true;
2676 while (hasValidAncestor && pindexTest && pindexTest != pindexFork) {
2682 if (fAutoUnpark && fParkedChain) {
2688 if (!pindexTip || !pindexFork) {
2702 pindexExtraPow = pindexExtraPow->
pprev;
2707 requiredWork += (deltaWork >> 1);
2718 LogPrintf(
"Unpark chain up to block %s as it has " 2719 "accumulated enough PoW.\n",
2721 fParkedChain =
false;
2732 if (!(fInvalidChain || fParkedChain || fMissingData)) {
2735 pindexTest = pindexTest->
pprev;
2741 hasValidAncestor =
false;
2744 if (fInvalidChain &&
2745 (pindexBestInvalid ==
nullptr ||
2746 pindexNew->
nChainWork > pindexBestInvalid->nChainWork)) {
2747 pindexBestInvalid = pindexNew;
2751 (pindexBestParked ==
nullptr ||
2752 pindexNew->
nChainWork > pindexBestParked->nChainWork)) {
2753 pindexBestParked = pindexNew;
2756 LogPrintf(
"Considered switching to better tip %s but that chain " 2757 "contains a%s%s%s block.\n",
2759 fInvalidChain ?
"n invalid" :
"",
2760 fParkedChain ?
" parked" :
"",
2761 fMissingData ?
" missing-data" :
"");
2765 while (pindexTest != pindexFailed) {
2766 if (fInvalidChain || fParkedChain) {
2770 }
else if (fMissingData) {
2776 std::make_pair(pindexFailed->pprev, pindexFailed));
2779 pindexFailed = pindexFailed->pprev;
2782 if (fInvalidChain || fParkedChain) {
2794 if (hasValidAncestor) {
2827 CBlockIndex *pindexMostWork,
const std::shared_ptr<const CBlock> &pblock,
2835 bool fBlocksDisconnected =
false;
2847 "Failed to disconnect block; see debug.log for details");
2851 fBlocksDisconnected =
true;
2855 std::vector<CBlockIndex *> vpindexToConnect;
2856 bool fContinue =
true;
2858 while (fContinue && nHeight != pindexMostWork->
nHeight) {
2861 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->
nHeight);
2862 vpindexToConnect.clear();
2863 vpindexToConnect.reserve(nTargetHeight - nHeight);
2865 while (pindexIter && pindexIter->
nHeight != nHeight) {
2866 vpindexToConnect.push_back(pindexIter);
2867 pindexIter = pindexIter->
pprev;
2870 nHeight = nTargetHeight;
2874 if (!
ConnectTip(config, state, pindexConnect,
2875 pindexConnect == pindexMostWork
2877 : std::shared_ptr<const CBlock>(),
2878 connectTrace, disconnectpool)) {
2886 fInvalidFound =
true;
2898 if (!pindexOldTip ||
2909 if (fBlocksDisconnected || !disconnectpool.
isEmpty()) {
2915 "rules upgrade/downgrade\n");
2922 if (fInvalidFound) {
2942 bool fNotify =
false;
2943 bool fInitialBlockDownload =
false;
2950 if (pindexHeader != pindexHeaderOld) {
2952 fInitialBlockDownload =
2954 pindexHeaderOld = pindexHeader;
2976 std::shared_ptr<const CBlock> pblock) {
2997 boost::this_thread::interruption_point();
3010 LOCK2(cs_main, ::g_mempool.
cs);
3012 bool blocks_connected =
false;
3021 if (pindexMostWork ==
nullptr) {
3026 if (pindexMostWork ==
nullptr ||
3031 bool fInvalidFound =
false;
3032 std::shared_ptr<const CBlock> nullBlockPtr;
3034 config, state, pindexMostWork,
3035 pblock && pblock->GetHash() ==
3039 fInvalidFound, connectTrace)) {
3043 blocks_connected =
true;
3045 if (fInvalidFound) {
3047 pindexMostWork =
nullptr;
3053 assert(trace.pblock && trace.pindex);
3066 if (!blocks_connected) {
3076 if (pindexFork != pindexNewTip) {
3089 if (nStopAtHeight && pindexNewTip &&
3090 pindexNewTip->
nHeight >= nStopAtHeight) {
3102 }
while (pindexNewTip != pindexMostWork);
3113 std::shared_ptr<const CBlock> pblock) {
3165 bool pindex_was_in_chain =
false;
3166 int disconnected = 0;
3183 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
3187 for (
const auto &entry :
m_blockman.m_block_index) {
3198 candidate_blocks_by_work.insert(
3199 std::make_pair(candidate->
nChainWork, candidate));
3223 pindex_was_in_chain =
true;
3231 bool ret =
DisconnectTip(chainparams, state, &disconnectpool);
3239 config, (++disconnected <= 10) && ret,
3258 setDirtyBlockIndex.insert(invalid_walk_tip);
3261 if (invalid_walk_tip == to_mark_failed_or_parked->
pprev &&
3267 to_mark_failed_or_parked->
nStatus =
3274 setDirtyBlockIndex.insert(to_mark_failed_or_parked);
3278 auto candidate_it = candidate_blocks_by_work.lower_bound(
3280 while (candidate_it != candidate_blocks_by_work.end()) {
3282 invalid_walk_tip->
pprev)) {
3284 candidate_it = candidate_blocks_by_work.erase(candidate_it);
3293 to_mark_failed_or_parked = invalid_walk_tip;
3308 to_mark_failed_or_parked->
nStatus =
3311 setDirtyBlockIndex.insert(to_mark_failed_or_parked);
3323 for (
const std::pair<const BlockHash, CBlockIndex *> &it :
3339 if (pindex_was_in_chain) {
3342 to_mark_failed_or_parked->
pprev);
3398 if (!pindexToInvalidate) {
3405 return UnwindBlock(config, state, pindexToInvalidate,
3409 template <
typename F>
3413 if (pindex->
nStatus != newStatus &&
3417 setDirtyBlockIndex.insert(pindex);
3433 template <
typename F,
typename C,
typename AC>
3435 F f, C fChild, AC fAncestorWasChanged) {
3441 for (
auto pindexAncestor = pindex; pindexAncestor !=
nullptr;
3442 pindexAncestor = pindexAncestor->
pprev) {
3444 pindexDeepestChanged = pindexAncestor;
3450 pindexDeepestChanged) {
3452 pindexReset =
nullptr;
3456 BlockMap::iterator it =
m_blockman.m_block_index.begin();
3457 while (it !=
m_blockman.m_block_index.end()) {
3460 fAncestorWasChanged);
3470 if (m_finalizedBlockIndex) {
3471 m_finalizedBlockIndex =
3476 pindex, pindexBestInvalid,
3496 pindex, pindexBestParked,
3519 return m_finalizedBlockIndex &&
3520 m_finalizedBlockIndex->GetAncestor(pindex->
nHeight) == pindex;
3526 return m_finalizedBlockIndex;
3534 BlockMap::iterator it = m_block_index.find(hash);
3535 if (it != m_block_index.end()) {
3545 BlockMap::iterator mi =
3546 m_block_index.insert(std::make_pair(hash, pindexNew)).first;
3548 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
3549 if (miPrev != m_block_index.end()) {
3550 pindexNew->
pprev = (*miPrev).second;
3558 : pindexNew->
nTime);
3563 if (pindexBestHeader ==
nullptr ||
3565 pindexBestHeader = pindexNew;
3568 setDirtyBlockIndex.insert(pindexNew);
3579 pindexNew->
nTx = block.
vtx.size();
3586 setDirtyBlockIndex.insert(pindexNew);
3591 std::deque<CBlockIndex *> queue;
3592 queue.push_back(pindexNew);
3596 while (!queue.empty()) {
3614 std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
3615 std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
3617 while (range.first != range.second) {
3618 std::multimap<CBlockIndex *, CBlockIndex *>::iterator it =
3620 queue.push_back(it->second);
3625 }
else if (pindexNew->
pprev &&
3628 std::make_pair(pindexNew->
pprev, pindexNew));
3633 unsigned int nHeight, uint64_t nTime,
3634 bool fKnown =
false) {
3635 LOCK(cs_LastBlockFile);
3637 unsigned int nFile = fKnown ? pos.
nFile : nLastBlockFile;
3638 if (vinfoBlockFile.size() <= nFile) {
3639 vinfoBlockFile.resize(nFile + 1);
3645 if (vinfoBlockFile.size() <= nFile) {
3646 vinfoBlockFile.resize(nFile + 1);
3650 pos.
nPos = vinfoBlockFile[nFile].nSize;
3653 if ((
int)nFile != nLastBlockFile) {
3655 LogPrintf(
"Leaving block file %i: %s\n", nLastBlockFile,
3656 vinfoBlockFile[nLastBlockFile].
ToString());
3659 nLastBlockFile = nFile;
3662 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
3664 vinfoBlockFile[nFile].nSize =
3665 std::max(pos.
nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3667 vinfoBlockFile[nFile].nSize += nAddSize;
3672 size_t bytes_allocated =
3675 return AbortNode(
"Disk space is too low!",
3676 _(
"Disk space is too low!"));
3679 fCheckForPruning =
true;
3683 setDirtyFileInfo.insert(nFile);
3691 LOCK(cs_LastBlockFile);
3693 pos.
nPos = vinfoBlockFile[nFile].nUndoSize;
3694 vinfoBlockFile[nFile].nUndoSize += nAddSize;
3695 setDirtyFileInfo.insert(nFile);
3698 size_t bytes_allocated =
3701 return AbortNode(state,
"Disk space is too low!",
3702 _(
"Disk space is too low!"));
3705 fCheckForPruning =
true;
3727 "high-hash",
"proof of work failed");
3753 "bad-txnmrklroot",
"hashMerkleRoot mismatch");
3761 "bad-txns-duplicate",
"duplicate transaction");
3770 if (block.
vtx.empty()) {
3772 "bad-cb-missing",
"first tx is not coinbase");
3781 "bad-blk-length",
"size limits failed");
3785 if (currentBlockSize > nMaxBlockSize) {
3787 "bad-blk-length",
"size limits failed");
3795 strprintf(
"Coinbase check failed (txid %s) %s",
3796 block.
vtx[0]->GetId().ToString(),
3802 for (
size_t i = 1; i < block.
vtx.size(); i++) {
3803 auto *tx = block.
vtx[i].get();
3808 strprintf(
"Transaction check failed (txid %s) %s",
3835 int64_t nAdjustedTime)
3837 assert(pindexPrev !=
nullptr);
3838 const int nHeight = pindexPrev->nHeight + 1;
3842 LogPrintf(
"bad bits after height: %d\n", pindexPrev->nHeight);
3844 "bad-diffbits",
"incorrect proof of work");
3854 LogPrintf(
"ERROR: %s: rejected by checkpoint lock-in at %d\n",
3857 "checkpoint mismatch");
3864 if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
3865 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint " 3869 "bad-fork-prior-to-checkpoint");
3874 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) {
3876 "time-too-old",
"block's timestamp is too early");
3883 "block timestamp too far in the future");
3890 if ((block.nVersion < 2 && nHeight >= consensusParams.
BIP34Height) ||
3891 (block.nVersion < 3 && nHeight >= consensusParams.
BIP66Height) ||
3892 (block.nVersion < 4 && nHeight >= consensusParams.
BIP65Height)) {
3895 strprintf(
"bad-version(0x%08x)", block.nVersion),
3896 strprintf(
"rejected nVersion=0x%08x block", block.nVersion));
3913 flags = std::max(flags, 0);
3928 const int64_t nMedianTimePast =
3937 nLockTimeCutoff, nMedianTimePast);
3951 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3954 int nLockTimeFlags = 0;
3956 assert(pindexPrev !=
nullptr);
3960 const int64_t nMedianTimePast =
3967 const bool fIsMagneticAnomalyEnabled =
3978 for (
const auto &ptx : block.
vtx) {
3980 if (fIsMagneticAnomalyEnabled) {
3981 if (prevTx && (tx.
GetId() <= prevTx->
GetId())) {
3991 strprintf(
"Transaction order is invalid (%s < %s)",
4003 nLockTimeCutoff, nMedianTimePast)) {
4013 if (block.
vtx[0]->vin[0].scriptSig.size() < expect.
size() ||
4014 !std::equal(expect.
begin(), expect.
end(),
4015 block.
vtx[0]->vin[0].scriptSig.begin())) {
4018 "block height mismatch in coinbase");
4039 BlockMap::iterator miSelf = m_block_index.find(hash);
4042 if (miSelf != m_block_index.end()) {
4044 pindex = miSelf->second;
4050 LogPrintf(
"ERROR: %s: block %s is marked invalid\n", __func__,
4061 return error(
"%s: Consensus::CheckBlockHeader: %s, %s", __func__,
4066 BlockMap::iterator mi = m_block_index.find(block.
hashPrevBlock);
4067 if (mi == m_block_index.end()) {
4068 LogPrintf(
"ERROR: %s: prev block not found\n", __func__);
4070 "prev-blk-not-found");
4076 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
4083 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s, %s",
4112 for (
const CBlockIndex *failedit : m_failed_blocks) {
4113 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
4114 assert(failedit->nStatus.hasFailed());
4116 while (invalid_walk != failedit) {
4119 setDirtyBlockIndex.insert(invalid_walk);
4120 invalid_walk = invalid_walk->pprev;
4122 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
4131 if (pindex ==
nullptr) {
4132 pindex = AddToBlockIndex(block);
4144 const Config &config,
const std::vector<CBlockHeader> &headers,
4170 LogPrintf(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n",
4171 (*ppindex)->nHeight,
4173 ((*ppindex)->nHeight +
4176 (*ppindex)->nHeight);
4191 if (dbp !=
nullptr) {
4196 error(
"%s: FindBlockPos failed", __func__);
4199 if (dbp ==
nullptr) {
4220 const std::shared_ptr<const CBlock> &pblock,
4225 const CBlock &block = *pblock;
4232 bool accepted_header =
4236 if (!accepted_header) {
4255 int64_t chainTipTimeDiff =
4261 LogPrintf(
"Chain tip timestamp-to-received-time difference: hash=%s, " 4264 LogPrintf(
"New block timestamp-to-received-time difference: hash=%s, " 4269 bool fHasMoreOrSameWork =
4290 if (pindex->
nTx != 0) {
4295 if (!fHasMoreOrSameWork) {
4308 if (pindex->
nChainWork < nMinimumChainWork) {
4316 if (!
CheckBlock(block, state, consensusParams,
4322 setDirtyBlockIndex.insert(pindex);
4325 return error(
"%s: %s (block %s)", __func__, state.
ToString(),
4338 LogPrintf(
"Park block %s as it would cause a deep reorg.\n",
4341 setDirtyBlockIndex.insert(pindex);
4361 "%s: Failed to find position to write new block to disk",
4366 }
catch (
const std::runtime_error &e) {
4367 return AbortNode(state, std::string(
"System error: ") + e.what());
4378 const Config &config,
const std::shared_ptr<const CBlock> pblock,
4379 bool fForceProcessing,
bool *fNewBlock) {
4403 config, pblock, state, fForceProcessing,
nullptr, fNewBlock);
4408 return error(
"%s: AcceptBlock FAILED (%s)", __func__,
4418 return error(
"%s: ActivateBestChain failed (%s)", __func__,
4429 assert(pindexPrev && pindexPrev == ::
ChainActive().Tip());
4433 indexDummy.pprev = pindexPrev;
4435 indexDummy.phashBlock = &block_hash;
4440 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__,
4445 return error(
"%s: Consensus::CheckBlock: %s", __func__,
4451 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__,
4456 params, validationOptions,
true)) {
4472 LOCK(cs_LastBlockFile);
4474 uint64_t retval = 0;
4476 retval += file.nSize + file.nUndoSize;
4484 LOCK(cs_LastBlockFile);
4486 for (
const auto &entry :
m_blockman.m_block_index) {
4488 if (pindex->
nFile == fileNumber) {
4493 setDirtyBlockIndex.insert(pindex);
4501 while (range.first != range.second) {
4502 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it =
4505 if (_it->second == pindex) {
4512 vinfoBlockFile[fileNumber].SetNull();
4513 setDirtyFileInfo.insert(fileNumber);
4517 for (
const int i : setFilesToPrune) {
4521 LogPrintf(
"Prune: %s deleted blk/rev (%05u)\n", __func__, i);
4530 std::set<int> &setFilesToPrune,
4531 int nManualPruneHeight) {
4532 assert(
fPruneMode && nManualPruneHeight > 0);
4534 LOCK2(cs_main, cs_LastBlockFile);
4541 unsigned int nLastBlockWeCanPrune =
4542 std::min((
unsigned)nManualPruneHeight,
4545 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4546 if (vinfoBlockFile[fileNumber].nSize == 0 ||
4547 vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
4551 setFilesToPrune.insert(fileNumber);
4554 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n",
4555 nLastBlockWeCanPrune, count);
4564 LogPrintf(
"%s: failed to flush state (%s)\n", __func__,
4591 std::set<int> &setFilesToPrune,
4592 uint64_t nPruneAfterHeight) {
4593 LOCK2(cs_main, cs_LastBlockFile);
4601 unsigned int nLastBlockWeCanPrune =
4608 uint64_t nBytesToPrune;
4622 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4623 nBytesToPrune = vinfoBlockFile[fileNumber].nSize +
4624 vinfoBlockFile[fileNumber].nUndoSize;
4626 if (vinfoBlockFile[fileNumber].nSize == 0) {
4637 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
4643 setFilesToPrune.insert(fileNumber);
4644 nCurrentUsage -= nBytesToPrune;
4650 "Prune: target=%dMiB actual=%dMiB diff=%dMiB " 4651 "max_prune_height=%d removed %d blk/rev pairs\n",
4652 nPruneTarget / 1024 / 1024, nCurrentUsage / 1024 / 1024,
4653 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage) / 1024 / 1024,
4654 nLastBlockWeCanPrune, count);
4665 BlockMap::iterator mi = m_block_index.find(hash);
4666 if (mi != m_block_index.end()) {
4667 return (*mi).second;
4672 mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
4680 std::set<CBlockIndex *, CBlockIndexWorkComparator>
4681 &block_index_candidates) {
4685 cs_main) {
return this->InsertBlockIndex(hash); })) {
4690 std::vector<std::pair<int, CBlockIndex *>> vSortedByHeight;
4691 vSortedByHeight.reserve(m_block_index.size());
4692 for (
const std::pair<const BlockHash, CBlockIndex *> &item :
4695 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
4698 sort(vSortedByHeight.begin(), vSortedByHeight.end());
4699 for (
const std::pair<int, CBlockIndex *> &item : vSortedByHeight) {
4711 if (pindex->
nTx > 0) {
4713 m_blocks_unlinked.insert(std::make_pair(pindex->
pprev, pindex));
4720 setDirtyBlockIndex.insert(pindex);
4724 block_index_candidates.insert(pindex);
4728 (!pindexBestInvalid ||
4729 pindex->
nChainWork > pindexBestInvalid->nChainWork)) {
4730 pindexBestInvalid = pindex;
4734 (!pindexBestParked ||
4735 pindex->
nChainWork > pindexBestParked->nChainWork)) {
4736 pindexBestParked = pindex;
4739 if (pindex->
pprev) {
4744 (pindexBestHeader ==
nullptr ||
4746 pindexBestHeader = pindex;
4754 m_failed_blocks.clear();
4755 m_blocks_unlinked.clear();
4757 for (
const BlockMap::value_type &entry : m_block_index) {
4758 delete entry.second;
4761 m_block_index.clear();
4767 if (!chainman.m_blockman.LoadBlockIndex(
4774 pblocktree->ReadLastBlockFile(nLastBlockFile);
4775 vinfoBlockFile.resize(nLastBlockFile + 1);
4776 LogPrintf(
"%s: last block file = %i\n", __func__, nLastBlockFile);
4777 for (
int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4778 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4780 LogPrintf(
"%s: last block file info: %s\n", __func__,
4781 vinfoBlockFile[nLastBlockFile].
ToString());
4782 for (
int nFile = nLastBlockFile + 1;
true; nFile++) {
4784 if (
pblocktree->ReadBlockFileInfo(nFile, info)) {
4785 vinfoBlockFile.push_back(info);
4792 LogPrintf(
"Checking all blk files are present...\n");
4793 std::set<int> setBlkDataFiles;
4794 for (
const std::pair<const BlockHash, CBlockIndex *> &item :
4795 chainman.BlockIndex()) {
4798 setBlkDataFiles.insert(pindex->
nFile);
4802 for (
const int i : setBlkDataFiles) {
4814 "LoadBlockIndexDB(): Block files have previously been pruned\n");
4832 if (tip && tip->GetBlockHash() == coins_cache.
GetBestBlock()) {
4846 "Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4854 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, 0,
false);
4862 int nCheckLevel,
int nCheckDepth) {
4878 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4879 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth,
4885 int nGoodTransactions = 0;
4890 pindex = pindex->
pprev) {
4891 boost::this_thread::interruption_point();
4892 const int percentageDone =
4893 std::max(1, std::min(99, (
int)(((
double)(::
ChainActive().Height() -
4895 (
double)nCheckDepth *
4896 (nCheckLevel >= 4 ? 50 : 100))));
4897 if (reportDone < percentageDone / 10) {
4900 reportDone = percentageDone / 10;
4903 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated,
4904 percentageDone,
false);
4911 LogPrintf(
"VerifyDB(): block verification stopping at height %d " 4912 "(pruning, no data)\n",
4922 "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s",
4927 if (nCheckLevel >= 1 && !
CheckBlock(block, state, consensusParams,
4929 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n",
4935 if (nCheckLevel >= 2 && pindex) {
4940 "VerifyDB(): *** found bad undo data at %d, hash=%s\n",
4948 if (nCheckLevel >= 3 &&
4956 return error(
"VerifyDB(): *** irrecoverable inconsistency in " 4957 "block data at %d, hash=%s",
4963 nGoodTransactions = 0;
4964 pindexFailure = pindex;
4966 nGoodTransactions += block.
vtx.size();
4975 if (pindexFailure) {
4976 return error(
"VerifyDB(): *** coin database inconsistencies found " 4977 "(last %i blocks, %i good transactions before that)\n",
4986 if (nCheckLevel >= 4) {
4988 boost::this_thread::interruption_point();
4989 const int percentageDone = std::max(
4990 1, std::min(99, 100 -
int(
double(::
ChainActive().Height() -
4992 double(nCheckDepth) * 50)));
4993 if (reportDone < percentageDone / 10) {
4996 reportDone = percentageDone / 10;
4998 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated,
4999 percentageDone,
false);
5004 "VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s",
5008 block, state, pindex, coins, params,
5010 return error(
"VerifyDB(): *** found unconnectable block at %d, " 5019 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i " 5021 block_count, nGoodTransactions);
5036 return error(
"ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s",
5046 if (tx->IsCoinBase()) {
5050 for (
const CTxIn &txin : tx->vin) {
5065 if (hashHeads.empty()) {
5069 if (hashHeads.size() != 2) {
5070 return error(
"ReplayBlocks(): unknown inconsistent state");
5073 uiInterface.ShowProgress(
_(
"Replaying blocks...").translated, 0,
false);
5083 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
5085 "ReplayBlocks(): reorganization to unknown block requested");
5088 pindexNew =
m_blockman.m_block_index[hashHeads[0]];
5090 if (!hashHeads[1].IsNull()) {
5092 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
5094 "ReplayBlocks(): reorganization from unknown block requested");
5097 pindexOld =
m_blockman.m_block_index[hashHeads[1]];
5099 assert(pindexFork !=
nullptr);
5103 while (pindexOld != pindexFork) {
5108 return error(
"RollbackBlock(): ReadBlockFromDisk() failed at " 5119 "RollbackBlock(): DisconnectBlock failed at %d, hash=%s",
5131 pindexOld = pindexOld->
pprev;
5135 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
5141 uiInterface.ShowProgress(
_(
"Replaying blocks...").translated,
5142 (
int)((
nHeight - nForkHeight) * 100.0 /
5143 (pindexNew->
nHeight - nForkHeight)),
5163 m_finalizedBlockIndex =
nullptr;
5171 g_chainman.Unload();
5172 pindexBestInvalid =
nullptr;
5173 pindexBestParked =
nullptr;
5174 pindexBestHeader =
nullptr;
5175 pindexBestForkTip =
nullptr;
5176 pindexBestForkBase =
nullptr;
5179 vinfoBlockFile.clear();
5181 setDirtyBlockIndex.clear();
5182 setDirtyFileInfo.clear();
5196 needs_init =
m_blockman.m_block_index.empty();
5206 LogPrintf(
"Initializing databases...\n");
5226 return error(
"%s: writing genesis block to disk failed", __func__);
5230 }
catch (
const std::runtime_error &e) {
5231 return error(
"%s: failed to write genesis block: %s", __func__,
5246 static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
5258 uint64_t nRewind = blkdat.
GetPos();
5259 while (!blkdat.
eof()) {
5269 unsigned int nSize = 0;
5274 nRewind = blkdat.
GetPos() + 1;
5276 if (memcmp(buf, chainparams.
DiskMagic().data(),
5286 }
catch (
const std::exception &) {
5293 uint64_t nBlockPos = blkdat.
GetPos();
5295 dbp->
nPos = nBlockPos;
5297 blkdat.
SetLimit(nBlockPos + nSize);
5298 blkdat.
SetPos(nBlockPos);
5299 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
5302 nRewind = blkdat.
GetPos();
5312 "%s: Out of order block %s, parent %s not known\n",
5314 block.hashPrevBlock.ToString());
5316 mapBlocksUnknownParent.insert(
5317 std::make_pair(block.hashPrevBlock, *dbp));
5327 config, pblock, state,
true, dbp,
nullptr)) {
5335 pindex->
nHeight % 1000 == 0) {
5338 "Block Import: already had block %s at height %d\n",
5356 std::deque<uint256> queue;
5357 queue.push_back(hash);
5358 while (!queue.empty()) {
5361 std::pair<std::multimap<uint256, FlatFilePos>::iterator,
5362 std::multimap<uint256, FlatFilePos>::iterator>
5363 range = mapBlocksUnknownParent.equal_range(head);
5364 while (range.first != range.second) {
5365 std::multimap<uint256, FlatFilePos>::iterator it =
5367 std::shared_ptr<CBlock> pblockrecursive =
5368 std::make_shared<CBlock>();
5373 "%s: Processing out of order child %s of %s\n",
5374 __func__, pblockrecursive->GetHash().ToString(),
5379 config, pblockrecursive, dummy,
true,
5380 &it->second,
nullptr)) {
5382 queue.push_back(pblockrecursive->GetHash());
5386 mapBlocksUnknownParent.erase(it);
5390 }
catch (
const std::exception &e) {
5391 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__,
5395 }
catch (
const std::runtime_error &e) {
5396 AbortNode(std::string(
"System error: ") + e.what());
5399 LogPrintf(
"Loaded %i blocks from external file in %dms\n", nLoaded,
5415 assert(
m_blockman.m_block_index.size() <= 1);
5420 std::multimap<CBlockIndex *, CBlockIndex *> forward;
5421 for (
const auto &entry :
m_blockman.m_block_index) {
5422 forward.emplace(entry.second->pprev, entry.second);
5425 assert(forward.size() ==
m_blockman.m_block_index.size());
5427 std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
5428 std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
5429 rangeGenesis = forward.equal_range(
nullptr);
5431 rangeGenesis.first++;
5433 assert(rangeGenesis.first == rangeGenesis.second);
5453 CBlockIndex *pindexFirstNotTransactionsValid =
nullptr;
5459 CBlockIndex *pindexFirstNotScriptsValid =
nullptr;
5460 while (pindex !=
nullptr) {
5463 pindexFirstInvalid = pindex;
5466 pindexFirstParked = pindex;
5468 if (pindexFirstMissing ==
nullptr && !pindex->
nStatus.
hasData()) {
5469 pindexFirstMissing = pindex;
5471 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) {
5472 pindexFirstNeverProcessed = pindex;
5474 if (pindex->
pprev !=
nullptr && pindexFirstNotTreeValid ==
nullptr &&
5476 pindexFirstNotTreeValid = pindex;
5478 if (pindex->
pprev !=
nullptr &&
5479 pindexFirstNotTransactionsValid ==
nullptr &&
5481 pindexFirstNotTransactionsValid = pindex;
5483 if (pindex->
pprev !=
nullptr && pindexFirstNotChainValid ==
nullptr &&
5485 pindexFirstNotChainValid = pindex;
5487 if (pindex->
pprev !=
nullptr && pindexFirstNotScriptsValid ==
nullptr &&
5489 pindexFirstNotScriptsValid = pindex;
5493 if (pindex->
pprev ==
nullptr) {
5512 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5516 assert(pindex->
nTx > 0);
5529 assert((pindexFirstNeverProcessed ==
nullptr) ==
5531 assert((pindexFirstNotTransactionsValid ==
nullptr) ==
5534 assert(pindex->
nHeight == nHeight);
5537 assert(pindex->
pprev ==
nullptr ||
5540 assert(nHeight < 2 ||
5543 assert(pindexFirstNotTreeValid ==
nullptr);
5546 assert(pindexFirstNotTreeValid ==
nullptr);
5550 assert(pindexFirstNotChainValid ==
nullptr);
5554 assert(pindexFirstNotScriptsValid ==
nullptr);
5556 if (pindexFirstInvalid ==
nullptr) {
5561 if (pindexFirstParked ==
nullptr) {
5568 pindexFirstNeverProcessed ==
nullptr) {
5569 if (pindexFirstInvalid ==
nullptr) {
5573 if (pindexFirstMissing ==
nullptr) {
5594 std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
5595 std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
5598 bool foundInUnlinked =
false;
5599 while (rangeUnlinked.first != rangeUnlinked.second) {
5600 assert(rangeUnlinked.first->first == pindex->
pprev);
5601 if (rangeUnlinked.first->second == pindex) {
5602 foundInUnlinked =
true;
5605 rangeUnlinked.first++;
5608 pindexFirstNeverProcessed !=
nullptr &&
5609 pindexFirstInvalid ==
nullptr) {
5613 assert(foundInUnlinked);
5617 assert(!foundInUnlinked);
5619 if (pindexFirstMissing ==
nullptr) {
5622 assert(!foundInUnlinked);
5625 pindexFirstNeverProcessed ==
nullptr &&
5626 pindexFirstMissing !=
nullptr) {
5642 if (pindexFirstInvalid ==
nullptr) {
5643 assert(foundInUnlinked);
5652 std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
5653 std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
5654 range = forward.equal_range(pindex);
5655 if (range.first != range.second) {
5657 pindex = range.first->second;
5667 if (pindex == pindexFirstInvalid) {
5668 pindexFirstInvalid =
nullptr;
5670 if (pindex == pindexFirstParked) {
5671 pindexFirstParked =
nullptr;
5673 if (pindex == pindexFirstMissing) {
5674 pindexFirstMissing =
nullptr;
5676 if (pindex == pindexFirstNeverProcessed) {
5677 pindexFirstNeverProcessed =
nullptr;
5679 if (pindex == pindexFirstNotTreeValid) {
5680 pindexFirstNotTreeValid =
nullptr;
5682 if (pindex == pindexFirstNotTransactionsValid) {
5683 pindexFirstNotTransactionsValid =
nullptr;
5685 if (pindex == pindexFirstNotChainValid) {
5686 pindexFirstNotChainValid =
nullptr;
5688 if (pindex == pindexFirstNotScriptsValid) {
5689 pindexFirstNotScriptsValid =
nullptr;
5694 std::pair<std::multimap<CBlockIndex *, CBlockIndex *>::iterator,
5695 std::multimap<CBlockIndex *, CBlockIndex *>::iterator>
5696 rangePar = forward.equal_range(pindexPar);
5697 while (rangePar.first->second != pindex) {
5700 assert(rangePar.first != rangePar.second);
5705 if (rangePar.first != rangePar.second) {
5707 pindex = rangePar.first->second;
5719 assert(nNodes == forward.size());
5724 return strprintf(
"Chainstate [%s] @ height %d (%s)",
5732 "CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)",
5733 nBlocks, nSize, nHeightFirst, nHeightLast,
5738 LOCK(cs_LastBlockFile);
5740 return &vinfoBlockFile.at(n);