62#include <boost/algorithm/string/replace.hpp>
82 "level 0 reads the blocks from disk",
83 "level 1 verifies block validity",
84 "level 2 verifies undo data",
85 "level 3 checks disconnection of tip blocks",
86 "level 4 tries to reconnect the blocks",
87 "each level includes the checks of the previous levels",
101 if (pa < pb)
return false;
102 if (pa > pb)
return true;
147void FlushBlockFile(
bool fFinalize =
false,
bool finalize_undo =
false);
153 BlockMap::const_iterator it = m_block_index.find(hash);
154 return it == m_block_index.end() ? nullptr : it->second;
179 std::vector<CScriptCheck>* pvChecks =
nullptr)
201 const int nBlockHeight = active_chain_tip->nHeight + 1;
209 ? active_chain_tip->GetMedianTimePast()
212 return IsFinalTx(tx, nBlockHeight, nBlockTime);
238 bool useExistingLockPoints)
252 std::pair<int, int64_t> lockPair;
253 if (useExistingLockPoints) {
256 lockPair.second =
lp->
time;
259 std::vector<int> prevheights;
260 prevheights.resize(tx.
vin.size());
261 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
262 const CTxIn& txin = tx.
vin[txinIndex];
265 return error(
"%s: Missing input", __func__);
269 prevheights[txinIndex] = tip->
nHeight + 1;
271 prevheights[txinIndex] = coin.
nHeight;
277 lp->
time = lockPair.second;
291 int maxInputHeight = 0;
292 for (
const int height : prevheights) {
294 if (height != tip->
nHeight+1) {
295 maxInputHeight = std::max(maxInputHeight, height);
310 int expired = pool.Expire(GetTime<std::chrono::seconds>() - age);
318 coins_cache.Uncache(removed);
324 if (active_chainstate.IsInitialBlockDownload())
341 std::vector<uint256> vHashUpdate;
351 if (!fAddToMempool || (*it)->IsCoinBase() ||
353 *
this, *
m_mempool, *it,
true ).m_result_type !=
359 vHashUpdate.push_back((*it)->GetHash());
378 std::chrono::hours{gArgs.GetIntArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
401 if (coin.
IsSpent())
return false;
428 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),
439 const int64_t m_accept_time;
440 const bool m_bypass_limits;
448 std::vector<COutPoint>& m_coins_to_uncache;
449 const bool m_test_accept;
453 const bool m_allow_bip125_replacement{
true};
470 explicit Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
471 std::set<uint256> m_conflicts;
474 std::unique_ptr<CTxMemPoolEntry> m_entry;
475 std::list<CTransactionRef> m_replaced_transactions;
482 size_t m_conflicting_size{0};
514 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
533 const size_t m_limit_ancestors;
534 const size_t m_limit_ancestor_size;
537 size_t m_limit_descendants;
538 size_t m_limit_descendant_size;
541bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
545 const uint256& hash = ws.m_hash;
548 const int64_t nAcceptTime = args.m_accept_time;
549 const bool bypass_limits = args.m_bypass_limits;
550 std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
554 std::set<uint256>& setConflicts = ws.m_conflicts;
557 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
558 CAmount& nModifiedFees = ws.m_modified_fees;
559 CAmount& nConflictingFees = ws.m_conflicting_fees;
560 size_t& nConflictingSize = ws.m_conflicting_size;
601 if (ptxConflicting) {
602 if (!args.m_allow_bip125_replacement) {
606 if (!setConflicts.count(ptxConflicting->
GetHash()))
619 setConflicts.insert(ptxConflicting->
GetHash());
625 m_view.SetBackend(m_viewmempool);
631 coins_to_uncache.push_back(txin.
prevout);
637 if (!m_view.HaveCoin(txin.
prevout)) {
639 for (
size_t out = 0; out < tx.
vout.size(); out++) {
652 m_view.GetBestBlock();
657 m_view.SetBackend(m_dummy);
667 if (!
Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), ws.m_base_fees)) {
684 nModifiedFees = ws.m_base_fees;
685 m_pool.ApplyDelta(hash, nModifiedFees);
689 bool fSpendsCoinbase =
false;
691 const Coin &coin = m_view.AccessCoin(txin.
prevout);
693 fSpendsCoinbase =
true;
698 entry.reset(
new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
699 fSpendsCoinbase, nSigOpsCost,
lp));
700 unsigned int nSize = entry->GetTxSize();
708 if (!bypass_limits && !
CheckFeeRate(nSize, nModifiedFees, state))
return false;
712 if (setConflicts.size() == 1) {
740 assert(setIterConflicting.size() == 1);
743 m_limit_descendants += 1;
744 m_limit_descendant_size += conflict->GetSizeWithDescendants();
747 std::string errString;
748 if (!m_pool.CalculateMemPoolAncestors(*entry, setAncestors, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants, m_limit_descendant_size, errString)) {
749 setAncestors.clear();
751 std::string dummy_err_string;
764 !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)) {
780 if (!setConflicts.empty()) {
781 CFeeRate newFeeRate(nModifiedFees, nSize);
795 "too many potential replacements", *err_string);
800 "replacement-adds-unconfirmed", *err_string);
806 nConflictingFees += it->GetModifiedFee();
807 nConflictingSize += it->GetTxSize();
825 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, txdata)) {
845 const uint256& hash = ws.m_hash;
866 return error(
"%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
873bool MemPoolAccept::Finalize(
const ATMPArgs& args, Workspace& ws)
876 const uint256& hash = ws.m_hash;
878 const bool bypass_limits = args.m_bypass_limits;
882 const CAmount& nModifiedFees = ws.m_modified_fees;
883 const CAmount& nConflictingFees = ws.m_conflicting_fees;
884 const size_t& nConflictingSize = ws.m_conflicting_size;
885 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
891 it->GetTx().GetHash().ToString(),
894 (
int)entry->GetTxSize() - (
int)nConflictingSize);
895 ws.m_replaced_transactions.push_back(it->GetSharedTx());
903 bool validForFeeEstimation = !bypass_limits &&
IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
906 m_pool.addUnchecked(*entry, setAncestors, validForFeeEstimation);
909 if (!bypass_limits) {
937 if (args.m_test_accept) {
956 std::vector<Workspace> workspaces{};
957 workspaces.reserve(txns.size());
958 std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
959 [](
const auto& tx) { return Workspace(tx); });
960 std::map<const uint256, const MempoolAcceptResult> results;
965 for (Workspace& ws : workspaces) {
966 if (!PreChecks(args, ws)) {
976 assert(!args.m_allow_bip125_replacement);
977 m_viewmempool.PackageAddTransaction(ws.m_ptx);
983 std::string err_string;
984 if (txns.size() > 1 &&
985 !m_pool.CheckPackageLimits(txns, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants,
986 m_limit_descendant_size, err_string)) {
993 for (Workspace& ws : workspaces) {
995 if (!PolicyScriptChecks(args, ws, txdata)) {
1001 if (args.m_test_accept) {
1004 results.emplace(ws.m_ptx->GetWitnessHash(),
1018 bool bypass_limits,
bool test_accept)
1021 std::vector<COutPoint> coins_to_uncache;
1022 MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache,
1023 test_accept,
true };
1025 const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
1032 for (
const COutPoint& hashTx : coins_to_uncache)
1033 active_chainstate.CoinsTip().Uncache(hashTx);
1042 bool bypass_limits,
bool test_accept)
1048 const Package& package,
bool test_accept)
1052 assert(!package.empty());
1053 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){return tx != nullptr;}));
1055 std::vector<COutPoint> coins_to_uncache;
1057 MemPoolAccept::ATMPArgs args { chainparams,
GetTime(),
false, coins_to_uncache,
1058 test_accept,
false };
1062 for (
const COutPoint& hashTx : coins_to_uncache) {
1077 nSubsidy >>= halvings;
1082 std::string ldb_name,
1083 size_t cache_size_bytes,
1085 bool should_wipe) : m_dbview(
1086 gArgs.GetDataDirNet() / ldb_name, cache_size_bytes, in_memory, should_wipe),
1087 m_catcherview(&m_dbview) {}
1089void CoinsViews::InitCache()
1091 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
1098 std::optional<uint256> from_snapshot_blockhash)
1099 : m_mempool(mempool),
1101 m_blockman(blockman),
1102 m_chainman(chainman),
1103 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1106 size_t cache_size_bytes,
1109 std::string leveldb_name)
1116 leveldb_name, cache_size_bytes, in_memory, should_wipe);
1119void CChainState::InitCoinsCache(
size_t cache_size_bytes)
1148 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1157 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1158 if (strCmd.empty())
return;
1163 std::string singleQuote(
"'");
1165 safeStatus = singleQuote+safeStatus+singleQuote;
1166 boost::replace_all(strCmd,
"%s", safeStatus);
1168 std::thread t(runCommand, strCmd);
1184 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1194 if (!pindexBestInvalid || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
1195 pindexBestInvalid = pindexNew;
1200 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
1205 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
1249 return pindexPrev->
nHeight + 1;
1268 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1269 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1294 std::vector<CScriptCheck>* pvChecks)
1299 pvChecks->reserve(tx.
vin.size());
1316 std::vector<CTxOut> spent_outputs;
1317 spent_outputs.reserve(tx.
vin.size());
1319 for (
const auto& txin : tx.
vin) {
1323 spent_outputs.emplace_back(coin.
out);
1325 txdata.
Init(tx, std::move(spent_outputs));
1329 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1341 check.
swap(pvChecks->back());
1342 }
else if (!check()) {
1370 if (cacheFullScriptStore && !pvChecks) {
1382 return state.
Error(strMessage);
1396 if (view.
HaveCoin(out)) fClean =
false;
1398 if (undo.nHeight == 0) {
1404 undo.nHeight = alternate.
nHeight;
1415 view.
AddCoin(out, std::move(undo), !fClean);
1428 error(
"DisconnectBlock(): failure reading undo data");
1432 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1433 error(
"DisconnectBlock(): block and undo data inconsistent");
1438 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1445 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1446 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1449 bool is_spent = view.
SpendCoin(out, &coin);
1460 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1463 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1602 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
1604 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
1621 bool fScriptChecks =
true;
1630 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
1667 bool fEnforceBIP30 = !((pindex->
nHeight==91842 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
1668 (pindex->
nHeight==91880 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
1696 static constexpr int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
1734 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
1735 for (
const auto& tx : block.
vtx) {
1736 for (
size_t o = 0; o < tx->
vout.size(); o++) {
1738 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
1746 int nLockTimeFlags = 0;
1765 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
1767 std::vector<int> prevheights;
1770 int64_t nSigOpsCost = 0;
1771 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
1772 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
1776 nInputs += tx.
vin.size();
1790 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n", __func__);
1797 prevheights.resize(tx.
vin.size());
1798 for (
size_t j = 0; j < tx.
vin.size(); j++) {
1802 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
1803 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
1814 LogPrintf(
"ERROR: ConnectBlock(): too many sigops\n");
1820 std::vector<CScriptCheck> vChecks;
1821 bool fCacheResults = fJustCheck;
1827 return error(
"ConnectBlock(): CheckInputScripts on %s failed with %s",
1830 control.
Add(vChecks);
1843 if (block.
vtx[0]->GetValueOut() > blockReward) {
1844 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.
vtx[0]->GetValueOut(), blockReward);
1848 if (!control.
Wait()) {
1849 LogPrintf(
"ERROR: %s: CheckQueue failed\n", __func__);
1874 TRACE6(validation, block_connected,
1888 return this->GetCoinsCacheSizeState(
1894 size_t max_coins_cache_size_bytes,
1895 size_t max_mempool_size_bytes)
1899 int64_t nTotalSpace =
1900 max_coins_cache_size_bytes + std::max<int64_t>(max_mempool_size_bytes - nMempoolUsage, 0);
1903 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
1904 int64_t large_threshold =
1905 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
1907 if (cacheSize > nTotalSpace) {
1908 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
1910 }
else if (cacheSize > large_threshold) {
1919 int nManualPruneHeight)
1923 static std::chrono::microseconds nLastWrite{0};
1924 static std::chrono::microseconds nLastFlush{0};
1925 std::set<int> setFilesToPrune;
1926 bool full_flush_completed =
false;
1933 bool fFlushForPrune =
false;
1934 bool fDoFullFlush =
false;
1946 if (nManualPruneHeight > 0) {
1956 if (!setFilesToPrune.empty()) {
1957 fFlushForPrune =
true;
1959 m_blockman.m_block_tree_db->WriteFlag(
"prunedblockfiles",
true);
1964 const auto nNow = GetTime<std::chrono::microseconds>();
1966 if (nLastWrite.count() == 0) {
1969 if (nLastFlush.count() == 0) {
1981 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
1983 if (fDoFullFlush || fPeriodicWrite) {
1986 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
1999 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2005 std::vector<const CBlockIndex*> vBlocks;
2008 vBlocks.push_back(*it);
2012 return AbortNode(state,
"Failed to write to block index database");
2016 if (fFlushForPrune) {
2024 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2034 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2038 return AbortNode(state,
"Failed to write to coin database");
2040 full_flush_completed =
true;
2043 if (full_flush_completed) {
2047 }
catch (
const std::runtime_error& e) {
2048 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2072 static bool fWarned =
false;
2091 const std::string& func_name,
2092 const std::string&
prefix,
2097 LogPrintf(
"%s%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n",
2099 tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion,
2100 log(tip->nChainWork.getdouble()) / log(2.0), (
unsigned long)tip->nChainTx,
2105 !warning_messages.empty() ?
strprintf(
" warning='%s'", warning_messages) :
"");
2108void CChainState::UpdateTip(
const CBlockIndex* pindexNew)
2110 const auto& coins_tip = this->
CoinsTip();
2116 constexpr int BACKGROUND_LOG_INTERVAL = 2000;
2117 if (pindexNew->
nHeight % BACKGROUND_LOG_INTERVAL == 0) {
2171 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2174 return error(
"DisconnectTip(): Failed to read block");
2183 bool flushed = view.
Flush();
2194 for (
auto it = block.
vtx.rbegin(); it != block.
vtx.rend(); ++it) {
2207 UpdateTip(pindexDelete->
pprev);
2274 std::shared_ptr<const CBlock> pthisBlock;
2276 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2278 return AbortNode(state,
"Failed to read block");
2280 pthisBlock = pblockNew;
2282 pthisBlock = pblock;
2284 const CBlock& blockConnecting = *pthisBlock;
2291 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view);
2301 bool flushed = view.
Flush();
2319 UpdateTip(pindexNew);
2348 bool fInvalidAncestor =
false;
2358 if (fFailedChain || fMissingData) {
2360 if (fFailedChain && (pindexBestInvalid ==
nullptr || pindexNew->
nChainWork > pindexBestInvalid->nChainWork))
2361 pindexBestInvalid = pindexNew;
2364 while (pindexTest != pindexFailed) {
2367 }
else if (fMissingData) {
2372 std::make_pair(pindexFailed->
pprev, pindexFailed));
2375 pindexFailed = pindexFailed->
pprev;
2378 fInvalidAncestor =
true;
2381 pindexTest = pindexTest->
pprev;
2383 if (!fInvalidAncestor)
2415 bool fBlocksDisconnected =
false;
2426 AbortNode(state,
"Failed to disconnect block; see debug.log for details");
2429 fBlocksDisconnected =
true;
2433 std::vector<CBlockIndex*> vpindexToConnect;
2434 bool fContinue =
true;
2439 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
2440 vpindexToConnect.clear();
2441 vpindexToConnect.reserve(nTargetHeight -
nHeight);
2444 vpindexToConnect.push_back(pindexIter);
2445 pindexIter = pindexIter->
pprev;
2451 if (!
ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2458 fInvalidFound =
true;
2479 if (fBlocksDisconnected) {
2499 bool fNotify =
false;
2500 bool fInitialBlockDownload =
false;
2507 if (pindexHeader != pindexHeaderOld) {
2509 fInitialBlockDownload = chainstate.IsInitialBlockDownload();
2510 pindexHeaderOld = pindexHeader;
2559 bool blocks_connected =
false;
2565 if (pindexMostWork ==
nullptr) {
2570 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
2574 bool fInvalidFound =
false;
2575 std::shared_ptr<const CBlock> nullBlockPtr;
2576 if (!
ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
2580 blocks_connected =
true;
2582 if (fInvalidFound) {
2584 pindexMostWork =
nullptr;
2589 assert(trace.pblock && trace.pindex);
2593 if (!blocks_connected)
return true;
2600 if (pindexFork != pindexNewTip) {
2617 }
while (pindexNewTip != pindexMostWork);
2661 if (pindex->
nHeight == 0)
return false;
2664 bool pindex_was_in_chain =
false;
2665 int disconnected = 0;
2679 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
2683 for (
const auto& entry :
m_blockman.m_block_index) {
2694 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
2711 pindex_was_in_chain =
true;
2724 if (!ret)
return false;
2744 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
2745 while (candidate_it != candidate_blocks_by_work.end()) {
2748 candidate_it = candidate_blocks_by_work.erase(candidate_it);
2756 to_mark_failed = invalid_walk_tip;
2781 BlockMap::iterator it =
m_blockman.m_block_index.begin();
2782 while (it !=
m_blockman.m_block_index.end()) {
2793 if (pindex_was_in_chain) {
2805 BlockMap::iterator it =
m_blockman.m_block_index.begin();
2806 while (it !=
m_blockman.m_block_index.end()) {
2807 if (!it->second->IsValid() && it->second->GetAncestor(
nHeight) == pindex) {
2808 it->second->nStatus &= ~BLOCK_FAILED_MASK;
2813 if (it->second == pindexBestInvalid) {
2815 pindexBestInvalid =
nullptr;
2823 while (pindex !=
nullptr) {
2825 pindex->
nStatus &= ~BLOCK_FAILED_MASK;
2829 pindex = pindex->
pprev;
2839 BlockMap::iterator it = m_block_index.find(hash);
2840 if (it != m_block_index.end())
2849 BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
2851 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
2852 if (miPrev != m_block_index.end())
2854 pindexNew->
pprev = (*miPrev).second;
2872 pindexNew->
nTx = block.
vtx.size();
2886 std::deque<CBlockIndex*> queue;
2887 queue.push_back(pindexNew);
2890 while (!queue.empty()) {
2898 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
2899 while (range.first != range.second) {
2900 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
2901 queue.push_back(it->second);
2940 if (fCheckMerkleRoot) {
2964 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
2966 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
2967 if (block.
vtx[i]->IsCoinBase())
2972 for (
const auto& tx : block.
vtx) {
2982 unsigned int nSigOps = 0;
2983 for (
const auto& tx : block.
vtx)
2990 if (fCheckPOW && fCheckMerkleRoot)
2999 static const std::vector<unsigned char>
nonce(32, 0x00);
3002 tx.
vin[0].scriptWitness.stack.resize(1);
3003 tx.
vin[0].scriptWitness.stack[0] =
nonce;
3010 std::vector<unsigned char> commitment;
3012 std::vector<unsigned char> ret(32, 0x00);
3028 tx.
vout.push_back(out);
3039 for (
const MapCheckpoints::value_type& i :
reverse_iterate(checkpoints))
3041 const uint256& hash = i.second;
3061 assert(pindexPrev !=
nullptr);
3062 const int nHeight = pindexPrev->nHeight + 1;
3074 CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
3075 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
3076 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
3082 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
3094 strprintf(
"rejected nVersion=0x%08x block", block.nVersion));
3108 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3111 int nLockTimeFlags = 0;
3113 assert(pindexPrev !=
nullptr);
3122 for (
const auto& tx : block.
vtx) {
3132 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3133 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3146 bool fHaveWitness =
false;
3150 bool malleated =
false;
3155 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3159 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3162 fHaveWitness =
true;
3167 if (!fHaveWitness) {
3168 for (
const auto& tx : block.
vtx) {
3193 BlockMap::iterator miSelf = m_block_index.find(hash);
3195 if (miSelf != m_block_index.end()) {
3214 BlockMap::iterator mi = m_block_index.find(block.
hashPrevBlock);
3215 if (mi == m_block_index.end()) {
3219 pindexPrev = (*mi).second;
3254 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
3257 while (invalid_walk != failedit) {
3260 invalid_walk = invalid_walk->
pprev;
3284 bool accepted = m_blockman.AcceptBlockHeader(
3285 header, state, chainparams, &pindex);
3298 LogPrintf(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n", (*ppindex)->nHeight, 100.0/((*ppindex)->nHeight+(
GetAdjustedTime() - (*ppindex)->GetBlockTime()) /
Params().GetConsensus().nPowTargetSpacing) * (*ppindex)->nHeight);
3307 const CBlock& block = *pblock;
3309 if (fNewBlock) *fNewBlock =
false;
3313 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3318 if (!accepted_header)
3340 if (fAlreadyHave)
return true;
3342 if (pindex->
nTx != 0)
return true;
3343 if (!fHasMoreOrSameWork)
return true;
3344 if (fTooFarAhead)
return true;
3368 if (fNewBlock) *fNewBlock =
true;
3372 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3376 }
catch (
const std::runtime_error& e) {
3377 return AbortNode(state, std::string(
"System error: ") + e.what());
3393 if (new_block) *new_block =
false;
3412 return error(
"%s: AcceptBlock FAILED (%s)", __func__, state.
ToString());
3420 return error(
"%s: ActivateBestChain failed (%s)", __func__, state.
ToString());
3432 bool fCheckMerkleRoot)
3439 indexDummy.
pprev = pindexPrev;
3445 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.
ToString());
3447 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
3449 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__, state.
ToString());
3450 if (!chainstate.
ConnectBlock(block, state, &indexDummy, viewNew,
true)) {
3467 for (
const auto& entry : m_block_index) {
3469 if (pindex->
nFile == fileNumber) {
3470 pindex->
nStatus &= ~BLOCK_HAVE_DATA;
3471 pindex->
nStatus &= ~BLOCK_HAVE_UNDO;
3482 while (range.first != range.second) {
3483 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
3485 if (_it->second == pindex) {
3501 if (chain_tip_height < 0) {
3506 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight, chain_tip_height -
MIN_BLOCKS_TO_KEEP);
3508 for (
int fileNumber = 0; fileNumber <
nLastBlockFile; fileNumber++) {
3513 setFilesToPrune.insert(fileNumber);
3516 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune,
count);
3535 if ((uint64_t)chain_tip_height <= nPruneAfterHeight) {
3539 unsigned int nLastBlockWeCanPrune = std::min(prune_height, chain_tip_height -
static_cast<int>(
MIN_BLOCKS_TO_KEEP));
3545 uint64_t nBytesToPrune;
3558 for (
int fileNumber = 0; fileNumber <
nLastBlockFile; fileNumber++) {
3570 if (
vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
3576 setFilesToPrune.insert(fileNumber);
3577 nCurrentUsage -= nBytesToPrune;
3582 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
3584 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
3585 nLastBlockWeCanPrune,
count);
3596 BlockMap::iterator mi = m_block_index.find(hash);
3597 if (mi != m_block_index.end())
3598 return (*mi).second;
3602 mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
3610 std::set<CBlockIndex*, CBlockIndexWorkComparator>& block_index_candidates)
3617 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
3618 vSortedByHeight.reserve(m_block_index.size());
3619 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index)
3622 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
3624 sort(vSortedByHeight.begin(), vSortedByHeight.end());
3625 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
3633 if (pindex->
nTx > 0) {
3634 if (pindex->
pprev) {
3652 block_index_candidates.insert(pindex);
3655 pindexBestInvalid = pindex;
3669 for (
const BlockMap::value_type& entry : m_block_index) {
3670 delete entry.second;
3673 m_block_index.clear();
3676bool BlockManager::LoadBlockIndexDB(std::set<CBlockIndex*, CBlockIndexWorkComparator>& setBlockIndexCandidates)
3679 ::
Params().GetConsensus(),
3680 setBlockIndexCandidates)) {
3689 m_block_tree_db->ReadBlockFileInfo(nFile,
vinfoBlockFile[nFile]);
3694 if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) {
3702 LogPrintf(
"Checking all blk files are present...\n");
3703 std::set<int> setBlkDataFiles;
3704 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index) {
3707 setBlkDataFiles.insert(pindex->
nFile);
3710 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
3719 m_block_tree_db->ReadFlag(
"prunedblockfiles",
fHavePruned);
3721 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
3724 bool fReindexing =
false;
3725 m_block_tree_db->ReadReindexing(fReindexing);
3760 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
3770 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, 0,
false);
3782 int nCheckLevel,
int nCheckDepth)
3790 if (nCheckDepth <= 0 || nCheckDepth > chainstate.
m_chain.
Height())
3792 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3793 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
3797 int nGoodTransactions = 0;
3805 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
3806 if (reportDone < percentageDone/10) {
3809 reportDone = percentageDone/10;
3811 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
3817 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
3826 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
3829 if (nCheckLevel >= 2 && pindex) {
3847 nGoodTransactions = 0;
3848 pindexFailure = pindex;
3850 nGoodTransactions += block.
vtx.size();
3856 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.
m_chain.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
3862 if (nCheckLevel >= 4) {
3864 const int percentageDone = std::max(1, std::min(99, 100 - (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * 50)));
3865 if (reportDone < percentageDone/10) {
3868 reportDone = percentageDone/10;
3870 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
3875 if (!chainstate.
ConnectBlock(block, state, pindex, coins)) {
3883 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
3898 if (!tx->IsCoinBase()) {
3899 for (
const CTxIn &txin : tx->vin) {
3917 if (hashHeads.empty())
return true;
3918 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
3920 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, 0,
false);
3927 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
3928 return error(
"ReplayBlocks(): reorganization to unknown block requested");
3930 pindexNew =
m_blockman.m_block_index[hashHeads[0]];
3932 if (!hashHeads[1].IsNull()) {
3933 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
3934 return error(
"ReplayBlocks(): reorganization from unknown block requested");
3936 pindexOld =
m_blockman.m_block_index[hashHeads[1]];
3938 assert(pindexFork !=
nullptr);
3942 while (pindexOld != pindexFork) {
3958 pindexOld = pindexOld->
pprev;
3962 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
3966 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, (
int) ((
nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
3988 block = block->
pprev;
3995 nBlockSequenceId = 1;
4006 pindexBestInvalid =
nullptr;
4008 if (mempool) mempool->
clear();
4015 warningcache[b].clear();
4026 bool ret = m_blockman.LoadBlockIndexDB(
ActiveChainstate().setBlockIndexCandidates);
4027 if (!ret)
return false;
4028 needs_init = m_blockman.m_block_index.empty();
4038 LogPrintf(
"Initializing databases...\n");
4058 return error(
"%s: writing genesis block to disk failed", __func__);
4061 }
catch (
const std::runtime_error& e) {
4062 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4071 static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
4078 uint64_t nRewind = blkdat.
GetPos();
4079 while (!blkdat.
eof()) {
4085 unsigned int nSize = 0;
4090 nRewind = blkdat.
GetPos()+1;
4099 }
catch (
const std::exception&) {
4105 uint64_t nBlockPos = blkdat.
GetPos();
4107 dbp->
nPos = nBlockPos;
4108 blkdat.
SetLimit(nBlockPos + nSize);
4109 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4112 nRewind = blkdat.
GetPos();
4122 mapBlocksUnknownParent.insert(std::make_pair(block.
hashPrevBlock, *dbp));
4130 if (
AcceptBlock(pblock, state,
nullptr,
true, dbp,
nullptr)) {
4152 std::deque<uint256> queue;
4153 queue.push_back(hash);
4154 while (!queue.empty()) {
4157 std::pair<std::multimap<uint256, FlatFilePos>::iterator, std::multimap<uint256, FlatFilePos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
4158 while (range.first != range.second) {
4159 std::multimap<uint256, FlatFilePos>::iterator it = range.first;
4160 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4162 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4166 if (
AcceptBlock(pblockrecursive, dummy,
nullptr,
true, &it->second,
nullptr)) {
4168 queue.push_back(pblockrecursive->GetHash());
4172 mapBlocksUnknownParent.erase(it);
4176 }
catch (
const std::exception& e) {
4177 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
4180 }
catch (
const std::runtime_error& e) {
4181 AbortNode(std::string(
"System error: ") + e.what());
4203 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4204 for (
const std::pair<const uint256, CBlockIndex*>& entry :
m_blockman.m_block_index) {
4205 forward.insert(std::make_pair(entry.second->pprev, entry.second));
4210 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4212 rangeGenesis.first++;
4213 assert(rangeGenesis.first == rangeGenesis.second);
4224 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4226 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4227 while (pindex !=
nullptr) {
4233 pindexFirstMissing = pindex;
4235 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4242 if (pindexFirstNotTransactionsValid ==
nullptr &&
4244 pindexFirstNotTransactionsValid = pindex;
4247 if (pindexFirstNotChainValid ==
nullptr &&
4249 pindexFirstNotChainValid = pindex;
4252 if (pindexFirstNotScriptsValid ==
nullptr &&
4254 pindexFirstNotScriptsValid = pindex;
4259 if (pindex->
pprev ==
nullptr) {
4272 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4294 assert(pindexFirstNotTreeValid ==
nullptr);
4298 if (pindexFirstInvalid ==
nullptr) {
4303 if (pindexFirstInvalid ==
nullptr) {
4314 if (is_active && (pindexFirstMissing ==
nullptr || pindex ==
m_chain.
Tip())) {
4325 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
m_blockman.
m_blocks_unlinked.equal_range(pindex->
pprev);
4326 bool foundInUnlinked =
false;
4327 while (rangeUnlinked.first != rangeUnlinked.second) {
4328 assert(rangeUnlinked.first->first == pindex->
pprev);
4329 if (rangeUnlinked.first->second == pindex) {
4330 foundInUnlinked =
true;
4333 rangeUnlinked.first++;
4335 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4340 if (pindexFirstMissing ==
nullptr)
assert(!foundInUnlinked);
4341 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4353 if (pindexFirstInvalid ==
nullptr) {
4362 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4363 if (range.first != range.second) {
4365 pindex = range.first->second;
4374 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4375 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4376 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4377 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4378 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4379 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4380 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4384 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4385 while (rangePar.first->second != pindex) {
4386 assert(rangePar.first != rangePar.second);
4391 if (rangePar.first != rangePar.second) {
4393 pindex = rangePar.first->second;
4405 assert(nNodes == forward.size());
4411 return strprintf(
"Chainstate [%s] @ height %d (%s)",
4416bool CChainState::ResizeCoinsCaches(
size_t coinstip_size,
size_t coinsdb_size)
4428 LogPrintf(
"[%s] resized coinsdb cache to %.1f MiB\n",
4429 this->
ToString(), coinsdb_size * (1.0 / 1024 / 1024));
4430 LogPrintf(
"[%s] resized coinstip cache to %.1f MiB\n",
4431 this->
ToString(), coinstip_size * (1.0 / 1024 / 1024));
4436 if (coinstip_size > old_coinstip_size) {
4456 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
4461 int64_t expired = 0;
4463 int64_t already_there = 0;
4464 int64_t unbroadcast = 0;
4483 CAmount amountdelta = nFeeDelta;
4487 if (nTime > nNow - nExpiryTimeout) {
4509 std::map<uint256, CAmount> mapDeltas;
4512 for (
const auto& i : mapDeltas) {
4516 std::set<uint256> unbroadcast_txids;
4517 file >> unbroadcast_txids;
4518 unbroadcast = unbroadcast_txids.size();
4519 for (
const auto& txid : unbroadcast_txids) {
4524 }
catch (
const std::exception& e) {
4525 LogPrintf(
"Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
4529 LogPrintf(
"Imported mempool transactions from disk: %i succeeded, %i failed, %i expired, %i already there, %i waiting for initial broadcast\n",
count, failed, expired, already_there, unbroadcast);
4537 std::map<uint256, CAmount> mapDeltas;
4538 std::vector<TxMempoolInfo> vinfo;
4539 std::set<uint256> unbroadcast_txids;
4541 static Mutex dump_mutex;
4546 for (
const auto &i : pool.mapDeltas) {
4547 mapDeltas[i.first] = i.second;
4556 FILE* filestr{mockable_fopen_function(
gArgs.
GetDataDirNet() /
"mempool.dat.new",
"wb")};
4566 file << (uint64_t)vinfo.size();
4567 for (
const auto& i : vinfo) {
4570 file << int64_t{i.nFeeDelta};
4571 mapDeltas.erase(i.tx->GetHash());
4576 LogPrintf(
"Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
4577 file << unbroadcast_txids;
4580 throw std::runtime_error(
"FileCommit failed");
4583 throw std::runtime_error(
"Rename failed");
4586 LogPrintf(
"Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*
MICRO, (last-mid)*
MICRO);
4587 }
catch (
const std::exception& e) {
4588 LogPrintf(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
4597 if (pindex ==
nullptr)
4600 int64_t nNow = time(
nullptr);
4610 return std::min<double>(pindex->
nChainTx / fTxTotal, 1.0);
4616 if (m_active_chainstate && m_active_chainstate->m_from_snapshot_blockhash) {
4618 return m_active_chainstate->m_from_snapshot_blockhash;
4620 return std::nullopt;
4626 std::vector<CChainState*> out;
4629 out.push_back(m_ibd_chainstate.get());
4632 if (m_snapshot_chainstate) {
4633 out.push_back(m_snapshot_chainstate.get());
4639CChainState& ChainstateManager::InitializeChainstate(
4640 CTxMemPool* mempool,
const std::optional<uint256>& snapshot_blockhash)
4642 bool is_snapshot = snapshot_blockhash.has_value();
4643 std::unique_ptr<CChainState>& to_modify =
4644 is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
4647 throw std::logic_error(
"should not be overwriting a chainstate");
4649 to_modify.reset(
new CChainState(mempool, m_blockman, *
this, snapshot_blockhash));
4652 if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
4653 LogPrintf(
"Switching active chainstate to %s\n", to_modify->ToString());
4654 m_active_chainstate = to_modify.get();
4656 throw std::logic_error(
"unexpected chainstate activation");
4666 const auto assumeutxo_found = valid_assumeutxos_map.find(height);
4668 if (assumeutxo_found != valid_assumeutxos_map.end()) {
4669 return &assumeutxo_found->second;
4682 LogPrintf(
"[snapshot] can't activate a snapshot-based chainstate more than once\n");
4686 int64_t current_coinsdb_cache_size{0};
4687 int64_t current_coinstip_cache_size{0};
4695 static constexpr double IBD_CACHE_PERC = 0.01;
4696 static constexpr double SNAPSHOT_CACHE_PERC = 0.99;
4714 static_cast<size_t>(current_coinstip_cache_size * IBD_CACHE_PERC),
4715 static_cast<size_t>(current_coinsdb_cache_size * IBD_CACHE_PERC));
4719 return std::make_unique<CChainState>(
4720 nullptr, m_blockman, *
this, base_blockhash));
4724 snapshot_chainstate->InitCoinsDB(
4725 static_cast<size_t>(current_coinsdb_cache_size * SNAPSHOT_CACHE_PERC),
4726 in_memory,
false,
"chainstate");
4727 snapshot_chainstate->InitCoinsCache(
4728 static_cast<size_t>(current_coinstip_cache_size * SNAPSHOT_CACHE_PERC));
4732 *snapshot_chainstate, coins_file, metadata);
4741 assert(!m_snapshot_chainstate);
4742 m_snapshot_chainstate.swap(snapshot_chainstate);
4743 const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip();
4746 m_active_chainstate = m_snapshot_chainstate.get();
4748 LogPrintf(
"[snapshot] successfully activated snapshot %s\n", base_blockhash.
ToString());
4750 m_snapshot_chainstate->CoinsTip().DynamicMemoryUsage() / (1000 * 1000));
4752 this->MaybeRebalanceCaches();
4770 if (!snapshot_start_block) {
4772 LogPrintf(
"[snapshot] Did not find snapshot start blockheader %s\n",
4777 int base_height = snapshot_start_block->
nHeight;
4780 if (!maybe_au_data) {
4781 LogPrintf(
"[snapshot] assumeutxo height in snapshot metadata not recognized "
4782 "(%d) - refusing to load snapshot\n", base_height);
4793 LogPrintf(
"[snapshot] loading coins from snapshot %s\n", base_blockhash.
ToString());
4794 int64_t flush_now{0};
4795 int64_t coins_processed{0};
4797 while (coins_left > 0) {
4799 coins_file >> outpoint;
4801 }
catch (
const std::ios_base::failure&) {
4802 LogPrintf(
"[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n",
4803 coins_count - coins_left);
4806 if (coin.
nHeight > base_height ||
4807 outpoint.
n >= std::numeric_limits<
decltype(outpoint.
n)>::max()
4809 LogPrintf(
"[snapshot] bad snapshot data after deserializing %d coins\n",
4810 coins_count - coins_left);
4819 if (coins_processed % 1000000 == 0) {
4820 LogPrintf(
"[snapshot] %d coins loaded (%.2f%%, %.2f MB)\n",
4822 static_cast<float>(coins_processed) * 100 /
static_cast<float>(coins_count),
4830 if (coins_processed % 120000 == 0) {
4836 return snapshot_chainstate.GetCoinsCacheSizeState());
4838 if (snapshot_cache_state >=
4840 LogPrintf(
"[snapshot] flushing coins cache (%.2f MB)... ",
4849 coins_cache.
Flush();
4862 bool out_of_coins{
false};
4864 coins_file >> outpoint;
4865 }
catch (
const std::ios_base::failure&) {
4867 out_of_coins =
true;
4869 if (!out_of_coins) {
4870 LogPrintf(
"[snapshot] bad snapshot - coins left over after deserializing %d coins\n",
4875 LogPrintf(
"[snapshot] loaded %d (%.2f MB) coins from snapshot %s\n",
4880 LogPrintf(
"[snapshot] flushing snapshot chainstate to disk\n");
4882 coins_cache.
Flush();
4887 auto breakpoint_fnc = [] { };
4894 LogPrintf(
"[snapshot] failed to generate coins stats\n");
4900 LogPrintf(
"[snapshot] bad snapshot content hash: expected %s, got %s\n",
4912 for (
int i = 0; i <= snapshot_chainstate.
m_chain.
Height(); ++i) {
4913 index = snapshot_chainstate.
m_chain[i];
4948 LogPrintf(
"[snapshot] validated snapshot (%.2f MB)\n",
4956 assert(m_active_chainstate);
4957 return *m_active_chainstate;
4963 return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get();
4966void ChainstateManager::Unload()
4969 chainstate->m_chain.SetTip(
nullptr);
4970 chainstate->UnloadBlockIndex();
4973 m_blockman.Unload();
4979 m_ibd_chainstate.reset();
4980 m_snapshot_chainstate.reset();
4981 m_active_chainstate =
nullptr;
4985void ChainstateManager::MaybeRebalanceCaches()
4987 if (m_ibd_chainstate && !m_snapshot_chainstate) {
4988 LogPrintf(
"[snapshot] allocating all cache to the IBD chainstate\n");
4992 else if (m_snapshot_chainstate && !m_ibd_chainstate) {
4993 LogPrintf(
"[snapshot] allocating all cache to the snapshot chainstate\n");
4997 else if (m_ibd_chainstate && m_snapshot_chainstate) {
5001 if (m_snapshot_chainstate->IsInitialBlockDownload()) {
5002 m_ibd_chainstate->ResizeCoinsCaches(
5004 m_snapshot_chainstate->ResizeCoinsCaches(
5007 m_snapshot_chainstate->ResizeCoinsCaches(
5009 m_ibd_chainstate->ResizeCoinsCaches(
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
void ForEachBlockFilterIndex(std::function< void(BlockFilterIndex &)> fn)
Iterate over all running block filter indexes, invoking fn on each.
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
bool fHavePruned
Pruning-related variables and constants.
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams)
bool fPruneMode
True if we're running in -prune mode.
FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, CChain &active_chain, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
std::atomic_bool fReindex
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
std::atomic_bool fImporting
arith_uint256 GetBlockProof(const CBlockIndex &block)
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
Return the time it would take to redo the work difference between from and to, assuming the current h...
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends,...
@ BLOCK_VALID_MASK
All validity bits.
@ BLOCK_ASSUMED_VALID
If set, this indicates that the block index entry is assumed-valid.
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
@ BLOCK_HAVE_DATA
full block available in blk*.dat
@ BLOCK_FAILED_CHILD
descends from failed block
@ BLOCK_FAILED_VALID
stage after last reached validness failed
@ BLOCK_OPT_WITNESS
block data in blk*.dat was received with a witness-enforcing client
static constexpr int64_t MAX_FUTURE_BLOCK_TIME
Maximum amount of time that a block timestamp is allowed to exceed the current network-adjusted time ...
const CChainParams & Params()
Return the currently selected parameters.
std::map< int, const AssumeutxoData > MapAssumeutxo
std::map< int, uint256 > MapCheckpoints
#define Assume(val)
Assume is the identity function.
Abstract class that implements BIP9-style threshold logic, and caches results.
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
std::string ToString() const
IndexSummary GetSummary() const
Get a summary of the index and its state.
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
CBlockIndex * GetLastCheckpoint(const CCheckpointData &data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Returns last CBlockIndex* that is a checkpoint.
CBlockIndex * AddToBlockIndex(const CBlockHeader &block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::set< CBlockIndex * > m_failed_blocks
In order to efficiently track invalidity of headers, we keep the set of blocks which we tried to conn...
CBlockIndex * LookupBlockIndex(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Clear all data members.
void FindFilesToPrune(std::set< int > &setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, int prune_height, bool is_ibd)
Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a us...
bool AcceptBlockHeader(const CBlockHeader &block, BlockValidationState &state, const CChainParams &chainparams, CBlockIndex **ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
If a block header hasn't already been seen, call CheckBlockHeader on it, ensure that it doesn't desce...
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
bool LoadBlockIndexDB(std::set< CBlockIndex *, CBlockIndexWorkComparator > &setBlockIndexCandidates) EXCLUSIVE_LOCKS_REQUIRED(boo LoadBlockIndex)(const Consensus::Params &consensus_params, std::set< CBlockIndex *, CBlockIndexWorkComparator > &block_index_candidates) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
int GetSpendHeight(const CCoinsViewCache &inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the spend height, which is one more than the inputs.GetBestBlock().
std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the last common block between the parameter chain and a locator.
Non-refcounted RAII wrapper for FILE*.
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
void BuildSkip()
Build the skiplist pointer for this entry.
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
int nFile
Which # file this block is stored in (blk?????.dat)
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
uint256 GetBlockHash() const
int64_t GetBlockTime() const
int64_t GetMedianTimePast() const
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
bool IsAssumedValid() const
unsigned int nTx
Number of transactions in this block.
FlatFilePos GetUndoPos() const
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
int32_t nVersion
block header
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
uint32_t nStatus
Verification status of this block.
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
Undo information for a CBlock.
std::vector< CTxUndo > vtxundo
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
prevent reading beyond a certain position no argument removes the limit
void FindByte(char ch)
search for a given byte in the stream, and remain positioned on it
uint64_t GetPos() const
return the current reading position
bool SetPos(uint64_t nPos)
rewind to a given reading position
bool eof() const
check whether we're at the end of the source file
An in-memory indexed chain of blocks.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip).
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
int Height() const
Return the maximal height in the chain.
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
void SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
const CBlock & GenesisBlock() const
const ChainTxData & TxData() const
const Consensus::Params & GetConsensus() const
const CMessageHeader::MessageStartChars & MessageStart() const
uint64_t PruneAfterHeight() const
const MapAssumeutxo & Assumeutxo() const
Get allowed assumeutxo configuration.
CChainState stores and provides an API to update our local knowledge of the current best chain.
void CheckBlockIndex()
Make various assertions about the state of the block index.
std::atomic< bool > m_cached_finished_ibd
Whether this chainstate is undergoing initial block download.
bool AcceptBlock(const std::shared_ptr< const CBlock > &pblock, BlockValidationState &state, CBlockIndex **ppindex, bool fRequested, const FlatFilePos *dbp, bool *fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Store block on disk.
arith_uint256 nLastPreciousChainwork
chainwork for the last block that preciousblock has been applied to.
const CChainParams & m_params
bool ReplayBlocks()
Replay blocks that aren't fully applied to the database.
bool ActivateBestChain(BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr) LOCKS_EXCLUDED(cs_main)
Find the best known block, and make it the tip of the block chain.
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
bool ConnectTip(BlockValidationState &state, CBlockIndex *pindexNew, const std::shared_ptr< const CBlock > &pblock, ConnectTrace &connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Connect a new block to m_chain.
void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void MaybeUpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Make mempool consistent after a reorg, by re-adding or recursively erasing disconnected block transac...
CTxMemPool * m_mempool
Optional mempool that is kept in sync with the chain.
RecursiveMutex m_cs_chainstate
the ChainState CriticalSection A lock that must be held when modifying this ChainState - held in Acti...
CChainState(CTxMemPool *mempool, BlockManager &blockman, ChainstateManager &chainman, std::optional< uint256 > from_snapshot_blockhash=std::nullopt)
std::set< CBlockIndex *, CBlockIndexWorkComparator > setBlockIndexCandidates
The set of all CBlockIndex entries with either BLOCK_VALID_TRANSACTIONS (for itself and all ancestors...
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void PruneAndFlush()
Prune blockfiles from the disk if necessary and then flush chainstate changes if we pruned.
const std::optional< uint256 > m_from_snapshot_blockhash
The blockhash which is the base of the snapshot this chainstate was created from.
void PruneBlockIndexCandidates()
Delete all entries in setBlockIndexCandidates that are worse than the current tip.
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove invalidity status from a block and its descendants.
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of a block on the utxo cache, ignoring that it may already have been applied.
bool ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size) EXCLUSIVE_LOCKS_REQUIRED(void LoadExternalBlockFile(FILE *fileIn, FlatFilePos *dbp=nullptr)
Resize the CoinsViews caches dynamically and flush state to disk.
size_t m_coinsdb_cache_size_bytes
The cache size of the on-disk coins view.
RecursiveMutex * MempoolMutex() const LOCK_RETURNED(m_mempool -> cs)
Indirection necessary to make lock annotations work with an optional mempool.
bool FlushStateToDisk(BlockValidationState &state, FlushStateMode mode, int nManualPruneHeight=0)
Update the on-disk chain state.
DisconnectResult DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view)
Undo the effects of this block (with given index) on the UTXO set represented by coins.
void InitCoinsDB(size_t cache_size_bytes, bool in_memory, bool should_wipe, std::string leveldb_name="chainstate")
Initialize the CoinsViews UTXO set database management data structures.
bool ConnectBlock(const CBlock &block, BlockValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool fJustCheck=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of this block (with given index) on the UTXO set represented by coins.
void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Whether the chain state needs to be redownloaded due to lack of witness data.
std::unique_ptr< CoinsViews > m_coins_views
Manages the UTXO set, which is a reflection of the contents of m_chain.
void UnloadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network)
int32_t nBlockReverseSequenceId
Decreasing counter (used by subsequent preciousblock calls).
bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Update the chain tip based on database information, i.e.
BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all CChainState instances.
CChain m_chain
The current chain of blockheaders we consult and build on.
bool DisconnectTip(BlockValidationState &state, DisconnectedBlockTransactions *disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Disconnect m_chain's tip.
void InitCoinsCache(size_t cache_size_bytes) EXCLUSIVE_LOCKS_REQUIRED(bool CanFlushToDisk() const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Initialize the in-memory coins cache (to be done after the health of the on-disk database is verified...
bool PreciousBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as precious and reorganize.
void ReceivedBlockTransactions(const CBlock &block, CBlockIndex *pindexNew, const FlatFilePos &pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
void InvalidChainFound(CBlockIndex *pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as invalid.
bool ActivateBestChainStep(BlockValidationState &state, CBlockIndex *pindexMostWork, const std::shared_ptr< const CBlock > &pblock, bool &fInvalidFound, ConnectTrace &connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Dictates whether we need to flush the cache to disk or not.
void LoadMempool(const ArgsManager &args)
Load the persisted mempool from disk.
CBlockIndex * FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the tip of the chain with the most work in it, that isn't known to be invalid (it's however fa...
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
void Add(std::vector< T > &vChecks)
Queue for verifications that have to be performed.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
void SetBestBlock(const uint256 &hashBlock)
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
bool Flush()
Push the modifications applied to this cache to its base.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
void ReallocateCache()
Force a reallocation of the cache map.
CCoinsView backed by the coin database (chainstate/)
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
Abstract view on the open txout dataset.
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
CCoinsView that brings transactions from a mempool into view.
Fee rate in satoshis per kilobyte: CAmount / kB.
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given size in bytes.
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
void Finalize(Span< unsigned char > output)
CHash256 & Write(Span< const unsigned char > input)
void TransactionAddedToMempool(const CTransactionRef &, uint64_t mempool_sequence)
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
void BlockDisconnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void BlockChecked(const CBlock &, const BlockValidationState &)
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
void ChainStateFlushed(const CBlockLocator &)
An outpoint - a combination of a transaction hash and an index n into its vout.
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Closure representing one script verification Note that this stores references to the spending transac...
ScriptError GetScriptError() const
PrecomputedTransactionData * txdata
void swap(CScriptCheck &check)
const CTransaction * ptxTo
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
const uint256 & GetWitnessHash() const
const uint256 & GetHash() const
const std::vector< CTxOut > vout
const std::vector< CTxIn > vin
An input of a transaction.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
void AddUnbroadcastTx(const uint256 &txid)
Adds a transaction to the unbroadcast set.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs
When adding transactions from a disconnected block back to the mempool, new mempool entries may have ...
void AddTransactionsUpdated(unsigned int n)
void removeForReorg(CChainState &active_chainstate, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs
CTransactionRef get(const uint256 &hash) const
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
void SetIsLoaded(bool loaded)
Sets the current loaded state.
std::set< txiter, CompareIteratorByHash > setEntries
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
bool exists(const GenTxid >xid) const
An output of a transaction.
Undo information for a CTransaction.
std::vector< Coin > vprevout
bool VerifyDB(CChainState &chainstate, const CChainParams &chainparams, CCoinsView &coinsview, int nCheckLevel, int nCheckDepth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
void Unload() EXCLUSIVE_LOCKS_REQUIRED(void Reset()
Unload block index and chain data before shutdown.
int64_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
int64_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > &block, bool force_processing, bool *new_block) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
CChainState &InitializeChainstate(CTxMemPool *mempool, const std::optional< uint256 > &snapshot_blockhash=std::nullopt) LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * GetAll)()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
CChainState & ActiveChainstate() const
The most-work chain.
bool PopulateAndValidateSnapshot(CChainState &snapshot_chainstate, CAutoFile &coins_file, const SnapshotMetadata &metadata)
Internal helper for ActivateSnapshot().
bool IsSnapshotActive() const
bool m_snapshot_validated
If true, the assumed-valid chainstate has been fully validated by the background validation chainstat...
bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the block tree and coins database from disk, initializing state if we're running with -reindex.
std::optional< uint256 > SnapshotBlockhash() const
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &block, BlockValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex=nullptr) LOCKS_EXCLUDED(cs_main)
Process incoming block headers.
bool ActivateSnapshot(CAutoFile &coins_file, const SnapshotMetadata &metadata, bool in_memory)
Construct and activate a Chainstate on the basis of UTXO snapshot data.
bool IsSnapshotValidated() const
Is there a snapshot in use and has it been fully validated?
CTxOut out
unspent transaction output
bool IsSpent() const
Either this coin never existed (see e.g.
uint32_t nHeight
at which height this containing transaction was included in the active block chain
unsigned int fCoinBase
whether containing transaction was a coinbase
CoinsViews(std::string ldb_name, size_t cache_size_bytes, bool in_memory, bool should_wipe)
This constructor initializes CCoinsViewDB and CCoinsViewErrorCatcher instances, but it does not creat...
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
std::vector< PerBlockConnectTrace > & GetBlocksConnected()
std::vector< PerBlockConnectTrace > blocksConnected
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
cache implements a cache with properties similar to a cuckoo-set.
static GenTxid Wtxid(const uint256 &hash)
static GenTxid Txid(const uint256 &hash)
std::string GetRejectReason() const
std::string GetDebugMessage() const
bool Error(const std::string &reject_reason)
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
std::string ToString() const
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Determine what nVersion a new block should use.
Threshold condition checker that triggers when unknown versionbits are seen on the network.
int64_t EndTime(const Consensus::Params ¶ms) const override
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
WarningBitsConditionChecker(int bitIn)
int Threshold(const Consensus::Params ¶ms) const override
int64_t BeginTime(const Consensus::Params ¶ms) const override
int Period(const Consensus::Params ¶ms) const override
256-bit unsigned big integer.
const unsigned char * data() const
std::string ToString() const
void resize(size_type new_size)
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
static bool GetUTXOStats(CCoinsView *view, BlockManager &blockman, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point, const CBlockIndex *pindex)
Calculate statistics about the unspent transaction output set.
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction.
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
static int64_t GetBlockWeight(const CBlock &block)
@ BLOCK_CHECKPOINT
the block failed to meet one of our checkpoints
@ BLOCK_INVALID_HEADER
invalid proof of work or time too old
@ BLOCK_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
@ BLOCK_MISSING_PREV
We don't have the previous block the checked one is built on.
@ BLOCK_INVALID_PREV
A block this one builds on is invalid.
@ BLOCK_MUTATED
the block's data didn't match the data committed to by the PoW
@ BLOCK_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs,...
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
@ TX_MEMPOOL_POLICY
violated mempool's fee/size/descendant/RBF/etc limits
@ TX_PREMATURE_SPEND
transaction spends a coinbase too early, or violates locktime/sequence locks
@ TX_INPUTS_NOT_STANDARD
inputs (covered by txid) failed policy rules
@ TX_WITNESS_STRIPPED
Transaction is missing a witness.
@ TX_CONFLICT
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
@ TX_NOT_STANDARD
otherwise didn't meet our local policy rules
@ TX_WITNESS_MUTATED
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
@ TX_CONSENSUS
invalid by consensus rules
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
static constexpr unsigned int LOCKTIME_MEDIAN_TIME_PAST
Use GetMedianTimePast() instead of nTime for end point timestamp.
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule)
static const int WITNESS_SCALE_FACTOR
VersionBitsCache g_versionbitscache
Global cache for versionbits deployment status.
bool DeploymentActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is active for the next block.
bool DeploymentActiveAt(const CBlockIndex &index, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is active for this block.
static feebumper::Result CheckFeeRate(const CWallet &wallet, const CWalletTx &wtx, const CFeeRate &newFeerate, const int64_t maxTxSize, std::vector< bilingual_str > &errors)
Check if the user provided a valid feeRate.
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
@ SCRIPT_VERIFY_NULLDUMMY
@ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY
@ SCRIPT_VERIFY_CLEANSTACK
@ SCRIPT_VERIFY_CHECKSEQUENCEVERIFY
#define LogPrint(category,...)
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, CAmount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts) This does not m...
bool CheckPackage(const Package &txns, PackageValidationState &state)
Context-free package policy checks:
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).
@ PCKG_TX
At least one tx is invalid.
std::optional< std::string > HasNoNewUnconfirmed(const CTransaction &tx, const CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting)
BIP125 Rule #2: "The replacement transaction may only include an unconfirmed input if that input was ...
std::optional< std::string > PaysForRBF(CAmount original_fees, CAmount replacement_fees, size_t replacement_vsize, CFeeRate relay_fee, const uint256 &txid)
Enforce BIP125 Rule #3 "The replacement transaction pays an absolute fee of at least the sum paid by ...
std::optional< std::string > EntriesAndTxidsDisjoint(const CTxMemPool::setEntries &ancestors, const std::set< uint256 > &direct_conflicts, const uint256 &txid)
Check the intersection between two sets of transactions (a set of mempool entries and a set of txids)...
std::optional< std::string > PaysMoreThanConflicts(const CTxMemPool::setEntries &iters_conflicting, CFeeRate replacement_feerate, const uint256 &txid)
Check that the feerate of the replacement transaction(s) is higher than the feerate of each of the tr...
std::optional< std::string > GetEntriesForConflicts(const CTransaction &tx, CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting, CTxMemPool::setEntries &all_conflicts)
Get all descendants of iters_conflicting.
CFeeRate incrementalRelayFee
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs, bool taproot_active)
Check transaction inputs to mitigate two potential denial-of-service attacks:
bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, const CFeeRate &dust_relay_fee, std::string &reason)
Check for standard transaction types.
bool IsWitnessStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check if the transaction is over standard P2WSH resources limit: 3600bytes witnessScript size,...
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST
The maximum number of sigops we're willing to relay/mine in a single tx.
static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS
Used as the flags parameter to sequence and nLocktime checks in non-consensus code.
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
static const unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE
The minimum non-witness size for transactions we're willing to relay/mine (1 segwit input + 1 P2WPKH ...
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS
For convenience, standard but not mandatory verify flags.
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
uint256 GetRandHash() noexcept
reverse_range< T > reverse_iterate(T &x)
std::string ScriptErrorString(const ScriptError serror)
size_t GetSerializeSize(const T &t, int nVersion=0)
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
void StartShutdown()
Request shutdown of the application.
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
static const int64_t MAX_MAX_SIG_CACHE_SIZE
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Holds configuration for use during UTXO snapshot load and validation.
const AssumeutxoHash hash_serialized
The expected hash of the deserialized UTXO set.
const unsigned int nChainTx
Used to populate the nChainTx value, which is used during BlockManager::LoadBlockIndex().
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
MapCheckpoints mapCheckpoints
A mutable version of CTransaction.
std::vector< CTxOut > vout
Holds various statistics on transactions within a chain.
double dTxRate
estimated number of transactions per second after that timestamp
int64_t nTime
UNIX timestamp of last known number of transactions.
int64_t nTxCount
total number of transactions between genesis and that timestamp
Parameters that influence chain consensus.
uint32_t nMinerConfirmationWindow
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
int BIP34Height
Block height and hash at which BIP34 becomes active.
int nSubsidyHalvingInterval
int MinBIP9WarningHeight
Don't warn about unknown BIP 9 activations below this height.
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,...
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
indexed_disconnected_transactions queuedTx
void removeForBlock(const std::vector< CTransactionRef > &vtx)
size_t DynamicMemoryUsage() const
void addTransaction(const CTransactionRef &tx)
CBlockIndex * maxInputBlock
Validation result for a single transaction mempool acceptance.
const ResultType m_result_type
static MempoolAcceptResult Success(std::list< CTransactionRef > &&replaced_txns, CAmount fees)
static MempoolAcceptResult Failure(TxValidationState state)
Validation result for package mempool acceptance.
std::shared_ptr< const CBlock > pblock
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
Initialize this PrecomputedTransactionData with transaction data.
bool m_spent_outputs_ready
Whether m_spent_outputs is initialized.
std::vector< CTxOut > m_spent_outputs
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
bool error(const char *fmt, const Args &... args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define LOCKS_EXCLUDED(...)
int64_t GetTimeMicros()
Returns the system time (not mockable)
int64_t GetTimeMillis()
Returns the system time (not mockable)
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
int64_t GetAdjustedTime()
#define LOG_TIME_MILLIS_WITH_CATEGORY(end_msg, log_category)
#define TRACE6(context, event, a, b, c, d, e, f)
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
bool CheckTransaction(const CTransaction &tx, TxValidationState &state)
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
std::pair< int, int64_t > CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Calculates the block height and previous block's median time past at which the transaction will be co...
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, uint32_t flags)
Compute total signature operation cost of a transaction.
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block.
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time.
@ REPLACED
Removed for replacement.
@ REORG
Removed for reorganization.
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0....
CClientUIInterface uiInterface
uint256 uint256S(const char *str)
bool SignalsOptInRBF(const CTransaction &tx)
Check whether the sequence numbers on this transaction are signaling opt-in to replace-by-fee,...
bool RenameOver(fs::path src, fs::path dest)
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
static void UpdateTipLog(const CCoinsViewCache &coins_tip, const CBlockIndex *tip, const CChainParams ¶ms, const std::string &func_name, const std::string &prefix, const std::string &warning_messages) EXCLUSIVE_LOCKS_REQUIRED(
void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
static CSHA256 g_scriptExecutionCacheHasher
void StartScriptCheckWorkerThreads(int threads_num)
Run instances of script checking worker threads.
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
static const uint64_t MEMPOOL_DUMP_VERSION
std::vector< COutPoint > vNoSpendsRemaining
static int64_t nTimeConnectTotal
static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_main)
std::condition_variable g_best_block_cv
static const unsigned int EXTRA_DESCENDANT_TX_SIZE_LIMIT
An extra transaction can be added to a package, as long as it only has one ancestor and is no larger ...
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE
Maximum kilobytes for transactions to store for processing during reorg.
static void AlertNotify(const std::string &strMessage)
std::set< CBlockIndex * > setDirtyBlockIndex
Dirty block index entries.
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
static int64_t nBlocksTotal
bool g_parallel_script_checks
Whether there are dedicated script-checking threads running.
static int64_t nTimePostConnect
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
static SynchronizationState GetSynchronizationState(bool init)
static bool ContextualCheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
NOTE: This function is not currently invoked by ConnectBlock(), so we should consider upgrade issues ...
static int64_t nTimeFlush
void PruneBlockFilesManual(CChainState &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out)
Restore the UTXO in a Coin at a given COutPoint.
std::vector< CBlockFileInfo > vinfoBlockFile
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL
Time to wait between flushing chainstate to disk.
static bool NotifyHeaderTip(CChainState &chainstate) LOCKS_EXCLUDED(cs_main)
static CCheckQueue< CScriptCheck > scriptcheckqueue(128)
bool CheckInputScripts(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData &txdata, std::vector< CScriptCheck > *pvChecks=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Check whether all of this transaction's input scripts succeed.
bool LoadMempool(CTxMemPool &pool, CChainState &active_chainstate, FopenFn mockable_fopen_function)
Load the mempool from disk.
RecursiveMutex cs_LastBlockFile
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
static void AppendWarning(bilingual_str &res, const bilingual_str &warn)
Private helper function that concatenates warning messages.
const AssumeutxoData * ExpectedAssumeutxo(const int height, const CChainParams &chainparams)
Return the expected assumeutxo value for a given height, if one exists.
static bool ContextualCheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, BlockManager &blockman, const CChainParams ¶ms, const CBlockIndex *pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Context-dependent validity checks.
void UnloadBlockIndex(CTxMemPool *mempool, ChainstateManager &chainman)
Unload database information.
void InitScriptExecutionCache()
Initializes the script-execution cache.
static int64_t nTimeVerify
static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams &chainparams, CTxMemPool &pool, CChainState &active_chainstate, const CTransactionRef &tx, int64_t nAcceptTime, bool bypass_limits, bool test_accept) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
(try to) add transaction to memory pool with a specified acceptance time
static bool CheckInputsFromMempoolAndCache(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &view, const CTxMemPool &pool, unsigned int flags, PrecomputedTransactionData &txdata, CCoinsViewCache &coins_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Checks to avoid mempool polluting consensus critical paths since cached signature and script validity...
void StopScriptCheckWorkerThreads()
Stop all of the script checking worker threads.
static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main)
void UpdateUncommittedBlockStructures(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Update uncommitted block structures (currently: only the witness reserved value).
PackageMempoolAcceptResult ProcessNewPackage(CChainState &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept)
Atomically test acceptance of a package.
bool CheckSequenceLocks(CBlockIndex *tip, const CCoinsView &coins_view, const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
Check if transaction will be BIP68 final in the next block to be created on top of tip.
bool TestBlockValidity(BlockValidationState &state, const CChainParams &chainparams, CChainState &chainstate, const CBlock &block, CBlockIndex *pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
Check a block is completely valid from start to finish (only works on top of our current best block)
static int64_t nTimeTotal
bool fCheckForPruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted.
static int64_t nTimeConnect
static void LimitMempoolSize(CTxMemPool &pool, CCoinsViewCache &coins_cache, size_t limit, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(pool.cs
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
bool CheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE
Maximum age of our tip for us to be considered current for fee estimation.
static int64_t nTimeIndex
static unsigned int GetBlockScriptFlags(const CBlockIndex *pindex, const Consensus::Params &chainparams)
static bool IsCurrentForFeeEstimation(CChainState &active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static CuckooCache::cache< uint256, SignatureCacheHasher > g_scriptExecutionCache
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
MempoolAcceptResult AcceptToMemoryPool(CChainState &active_chainstate, CTxMemPool &pool, const CTransactionRef &tx, bool bypass_limits, bool test_accept)
(Try to) add a transaction to the memory pool.
bool AbortNode(BlockValidationState &state, const std::string &strMessage, const bilingual_str &userMessage)
static bool CheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW=true)
bool CheckFinalTx(const CBlockIndex *active_chain_tip, const CTransaction &tx, int flags)
Transaction validation functions.
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
static int64_t nTimeForks
static int64_t nTimeCheck
bool DumpMempool(const CTxMemPool &pool, FopenFn mockable_fopen_function, bool skip_file_commit)
Dump the mempool to disk.
std::set< int > setDirtyFileInfo
Dirty block file entries.
uint256 g_best_block
Used to notify getblocktemplate RPC of new tips.
bool TestLockPointValidity(CChain &active_chain, const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain.
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL
Time to wait between writing blocks/block index to disk.
static int64_t nTimeChainState
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download.
std::vector< unsigned char > GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
static int64_t nTimeReadFromDisk
static void DoWarning(const bilingual_str &warning)
static const bool DEFAULT_CHECKPOINTS_ENABLED
static const unsigned int DEFAULT_DESCENDANT_LIMIT
Default for -limitdescendantcount, max number of in-mempool descendants.
std::function< FILE *(const fs::path &, const char *)> FopenFn
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT
Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants.
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
SynchronizationState
Current sync state passed to tip changed callbacks.
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
static const unsigned int DEFAULT_MEMPOOL_EXPIRY
Default for -mempoolexpiry, expiration time for mempool transactions in hours.
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT
Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors.
@ LARGE
The cache is at >= 90% capacity.
@ CRITICAL
The coins cache is in immediate need of a flush.
static const unsigned int DEFAULT_ANCESTOR_LIMIT
Default for -limitancestorcount, max number of in-mempool ancestors.
static const int64_t DEFAULT_MAX_TIP_AGE
static const bool DEFAULT_PERSIST_MEMPOOL
Default for -persistmempool.
static const int DEFAULT_STOPATHEIGHT
Default for -stopatheight.
CMainSignals & GetMainSignals()
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
static const int PROTOCOL_VERSION
network protocol versioning
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
static const int32_t VERSIONBITS_NUM_BITS
Total bits available for versionbits.
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
void SetfLargeWorkInvalidChainFound(bool flag)
void SetMiscWarning(const bilingual_str &warning)