56 #include <boost/algorithm/string/replace.hpp>
58 #define MICRO 0.000001
80 "level 0 reads the blocks from disk",
81 "level 1 verifies block validity",
82 "level 2 verifies undo data",
83 "level 3 checks disconnection of tip blocks",
84 "level 4 tries to reconnect the blocks",
85 "each level includes the checks of the previous levels",
99 if (pa < pb)
return false;
100 if (pa > pb)
return true;
158 std::vector<CBlockFileInfo> vinfoBlockFile;
159 int nLastBlockFile = 0;
164 bool fCheckForPruning =
false;
167 std::set<CBlockIndex*> setDirtyBlockIndex;
170 std::set<int> setDirtyFileInfo;
177 BlockMap::const_iterator
it = m_block_index.find(hash);
178 return it == m_block_index.end() ? nullptr :
it->second;
206 std::vector<CScriptCheck>* pvChecks =
nullptr)
216 assert(std::addressof(*::
ChainActive().Tip()) == std::addressof(*active_chain_tip));
232 const int nBlockHeight = active_chain_tip->nHeight + 1;
240 ? active_chain_tip->GetMedianTimePast()
243 return IsFinalTx(tx, nBlockHeight, nBlockTime);
270 bool useExistingLockPoints)
289 std::pair<int, int64_t> lockPair;
290 if (useExistingLockPoints) {
293 lockPair.second =
lp->
time;
298 std::vector<int> prevheights;
299 prevheights.resize(tx.
vin.size());
300 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
301 const CTxIn& txin = tx.
vin[txinIndex];
304 return error(
"%s: Missing input", __func__);
308 prevheights[txinIndex] = tip->
nHeight + 1;
310 prevheights[txinIndex] = coin.
nHeight;
316 lp->
time = lockPair.second;
330 int maxInputHeight = 0;
331 for (
const int height : prevheights) {
333 if (height != tip->
nHeight+1) {
334 maxInputHeight = std::max(maxInputHeight, height);
349 int expired = pool.Expire(GetTime<std::chrono::seconds>() - age);
358 coins_cache.Uncache(removed);
365 if (active_chainstate.IsInitialBlockDownload())
402 if (!fAddToMempool || (*it)->IsCoinBase() ||
407 }
else if (mempool.exists((*it)->GetHash())) {
412 disconnectpool.queuedTx.clear();
446 if (coin.
IsSpent())
return false;
459 const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.
prevout);
474 explicit MemPoolAccept(
CTxMemPool& mempool,
CChainState& active_chainstate) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&active_chainstate.CoinsTip(), m_pool), m_active_chainstate(active_chainstate),
486 const int64_t m_accept_time;
487 const bool m_bypass_limits;
495 std::vector<COutPoint>& m_coins_to_uncache;
496 const bool m_test_accept;
506 explicit Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
507 std::set<uint256> m_conflicts;
510 std::unique_ptr<CTxMemPoolEntry> m_entry;
511 std::list<CTransactionRef> m_replaced_transactions;
513 bool m_replacement_transaction;
517 size_t m_conflicting_size;
549 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
568 const size_t m_limit_ancestors;
569 const size_t m_limit_ancestor_size;
572 size_t m_limit_descendants;
573 size_t m_limit_descendant_size;
576 bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
580 const uint256& hash = ws.m_hash;
583 const int64_t nAcceptTime = args.m_accept_time;
584 const bool bypass_limits = args.m_bypass_limits;
585 std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
589 std::set<uint256>& setConflicts = ws.m_conflicts;
592 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
593 bool& fReplacementTransaction = ws.m_replacement_transaction;
594 CAmount& nModifiedFees = ws.m_modified_fees;
595 CAmount& nConflictingFees = ws.m_conflicting_fees;
596 size_t& nConflictingSize = ws.m_conflicting_size;
621 assert(std::addressof(::
ChainActive()) == std::addressof(m_active_chainstate.m_chain));
626 if (m_pool.exists(hash)) {
634 if (ptxConflicting) {
635 if (!setConflicts.count(ptxConflicting->
GetHash()))
649 bool fReplacementOptOut =
true;
650 for (
const CTxIn &_txin : ptxConflicting->
vin)
654 fReplacementOptOut =
false;
658 if (fReplacementOptOut) {
662 setConflicts.insert(ptxConflicting->
GetHash());
668 m_view.SetBackend(m_viewmempool);
670 assert(std::addressof(::
ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
675 coins_to_uncache.push_back(txin.
prevout);
681 if (!m_view.HaveCoin(txin.
prevout)) {
683 for (
size_t out = 0; out < tx.
vout.size(); out++) {
696 m_view.GetBestBlock();
701 m_view.SetBackend(m_dummy);
712 assert(std::addressof(
g_chainman.m_blockman) == std::addressof(m_active_chainstate.m_blockman));
713 if (!
Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), ws.m_base_fees)) {
718 const auto& params = args.m_chainparams.GetConsensus();
719 assert(std::addressof(::
ChainActive()) == std::addressof(m_active_chainstate.m_chain));
732 nModifiedFees = ws.m_base_fees;
733 m_pool.ApplyDelta(hash, nModifiedFees);
737 bool fSpendsCoinbase =
false;
739 const Coin &coin = m_view.AccessCoin(txin.
prevout);
741 fSpendsCoinbase =
true;
746 assert(std::addressof(::
ChainActive()) == std::addressof(m_active_chainstate.m_chain));
747 entry.reset(
new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
748 fSpendsCoinbase, nSigOpsCost,
lp));
749 unsigned int nSize = entry->GetTxSize();
757 if (!bypass_limits && !
CheckFeeRate(nSize, nModifiedFees, state))
return false;
761 if (setConflicts.size() == 1) {
789 assert(setIterConflicting.size() == 1);
792 m_limit_descendants += 1;
793 m_limit_descendant_size += conflict->GetSizeWithDescendants();
796 std::string errString;
797 if (!m_pool.CalculateMemPoolAncestors(*entry, setAncestors, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants, m_limit_descendant_size, errString)) {
798 setAncestors.clear();
800 std::string dummy_err_string;
813 !m_pool.CalculateMemPoolAncestors(*entry, setAncestors, 2, m_limit_ancestor_size, m_limit_descendants + 1, m_limit_descendant_size +
EXTRA_DESCENDANT_TX_SIZE_LIMIT, dummy_err_string)) {
824 const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
825 if (setConflicts.count(hashAncestor))
828 strprintf(
"%s spends conflicting transaction %s",
836 nConflictingFees = 0;
837 nConflictingSize = 0;
838 uint64_t nConflictingCount = 0;
843 fReplacementTransaction = setConflicts.size();
844 if (fReplacementTransaction)
846 CFeeRate newFeeRate(nModifiedFees, nSize);
847 std::set<uint256> setConflictsParents;
848 const int maxDescendantsToVisit = 100;
849 for (
const auto& mi : setIterConflicting) {
864 CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
865 if (newFeeRate <= oldFeeRate)
868 strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
870 newFeeRate.ToString(),
871 oldFeeRate.ToString()));
874 for (
const CTxIn &txin : mi->GetTx().vin)
879 nConflictingCount += mi->GetCountWithDescendants();
884 if (nConflictingCount <= maxDescendantsToVisit) {
888 m_pool.CalculateDescendants(
it, allConflicting);
891 nConflictingFees +=
it->GetModifiedFee();
892 nConflictingSize +=
it->GetTxSize();
896 strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
899 maxDescendantsToVisit));
902 for (
unsigned int j = 0; j < tx.
vin.size(); j++)
913 if (!setConflictsParents.count(tx.
vin[j].prevout.hash))
918 if (m_pool.exists(tx.
vin[j].prevout.hash)) {
920 strprintf(
"replacement %s adds unconfirmed input, idx %d",
929 if (nModifiedFees < nConflictingFees)
932 strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
938 CAmount nDeltaFees = nModifiedFees - nConflictingFees;
942 strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
960 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, txdata)) {
980 const uint256& hash = ws.m_hash;
999 assert(std::addressof(::
ChainActive()) == std::addressof(m_active_chainstate.m_chain));
1001 assert(std::addressof(::
ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
1003 return error(
"%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
1010 bool MemPoolAccept::Finalize(
const ATMPArgs& args, Workspace& ws)
1013 const uint256& hash = ws.m_hash;
1015 const bool bypass_limits = args.m_bypass_limits;
1019 const CAmount& nModifiedFees = ws.m_modified_fees;
1020 const CAmount& nConflictingFees = ws.m_conflicting_fees;
1021 const size_t& nConflictingSize = ws.m_conflicting_size;
1022 const bool fReplacementTransaction = ws.m_replacement_transaction;
1023 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
1029 it->GetTx().GetHash().ToString(),
1032 (
int)entry->GetTxSize() - (
int)nConflictingSize);
1033 ws.m_replaced_transactions.push_back(
it->GetSharedTx());
1043 bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits &&
IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
1046 m_pool.addUnchecked(*entry, setAncestors, validForFeeEstimation);
1049 if (!bypass_limits) {
1050 assert(std::addressof(::
ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
1052 if (!m_pool.exists(hash))
1078 if (args.m_test_accept) {
1095 bool bypass_limits,
bool test_accept)
1098 std::vector<COutPoint> coins_to_uncache;
1099 MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache, test_accept };
1102 const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
1109 for (
const COutPoint& hashTx : coins_to_uncache)
1119 bool bypass_limits,
bool test_accept)
1132 for (
const auto& tx : block.
vtx) {
1143 if (ptx)
return ptx;
1147 if (
g_txindex->FindTx(hash, hashBlock, tx))
return tx;
1161 nSubsidy >>= halvings;
1166 std::string ldb_name,
1167 size_t cache_size_bytes,
1169 bool should_wipe) : m_dbview(
1170 GetDataDir() / ldb_name, cache_size_bytes, in_memory, should_wipe),
1171 m_catcherview(&m_dbview) {}
1173 void CoinsViews::InitCache()
1175 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
1179 : m_mempool(mempool),
1180 m_blockman(blockman),
1181 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1184 size_t cache_size_bytes,
1187 std::string leveldb_name)
1194 leveldb_name, cache_size_bytes, in_memory, should_wipe);
1197 void CChainState::InitCoinsCache(
size_t cache_size_bytes)
1226 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1235 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1236 if (strCmd.empty())
return;
1241 std::string singleQuote(
"'");
1243 safeStatus = singleQuote+safeStatus+singleQuote;
1244 boost::replace_all(strCmd,
"%s", safeStatus);
1246 std::thread t(runCommand, strCmd);
1263 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1274 if (!pindexBestInvalid || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
1275 pindexBestInvalid = pindexNew;
1280 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
1285 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
1297 setDirtyBlockIndex.insert(pindex);
1335 return pindexPrev->
nHeight + 1;
1354 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1355 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1380 std::vector<CScriptCheck>* pvChecks)
1385 pvChecks->reserve(tx.
vin.size());
1402 std::vector<CTxOut> spent_outputs;
1403 spent_outputs.reserve(tx.
vin.size());
1405 for (
const auto& txin : tx.
vin) {
1409 spent_outputs.emplace_back(coin.
out);
1411 txdata.
Init(tx, std::move(spent_outputs));
1415 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1427 check.
swap(pvChecks->back());
1428 }
else if (!check()) {
1456 if (cacheFullScriptStore && !pvChecks) {
1470 return error(
"%s: OpenUndoFile failed", __func__);
1474 fileout << messageStart << nSize;
1477 long fileOutPos = ftell(fileout.
Get());
1479 return error(
"%s: ftell failed", __func__);
1480 pos.
nPos = (
unsigned int)fileOutPos;
1481 fileout << blockundo;
1485 hasher << hashBlock;
1486 hasher << blockundo;
1496 return error(
"%s: no undo data available", __func__);
1502 return error(
"%s: OpenUndoFile failed", __func__);
1509 verifier >> blockundo;
1510 filein >> hashChecksum;
1512 catch (
const std::exception& e) {
1513 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1517 if (hashChecksum != verifier.
GetHash())
1518 return error(
"%s: Checksum mismatch", __func__);
1526 return state.
Error(strMessage);
1540 if (view.
HaveCoin(out)) fClean =
false;
1542 if (undo.nHeight == 0) {
1548 undo.nHeight = alternate.
nHeight;
1559 view.
AddCoin(out, std::move(undo), !fClean);
1572 error(
"DisconnectBlock(): failure reading undo data");
1576 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1577 error(
"DisconnectBlock(): block and undo data inconsistent");
1582 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1589 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1590 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1593 bool is_spent = view.
SpendCoin(out, &coin);
1604 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1607 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1625 FlatFilePos undo_pos_old(block_file, vinfoBlockFile[block_file].nUndoSize);
1626 if (!
UndoFileSeq().Flush(undo_pos_old, finalize)) {
1627 AbortNode(
"Flushing undo file to disk failed. This is likely the result of an I/O error.");
1633 LOCK(cs_LastBlockFile);
1634 FlatFilePos block_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nSize);
1636 AbortNode(
"Flushing block file to disk failed. This is likely the result of an I/O error.");
1640 if (!fFinalize || finalize_undo)
FlushUndoFile(nLastBlockFile, finalize_undo);
1651 return error(
"ConnectBlock(): FindUndoPos failed");
1653 return AbortNode(state,
"Failed to write undo data");
1659 if (_pos.
nFile < nLastBlockFile &&
static_cast<uint32_t
>(pindex->
nHeight) == vinfoBlockFile[_pos.
nFile].nHeightLast) {
1666 setDirtyBlockIndex.insert(pindex);
1734 return params.
SegwitHeight != std::numeric_limits<int>::max();
1747 if (consensusparams.BIP16Exception.IsNull() ||
1748 pindex->phashBlock ==
nullptr ||
1749 *pindex->phashBlock != consensusparams.BIP16Exception)
1761 if (pindex->nHeight >= consensusparams.BIP66Height) {
1766 if (pindex->nHeight >= consensusparams.BIP65Height) {
1771 if (pindex->nHeight >= consensusparams.CSVHeight) {
1828 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
1830 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
1847 bool fScriptChecks =
true;
1856 if (
it->second->GetAncestor(pindex->
nHeight) == pindex &&
1893 bool fEnforceBIP30 = !((pindex->
nHeight==91842 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
1894 (pindex->
nHeight==91880 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
1922 static constexpr
int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
1960 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
1961 for (
const auto& tx : block.
vtx) {
1962 for (
size_t o = 0; o < tx->
vout.size(); o++) {
1964 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
1972 int nLockTimeFlags = 0;
1991 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
1993 std::vector<int> prevheights;
1996 int64_t nSigOpsCost = 0;
1997 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
1998 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2002 nInputs += tx.
vin.size();
2016 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n", __func__);
2023 prevheights.resize(tx.
vin.size());
2024 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2028 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
2029 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
2040 LogPrintf(
"ERROR: ConnectBlock(): too many sigops\n");
2046 std::vector<CScriptCheck> vChecks;
2047 bool fCacheResults = fJustCheck;
2053 return error(
"ConnectBlock(): CheckInputScripts on %s failed with %s",
2056 control.
Add(vChecks);
2069 if (block.
vtx[0]->GetValueOut() > blockReward) {
2070 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.
vtx[0]->GetValueOut(), blockReward);
2074 if (!control.
Wait()) {
2075 LogPrintf(
"ERROR: %s: CheckQueue failed\n", __func__);
2089 setDirtyBlockIndex.insert(pindex);
2107 return this->GetCoinsCacheSizeState(
2115 size_t max_coins_cache_size_bytes,
2116 size_t max_mempool_size_bytes)
2120 int64_t nTotalSpace =
2121 max_coins_cache_size_bytes + std::max<int64_t>(max_mempool_size_bytes - nMempoolUsage, 0);
2124 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
2125 int64_t large_threshold =
2126 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2128 if (cacheSize > nTotalSpace) {
2129 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
2131 }
else if (cacheSize > large_threshold) {
2141 int nManualPruneHeight)
2144 assert(this->CanFlushToDisk());
2145 static std::chrono::microseconds nLastWrite{0};
2146 static std::chrono::microseconds nLastFlush{0};
2147 std::set<int> setFilesToPrune;
2148 bool full_flush_completed =
false;
2155 bool fFlushForPrune =
false;
2156 bool fDoFullFlush =
false;
2159 LOCK(cs_LastBlockFile);
2168 if (nManualPruneHeight > 0) {
2176 fCheckForPruning =
false;
2178 if (!setFilesToPrune.empty()) {
2179 fFlushForPrune =
true;
2181 pblocktree->WriteFlag(
"prunedblockfiles",
true);
2186 const auto nNow = GetTime<std::chrono::microseconds>();
2188 if (nLastWrite.count() == 0) {
2191 if (nLastFlush.count() == 0) {
2203 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2205 if (fDoFullFlush || fPeriodicWrite) {
2208 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2221 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2222 vFiles.reserve(setDirtyFileInfo.size());
2223 for (std::set<int>::iterator
it = setDirtyFileInfo.begin();
it != setDirtyFileInfo.end(); ) {
2224 vFiles.push_back(std::make_pair(*
it, &vinfoBlockFile[*
it]));
2225 setDirtyFileInfo.erase(
it++);
2227 std::vector<const CBlockIndex*> vBlocks;
2228 vBlocks.reserve(setDirtyBlockIndex.size());
2229 for (std::set<CBlockIndex*>::iterator
it = setDirtyBlockIndex.begin();
it != setDirtyBlockIndex.end(); ) {
2230 vBlocks.push_back(*
it);
2231 setDirtyBlockIndex.erase(
it++);
2233 if (!
pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
2234 return AbortNode(state,
"Failed to write to block index database");
2238 if (fFlushForPrune) {
2246 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2248 coins_count, coins_mem_usage / 1000));
2256 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2260 return AbortNode(state,
"Failed to write to coin database");
2262 full_flush_completed =
true;
2265 if (full_flush_completed) {
2269 }
catch (
const std::runtime_error& e) {
2270 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2285 fCheckForPruning =
true;
2295 static bool fWarned =
false;
2341 LogPrintf(
"%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__,
2342 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
2343 log(pindexNew->nChainWork.getdouble())/log(2.0), (
unsigned long)pindexNew->nChainTx,
2367 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2370 return error(
"DisconnectTip(): Failed to read block");
2378 bool flushed = view.
Flush();
2386 if (disconnectpool) {
2388 for (
auto it = block.
vtx.rbegin();
it != block.
vtx.rend(); ++
it) {
2468 std::shared_ptr<const CBlock> pthisBlock;
2470 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2472 return AbortNode(state,
"Failed to read block");
2473 pthisBlock = pblockNew;
2475 pthisBlock = pblock;
2477 const CBlock& blockConnecting = *pthisBlock;
2484 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
2494 bool flushed = view.
Flush();
2538 bool fInvalidAncestor =
false;
2548 if (fFailedChain || fMissingData) {
2550 if (fFailedChain && (pindexBestInvalid ==
nullptr || pindexNew->
nChainWork > pindexBestInvalid->nChainWork))
2551 pindexBestInvalid = pindexNew;
2554 while (pindexTest != pindexFailed) {
2557 }
else if (fMissingData) {
2562 std::make_pair(pindexFailed->
pprev, pindexFailed));
2565 pindexFailed = pindexFailed->
pprev;
2568 fInvalidAncestor =
true;
2571 pindexTest = pindexTest->
pprev;
2573 if (!fInvalidAncestor)
2606 bool fBlocksDisconnected =
false;
2617 AbortNode(state,
"Failed to disconnect block; see debug.log for details");
2620 fBlocksDisconnected =
true;
2624 std::vector<CBlockIndex*> vpindexToConnect;
2625 bool fContinue =
true;
2630 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
2631 vpindexToConnect.clear();
2632 vpindexToConnect.reserve(nTargetHeight -
nHeight);
2635 vpindexToConnect.push_back(pindexIter);
2636 pindexIter = pindexIter->
pprev;
2642 if (!
ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2649 fInvalidFound =
true;
2670 if (fBlocksDisconnected) {
2690 bool fNotify =
false;
2691 bool fInitialBlockDownload =
false;
2698 if (pindexHeader != pindexHeaderOld) {
2701 fInitialBlockDownload = chainstate.IsInitialBlockDownload();
2702 pindexHeaderOld = pindexHeader;
2749 bool blocks_connected =
false;
2755 if (pindexMostWork ==
nullptr) {
2760 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
2764 bool fInvalidFound =
false;
2765 std::shared_ptr<const CBlock> nullBlockPtr;
2766 if (!
ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
2770 blocks_connected =
true;
2772 if (fInvalidFound) {
2774 pindexMostWork =
nullptr;
2779 assert(trace.pblock && trace.pindex);
2783 if (!blocks_connected)
return true;
2790 if (pindexFork != pindexNewTip) {
2807 }
while (pindexNewTip != pindexMostWork);
2851 if (pindex->
nHeight == 0)
return false;
2854 bool pindex_was_in_chain =
false;
2855 int disconnected = 0;
2869 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
2873 for (
const auto& entry :
m_blockman.m_block_index) {
2884 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
2899 pindex_was_in_chain =
true;
2905 bool ret =
DisconnectTip(state, chainparams, &disconnectpool);
2913 if (!ret)
return false;
2922 setDirtyBlockIndex.insert(invalid_walk_tip);
2929 setDirtyBlockIndex.insert(to_mark_failed);
2933 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
2934 while (candidate_it != candidate_blocks_by_work.end()) {
2937 candidate_it = candidate_blocks_by_work.erase(candidate_it);
2945 to_mark_failed = invalid_walk_tip;
2959 setDirtyBlockIndex.insert(to_mark_failed);
2970 BlockMap::iterator
it =
m_blockman.m_block_index.begin();
2982 if (pindex_was_in_chain) {
2994 BlockMap::iterator
it =
m_blockman.m_block_index.begin();
2996 if (!
it->second->IsValid() &&
it->second->GetAncestor(
nHeight) == pindex) {
2998 setDirtyBlockIndex.insert(
it->second);
3002 if (
it->second == pindexBestInvalid) {
3004 pindexBestInvalid =
nullptr;
3012 while (pindex !=
nullptr) {
3015 setDirtyBlockIndex.insert(pindex);
3018 pindex = pindex->
pprev;
3028 BlockMap::iterator
it = m_block_index.find(hash);
3029 if (
it != m_block_index.end())
3038 BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
3040 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
3041 if (miPrev != m_block_index.end())
3043 pindexNew->
pprev = (*miPrev).second;
3053 setDirtyBlockIndex.insert(pindexNew);
3061 pindexNew->
nTx = block.
vtx.size();
3071 setDirtyBlockIndex.insert(pindexNew);
3075 std::deque<CBlockIndex*> queue;
3076 queue.push_back(pindexNew);
3079 while (!queue.empty()) {
3090 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
3091 while (range.first != range.second) {
3092 std::multimap<CBlockIndex*, CBlockIndex*>::iterator
it = range.first;
3093 queue.push_back(
it->second);
3100 m_blockman.m_blocks_unlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
3108 LOCK(cs_LastBlockFile);
3110 unsigned int nFile = fKnown ? pos.
nFile : nLastBlockFile;
3111 if (vinfoBlockFile.size() <= nFile) {
3112 vinfoBlockFile.resize(nFile + 1);
3115 bool finalize_undo =
false;
3122 finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (
unsigned int)active_chain.
Tip()->
nHeight);
3124 if (vinfoBlockFile.size() <= nFile) {
3125 vinfoBlockFile.resize(nFile + 1);
3129 pos.
nPos = vinfoBlockFile[nFile].nSize;
3132 if ((
int)nFile != nLastBlockFile) {
3137 nLastBlockFile = nFile;
3140 vinfoBlockFile[nFile].AddBlock(
nHeight, nTime);
3142 vinfoBlockFile[nFile].nSize = std::max(pos.
nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3144 vinfoBlockFile[nFile].nSize += nAddSize;
3150 return AbortNode(
"Disk space is too low!",
_(
"Disk space is too low!"));
3153 fCheckForPruning =
true;
3157 setDirtyFileInfo.insert(nFile);
3165 LOCK(cs_LastBlockFile);
3167 pos.
nPos = vinfoBlockFile[nFile].nUndoSize;
3168 vinfoBlockFile[nFile].nUndoSize += nAddSize;
3169 setDirtyFileInfo.insert(nFile);
3174 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
3177 fCheckForPruning =
true;
3210 if (fCheckMerkleRoot) {
3234 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3236 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3237 if (block.
vtx[i]->IsCoinBase())
3242 for (
const auto& tx : block.
vtx) {
3252 unsigned int nSigOps = 0;
3253 for (
const auto& tx : block.
vtx)
3260 if (fCheckPOW && fCheckMerkleRoot)
3268 int height = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3275 static const std::vector<unsigned char> nonce(32, 0x00);
3278 tx.
vin[0].scriptWitness.stack.resize(1);
3279 tx.
vin[0].scriptWitness.stack[0] = nonce;
3286 std::vector<unsigned char> commitment;
3288 std::vector<unsigned char> ret(32, 0x00);
3289 if (consensusParams.
SegwitHeight != std::numeric_limits<int>::max()) {
3305 tx.
vout.push_back(out);
3317 for (
const MapCheckpoints::value_type& i :
reverse_iterate(checkpoints))
3319 const uint256& hash = i.second;
3340 assert(pindexPrev !=
nullptr);
3341 const int nHeight = pindexPrev->nHeight + 1;
3354 CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
3355 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
3356 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
3362 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
3375 strprintf(
"rejected nVersion=0x%08x block", block.nVersion));
3388 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3391 int nLockTimeFlags = 0;
3393 assert(pindexPrev !=
nullptr);
3402 for (
const auto& tx : block.
vtx) {
3412 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3413 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3426 bool fHaveWitness =
false;
3430 bool malleated =
false;
3435 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3439 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3442 fHaveWitness =
true;
3447 if (!fHaveWitness) {
3448 for (
const auto& tx : block.
vtx) {
3473 BlockMap::iterator miSelf = m_block_index.find(hash);
3475 if (miSelf != m_block_index.end()) {
3481 LogPrintf(
"ERROR: %s: block %s is marked invalid\n", __func__, hash.
ToString());
3494 BlockMap::iterator mi = m_block_index.find(block.
hashPrevBlock);
3495 if (mi == m_block_index.end()) {
3496 LogPrintf(
"ERROR: %s: prev block not found\n", __func__);
3499 pindexPrev = (*mi).second;
3501 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
3505 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.
ToString(), state.
ToString());
3532 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
3535 while (invalid_walk != failedit) {
3537 setDirtyBlockIndex.insert(invalid_walk);
3538 invalid_walk = invalid_walk->
pprev;
3540 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
3563 bool accepted = m_blockman.AcceptBlockHeader(
3564 header, state, chainparams, &pindex);
3577 LogPrintf(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n", (*ppindex)->nHeight, 100.0/((*ppindex)->nHeight+(
GetAdjustedTime() - (*ppindex)->GetBlockTime()) /
Params().GetConsensus().nPowTargetSpacing) * (*ppindex)->nHeight);
3586 const CBlock& block = *pblock;
3588 if (fNewBlock) *fNewBlock =
false;
3592 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3597 if (!accepted_header)
3619 if (fAlreadyHave)
return true;
3621 if (pindex->
nTx != 0)
return true;
3622 if (!fHasMoreOrSameWork)
return true;
3623 if (fTooFarAhead)
return true;
3636 setDirtyBlockIndex.insert(pindex);
3647 if (fNewBlock) *fNewBlock =
true;
3652 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3656 }
catch (
const std::runtime_error& e) {
3657 return AbortNode(state, std::string(
"System error: ") + e.what());
3674 if (fNewBlock) *fNewBlock =
false;
3690 return error(
"%s: AcceptBlock FAILED (%s)", __func__, state.
ToString());
3698 return error(
"%s: ActivateBestChain failed (%s)", __func__, state.
ToString());
3709 bool fCheckMerkleRoot)
3717 indexDummy.
pprev = pindexPrev;
3724 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.
ToString());
3726 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
3728 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__, state.
ToString());
3729 if (!chainstate.
ConnectBlock(block, state, &indexDummy, viewNew, chainparams,
true))
3743 LOCK(cs_LastBlockFile);
3745 uint64_t retval = 0;
3747 retval += file.nSize + file.nUndoSize;
3755 LOCK(cs_LastBlockFile);
3757 for (
const auto& entry : m_block_index) {
3759 if (pindex->
nFile == fileNumber) {
3765 setDirtyBlockIndex.insert(pindex);
3772 while (range.first != range.second) {
3773 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
3775 if (_it->second == pindex) {
3782 vinfoBlockFile[fileNumber].SetNull();
3783 setDirtyFileInfo.insert(fileNumber);
3789 for (std::set<int>::iterator
it = setFilesToPrune.begin();
it != setFilesToPrune.end(); ++
it) {
3793 LogPrintf(
"Prune: %s deleted blk/rev (%05u)\n", __func__, *
it);
3802 if (chain_tip_height < 0) {
3807 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight, chain_tip_height -
MIN_BLOCKS_TO_KEEP);
3809 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
3810 if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
3814 setFilesToPrune.insert(fileNumber);
3817 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune,
count);
3838 if ((uint64_t)chain_tip_height <= nPruneAfterHeight) {
3842 unsigned int nLastBlockWeCanPrune = std::min(prune_height, chain_tip_height -
static_cast<int>(
MIN_BLOCKS_TO_KEEP));
3848 uint64_t nBytesToPrune;
3861 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
3862 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
3864 if (vinfoBlockFile[fileNumber].nSize == 0) {
3873 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
3879 setFilesToPrune.insert(fileNumber);
3880 nCurrentUsage -= nBytesToPrune;
3885 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
3887 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
3888 nLastBlockWeCanPrune,
count);
3923 BlockMap::iterator mi = m_block_index.find(hash);
3924 if (mi != m_block_index.end())
3925 return (*mi).second;
3929 mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
3938 std::set<CBlockIndex*, CBlockIndexWorkComparator>& block_index_candidates)
3944 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
3945 vSortedByHeight.reserve(m_block_index.size());
3946 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index)
3949 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
3951 sort(vSortedByHeight.begin(), vSortedByHeight.end());
3952 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
3960 if (pindex->
nTx > 0) {
3961 if (pindex->
pprev) {
3974 setDirtyBlockIndex.insert(pindex);
3977 block_index_candidates.insert(pindex);
3980 pindexBestInvalid = pindex;
3994 for (
const BlockMap::value_type& entry : m_block_index) {
3995 delete entry.second;
3998 m_block_index.clear();
4011 pblocktree->ReadLastBlockFile(nLastBlockFile);
4012 vinfoBlockFile.resize(nLastBlockFile + 1);
4013 LogPrintf(
"%s: last block file = %i\n", __func__, nLastBlockFile);
4014 for (
int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4015 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4017 LogPrintf(
"%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].
ToString());
4018 for (
int nFile = nLastBlockFile + 1;
true; nFile++) {
4020 if (
pblocktree->ReadBlockFileInfo(nFile, info)) {
4021 vinfoBlockFile.push_back(info);
4028 LogPrintf(
"Checking all blk files are present...\n");
4029 std::set<int> setBlkDataFiles;
4030 for (
const std::pair<const uint256, CBlockIndex*>& item :
m_blockman.m_block_index) {
4033 setBlkDataFiles.insert(pindex->
nFile);
4036 for (std::set<int>::iterator
it = setBlkDataFiles.begin();
it != setBlkDataFiles.end();
it++)
4047 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
4050 bool fReindexing =
false;
4086 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4096 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, 0,
false);
4113 if (nCheckDepth <= 0 || nCheckDepth > active_chainstate.
m_chain.
Height())
4115 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4116 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4120 int nGoodTransactions = 0;
4124 for (pindex = active_chainstate.
m_chain.
Tip(); pindex && pindex->
pprev; pindex = pindex->
pprev) {
4125 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(active_chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
4126 if (reportDone < percentageDone/10) {
4129 reportDone = percentageDone/10;
4131 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, percentageDone,
false);
4136 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
4145 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
4148 if (nCheckLevel >= 2 && pindex) {
4164 nGoodTransactions = 0;
4165 pindexFailure = pindex;
4167 nGoodTransactions += block.
vtx.size();
4173 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", active_chainstate.
m_chain.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
4179 if (nCheckLevel >= 4) {
4180 while (pindex != active_chainstate.
m_chain.
Tip()) {
4181 const int percentageDone = std::max(1, std::min(99, 100 - (
int)(((
double)(active_chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * 50)));
4182 if (reportDone < percentageDone/10) {
4185 reportDone = percentageDone/10;
4187 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, percentageDone,
false);
4192 if (!active_chainstate.
ConnectBlock(block, state, pindex, coins, chainparams))
4199 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
4214 if (!tx->IsCoinBase()) {
4215 for (
const CTxIn &txin : tx->vin) {
4233 if (hashHeads.empty())
return true;
4234 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4236 uiInterface.ShowProgress(
_(
"Replaying blocks...").translated, 0,
false);
4243 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
4244 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4246 pindexNew =
m_blockman.m_block_index[hashHeads[0]];
4248 if (!hashHeads[1].IsNull()) {
4249 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
4250 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4252 pindexOld =
m_blockman.m_block_index[hashHeads[1]];
4254 assert(pindexFork !=
nullptr);
4258 while (pindexOld != pindexFork) {
4274 pindexOld = pindexOld->
pprev;
4278 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4282 uiInterface.ShowProgress(
_(
"Replaying blocks...").translated, (
int) ((
nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
4311 setDirtyBlockIndex.insert(index);
4315 while (ret.first != ret.second) {
4316 if (ret.first->second == index) {
4337 for (
const auto& entry :
m_blockman.m_block_index) {
4383 return error(
"RewindBlockIndex: unable to disconnect block at height %i (%s)", tip->
nHeight, state.
ToString());
4403 LogPrintf(
"RewindBlockIndex: unable to flush state to disk (%s)\n", state.
ToString());
4422 LogPrintf(
"RewindBlockIndex: unable to flush state to disk (%s)\n", state.
ToString());
4443 pindexBestInvalid =
nullptr;
4445 if (mempool) mempool->
clear();
4446 vinfoBlockFile.clear();
4448 setDirtyBlockIndex.clear();
4449 setDirtyFileInfo.clear();
4452 warningcache[b].clear();
4464 if (!ret)
return false;
4465 needs_init = m_blockman.m_block_index.empty();
4475 LogPrintf(
"Initializing databases...\n");
4496 return error(
"%s: writing genesis block to disk failed", __func__);
4499 }
catch (
const std::runtime_error& e) {
4500 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4509 static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
4516 uint64_t nRewind = blkdat.GetPos();
4517 while (!blkdat.eof()) {
4520 blkdat.SetPos(nRewind);
4523 unsigned int nSize = 0;
4528 nRewind = blkdat.GetPos()+1;
4536 }
catch (
const std::exception&) {
4542 uint64_t nBlockPos = blkdat.GetPos();
4544 dbp->
nPos = nBlockPos;
4545 blkdat.SetLimit(nBlockPos + nSize);
4546 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4549 nRewind = blkdat.GetPos();
4551 uint256 hash = block.GetHash();
4558 block.hashPrevBlock.ToString());
4560 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
4570 if (
AcceptBlock(pblock, state, chainparams,
nullptr,
true, dbp,
nullptr)) {
4594 std::deque<uint256> queue;
4595 queue.push_back(hash);
4596 while (!queue.empty()) {
4599 std::pair<std::multimap<uint256, FlatFilePos>::iterator, std::multimap<uint256, FlatFilePos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
4600 while (range.first != range.second) {
4601 std::multimap<uint256, FlatFilePos>::iterator
it = range.first;
4602 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4605 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4610 if (
AcceptBlock(pblockrecursive, dummy, chainparams,
nullptr,
true, &
it->second,
nullptr))
4613 queue.push_back(pblockrecursive->GetHash());
4617 mapBlocksUnknownParent.erase(
it);
4622 }
catch (
const std::exception& e) {
4623 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
4626 }
catch (
const std::runtime_error& e) {
4627 AbortNode(std::string(
"System error: ") + e.what());
4649 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4650 for (
const std::pair<const uint256, CBlockIndex*>& entry :
m_blockman.m_block_index) {
4651 forward.insert(std::make_pair(entry.second->pprev, entry.second));
4656 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4658 rangeGenesis.first++;
4659 assert(rangeGenesis.first == rangeGenesis.second);
4670 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4672 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4673 while (pindex !=
nullptr) {
4677 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4684 if (pindex->
pprev ==
nullptr) {
4695 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4708 assert(pindexFirstNotTreeValid ==
nullptr);
4712 if (pindexFirstInvalid ==
nullptr) {
4717 if (pindexFirstInvalid ==
nullptr) {
4722 if (pindexFirstMissing ==
nullptr || pindex ==
m_chain.
Tip()) {
4733 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
m_blockman.
m_blocks_unlinked.equal_range(pindex->
pprev);
4734 bool foundInUnlinked =
false;
4735 while (rangeUnlinked.first != rangeUnlinked.second) {
4736 assert(rangeUnlinked.first->first == pindex->
pprev);
4737 if (rangeUnlinked.first->second == pindex) {
4738 foundInUnlinked =
true;
4741 rangeUnlinked.first++;
4743 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4748 if (pindexFirstMissing ==
nullptr)
assert(!foundInUnlinked);
4749 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4761 if (pindexFirstInvalid ==
nullptr) {
4770 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4771 if (range.first != range.second) {
4773 pindex = range.first->second;
4782 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4783 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4784 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4785 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4786 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4787 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4788 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4792 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4793 while (rangePar.first->second != pindex) {
4794 assert(rangePar.first != rangePar.second);
4799 if (rangePar.first != rangePar.second) {
4801 pindex = rangePar.first->second;
4813 assert(nNodes == forward.size());
4819 return strprintf(
"Chainstate [%s] @ height %d (%s)",
4824 bool CChainState::ResizeCoinsCaches(
size_t coinstip_size,
size_t coinsdb_size)
4836 LogPrintf(
"[%s] resized coinsdb cache to %.1f MiB\n",
4837 this->
ToString(), coinsdb_size * (1.0 / 1024 / 1024));
4838 LogPrintf(
"[%s] resized coinstip cache to %.1f MiB\n",
4839 this->
ToString(), coinstip_size * (1.0 / 1024 / 1024));
4846 if (coinstip_size > old_coinstip_size) {
4864 LOCK(cs_LastBlockFile);
4866 return &vinfoBlockFile.at(n);
4875 FILE* filestr{mockable_fopen_function(
GetDataDir() /
"mempool.dat",
"rb")};
4878 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
4883 int64_t expired = 0;
4885 int64_t already_there = 0;
4886 int64_t unbroadcast = 0;
4905 CAmount amountdelta = nFeeDelta;
4909 if (nTime > nNow - nExpiryTimeout) {
4920 if (pool.
exists(tx->GetHash())) {