59 #include <boost/algorithm/string/replace.hpp> 61 #define MICRO 0.000001 79 "level 0 reads the blocks from disk",
80 "level 1 verifies block validity",
81 "level 2 verifies undo data",
82 "level 3 checks disconnection of tip blocks",
83 "level 4 tries to reconnect the blocks",
84 "each level includes the checks of the previous levels",
98 if (pa < pb)
return false;
99 if (pa > pb)
return true;
144 void FlushBlockFile(
bool fFinalize =
false,
bool finalize_undo =
false);
150 BlockMap::const_iterator it = m_block_index.find(hash);
151 return it == m_block_index.end() ? nullptr : it->second;
178 std::vector<CScriptCheck>* pvChecks =
nullptr)
200 const int nBlockHeight = active_chain_tip->nHeight + 1;
208 ? active_chain_tip->GetMedianTimePast()
211 return IsFinalTx(tx, nBlockHeight, nBlockTime);
237 bool useExistingLockPoints)
251 std::pair<int, int64_t> lockPair;
252 if (useExistingLockPoints) {
255 lockPair.second =
lp->
time;
258 std::vector<int> prevheights;
259 prevheights.resize(tx.
vin.size());
260 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
261 const CTxIn& txin = tx.
vin[txinIndex];
264 return error(
"%s: Missing input", __func__);
268 prevheights[txinIndex] = tip->
nHeight + 1;
270 prevheights[txinIndex] = coin.
nHeight;
276 lp->
time = lockPair.second;
290 int maxInputHeight = 0;
291 for (
const int height : prevheights) {
293 if (height != tip->
nHeight+1) {
294 maxInputHeight = std::max(maxInputHeight, height);
309 int expired = pool.Expire(GetTime<std::chrono::seconds>() - age);
317 coins_cache.Uncache(removed);
323 if (active_chainstate.IsInitialBlockDownload())
340 std::vector<uint256> vHashUpdate;
350 if (!fAddToMempool || (*it)->IsCoinBase() ||
358 vHashUpdate.push_back((*it)->GetHash());
400 if (coin.
IsSpent())
return false;
412 const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.
prevout);
427 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),
438 const int64_t m_accept_time;
439 const bool m_bypass_limits;
447 std::vector<COutPoint>& m_coins_to_uncache;
448 const bool m_test_accept;
452 const bool m_allow_bip125_replacement{
true};
469 explicit Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
470 std::set<uint256> m_conflicts;
473 std::unique_ptr<CTxMemPoolEntry> m_entry;
474 std::list<CTransactionRef> m_replaced_transactions;
476 bool m_replacement_transaction;
480 size_t m_conflicting_size;
512 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
531 const size_t m_limit_ancestors;
532 const size_t m_limit_ancestor_size;
535 size_t m_limit_descendants;
536 size_t m_limit_descendant_size;
539 bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
543 const uint256& hash = ws.m_hash;
546 const int64_t nAcceptTime = args.m_accept_time;
547 const bool bypass_limits = args.m_bypass_limits;
548 std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
552 std::set<uint256>& setConflicts = ws.m_conflicts;
555 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
556 bool& fReplacementTransaction = ws.m_replacement_transaction;
557 CAmount& nModifiedFees = ws.m_modified_fees;
558 CAmount& nConflictingFees = ws.m_conflicting_fees;
559 size_t& nConflictingSize = ws.m_conflicting_size;
600 if (ptxConflicting) {
601 if (!args.m_allow_bip125_replacement) {
605 if (!setConflicts.count(ptxConflicting->
GetHash()))
622 bool fReplacementOptOut =
true;
623 for (
const CTxIn &_txin : ptxConflicting->
vin)
627 fReplacementOptOut =
false;
631 if (fReplacementOptOut) {
635 setConflicts.insert(ptxConflicting->
GetHash());
641 m_view.SetBackend(m_viewmempool);
647 coins_to_uncache.push_back(txin.
prevout);
653 if (!m_view.HaveCoin(txin.
prevout)) {
655 for (
size_t out = 0; out < tx.
vout.size(); out++) {
668 m_view.GetBestBlock();
673 m_view.SetBackend(m_dummy);
683 if (!
Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), ws.m_base_fees)) {
700 nModifiedFees = ws.m_base_fees;
701 m_pool.ApplyDelta(hash, nModifiedFees);
705 bool fSpendsCoinbase =
false;
706 for (
const CTxIn &txin : tx.vin) {
707 const Coin &coin = m_view.AccessCoin(txin.
prevout);
709 fSpendsCoinbase =
true;
714 entry.reset(
new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
715 fSpendsCoinbase, nSigOpsCost,
lp));
716 unsigned int nSize = entry->GetTxSize();
724 if (!bypass_limits && !
CheckFeeRate(nSize, nModifiedFees, state))
return false;
728 if (setConflicts.size() == 1) {
756 assert(setIterConflicting.size() == 1);
759 m_limit_descendants += 1;
760 m_limit_descendant_size += conflict->GetSizeWithDescendants();
763 std::string errString;
764 if (!m_pool.CalculateMemPoolAncestors(*entry, setAncestors, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants, m_limit_descendant_size, errString)) {
765 setAncestors.clear();
767 std::string dummy_err_string;
780 !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)) {
791 const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
792 if (setConflicts.count(hashAncestor))
795 strprintf(
"%s spends conflicting transaction %s",
803 nConflictingFees = 0;
804 nConflictingSize = 0;
805 uint64_t nConflictingCount = 0;
810 fReplacementTransaction = setConflicts.size();
811 if (fReplacementTransaction)
813 CFeeRate newFeeRate(nModifiedFees, nSize);
814 std::set<uint256> setConflictsParents;
815 const int maxDescendantsToVisit = 100;
816 for (
const auto& mi : setIterConflicting) {
831 CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
832 if (newFeeRate <= oldFeeRate)
835 strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
837 newFeeRate.ToString(),
838 oldFeeRate.ToString()));
841 for (
const CTxIn &txin : mi->GetTx().vin)
846 nConflictingCount += mi->GetCountWithDescendants();
851 if (nConflictingCount <= maxDescendantsToVisit) {
855 m_pool.CalculateDescendants(it, allConflicting);
858 nConflictingFees += it->GetModifiedFee();
859 nConflictingSize += it->GetTxSize();
863 strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
866 maxDescendantsToVisit));
869 for (
unsigned int j = 0; j < tx.vin.size(); j++)
880 if (!setConflictsParents.count(tx.vin[j].prevout.hash))
885 if (m_pool.exists(tx.vin[j].prevout.hash)) {
887 strprintf(
"replacement %s adds unconfirmed input, idx %d",
896 if (nModifiedFees < nConflictingFees)
899 strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
905 CAmount nDeltaFees = nModifiedFees - nConflictingFees;
909 strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
927 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, txdata)) {
947 const uint256& hash = ws.m_hash;
968 return error(
"%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
975 bool MemPoolAccept::Finalize(
const ATMPArgs& args, Workspace& ws)
978 const uint256& hash = ws.m_hash;
980 const bool bypass_limits = args.m_bypass_limits;
984 const CAmount& nModifiedFees = ws.m_modified_fees;
985 const CAmount& nConflictingFees = ws.m_conflicting_fees;
986 const size_t& nConflictingSize = ws.m_conflicting_size;
987 const bool fReplacementTransaction = ws.m_replacement_transaction;
988 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
994 it->GetTx().GetHash().ToString(),
997 (int)entry->GetTxSize() - (int)nConflictingSize);
998 ws.m_replaced_transactions.push_back(it->GetSharedTx());
1007 bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits &&
IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
1010 m_pool.addUnchecked(*entry, setAncestors, validForFeeEstimation);
1013 if (!bypass_limits) {
1015 if (!m_pool.exists(hash))
1041 if (args.m_test_accept) {
1052 PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(
const std::vector<CTransactionRef>& txns, ATMPArgs& args)
1060 std::vector<Workspace> workspaces{};
1061 workspaces.reserve(txns.size());
1062 std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
1063 [](
const auto& tx) {
return Workspace(tx); });
1064 std::map<const uint256, const MempoolAcceptResult> results;
1069 for (Workspace& ws : workspaces) {
1070 if (!PreChecks(args, ws)) {
1080 assert(!args.m_allow_bip125_replacement);
1081 m_viewmempool.PackageAddTransaction(ws.m_ptx);
1084 for (Workspace& ws : workspaces) {
1086 if (!PolicyScriptChecks(args, ws, txdata)) {
1092 if (args.m_test_accept) {
1095 results.emplace(ws.m_ptx->GetWitnessHash(),
1109 bool bypass_limits,
bool test_accept)
1112 std::vector<COutPoint> coins_to_uncache;
1113 MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache,
1114 test_accept,
true };
1116 const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
1123 for (
const COutPoint& hashTx : coins_to_uncache)
1124 active_chainstate.CoinsTip().Uncache(hashTx);
1133 bool bypass_limits,
bool test_accept)
1139 const Package& package,
bool test_accept)
1143 assert(!package.empty());
1144 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){
return tx !=
nullptr;}));
1146 std::vector<COutPoint> coins_to_uncache;
1148 MemPoolAccept::ATMPArgs args { chainparams,
GetTime(),
false, coins_to_uncache,
1149 test_accept,
false };
1153 for (
const COutPoint& hashTx : coins_to_uncache) {
1166 for (
const auto& tx : block.
vtx) {
1177 if (ptx)
return ptx;
1181 if (
g_txindex->FindTx(hash, hashBlock, tx))
return tx;
1195 nSubsidy >>= halvings;
1200 std::string ldb_name,
1201 size_t cache_size_bytes,
1203 bool should_wipe) : m_dbview(
1204 gArgs.GetDataDirNet() / ldb_name, cache_size_bytes, in_memory, should_wipe),
1205 m_catcherview(&m_dbview) {}
1207 void CoinsViews::InitCache()
1209 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
1213 : m_mempool(mempool),
1215 m_blockman(blockman),
1216 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1219 size_t cache_size_bytes,
1222 std::string leveldb_name)
1229 leveldb_name, cache_size_bytes, in_memory, should_wipe);
1232 void CChainState::InitCoinsCache(
size_t cache_size_bytes)
1261 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1270 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1271 if (strCmd.empty())
return;
1276 std::string singleQuote(
"'");
1278 safeStatus = singleQuote+safeStatus+singleQuote;
1279 boost::replace_all(strCmd,
"%s", safeStatus);
1281 std::thread t(runCommand, strCmd);
1297 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1307 if (!pindexBestInvalid || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
1308 pindexBestInvalid = pindexNew;
1313 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
1318 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
1368 return pindexPrev->
nHeight + 1;
1387 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1388 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1413 std::vector<CScriptCheck>* pvChecks)
1418 pvChecks->reserve(tx.
vin.size());
1435 std::vector<CTxOut> spent_outputs;
1436 spent_outputs.reserve(tx.
vin.size());
1438 for (
const auto& txin : tx.
vin) {
1442 spent_outputs.emplace_back(coin.
out);
1444 txdata.
Init(tx, std::move(spent_outputs));
1448 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1460 check.
swap(pvChecks->back());
1461 }
else if (!check()) {
1489 if (cacheFullScriptStore && !pvChecks) {
1501 return state.
Error(strMessage);
1515 if (view.
HaveCoin(out)) fClean =
false;
1517 if (undo.nHeight == 0) {
1523 undo.nHeight = alternate.
nHeight;
1534 view.
AddCoin(out, std::move(undo), !fClean);
1547 error(
"DisconnectBlock(): failure reading undo data");
1551 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1552 error(
"DisconnectBlock(): block and undo data inconsistent");
1557 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1564 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1565 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1568 bool is_spent = view.
SpendCoin(out, &coin);
1579 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1582 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1727 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
1729 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
1746 bool fScriptChecks =
true;
1755 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
1792 bool fEnforceBIP30 = !((pindex->
nHeight==91842 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
1793 (pindex->
nHeight==91880 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
1821 static constexpr
int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
1859 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
1860 for (
const auto& tx : block.
vtx) {
1861 for (
size_t o = 0; o < tx->
vout.size(); o++) {
1863 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
1871 int nLockTimeFlags = 0;
1890 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
1892 std::vector<int> prevheights;
1895 int64_t nSigOpsCost = 0;
1896 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
1897 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
1901 nInputs += tx.
vin.size();
1915 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n", __func__);
1922 prevheights.resize(tx.
vin.size());
1923 for (
size_t j = 0; j < tx.
vin.size(); j++) {
1927 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
1928 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
1939 LogPrintf(
"ERROR: ConnectBlock(): too many sigops\n");
1945 std::vector<CScriptCheck> vChecks;
1946 bool fCacheResults = fJustCheck;
1952 return error(
"ConnectBlock(): CheckInputScripts on %s failed with %s",
1955 control.
Add(vChecks);
1968 if (block.
vtx[0]->GetValueOut() > blockReward) {
1969 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.
vtx[0]->GetValueOut(), blockReward);
1973 if (!control.
Wait()) {
1974 LogPrintf(
"ERROR: %s: CheckQueue failed\n", __func__);
2007 return this->GetCoinsCacheSizeState(
2013 size_t max_coins_cache_size_bytes,
2014 size_t max_mempool_size_bytes)
2018 int64_t nTotalSpace =
2019 max_coins_cache_size_bytes + std::max<int64_t>(max_mempool_size_bytes - nMempoolUsage, 0);
2022 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
2023 int64_t large_threshold =
2024 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2026 if (cacheSize > nTotalSpace) {
2027 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
2029 }
else if (cacheSize > large_threshold) {
2038 int nManualPruneHeight)
2041 assert(this->CanFlushToDisk());
2042 static std::chrono::microseconds nLastWrite{0};
2043 static std::chrono::microseconds nLastFlush{0};
2044 std::set<int> setFilesToPrune;
2045 bool full_flush_completed =
false;
2052 bool fFlushForPrune =
false;
2053 bool fDoFullFlush =
false;
2065 if (nManualPruneHeight > 0) {
2075 if (!setFilesToPrune.empty()) {
2076 fFlushForPrune =
true;
2078 pblocktree->WriteFlag(
"prunedblockfiles",
true);
2083 const auto nNow = GetTime<std::chrono::microseconds>();
2085 if (nLastWrite.count() == 0) {
2088 if (nLastFlush.count() == 0) {
2100 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2102 if (fDoFullFlush || fPeriodicWrite) {
2105 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2118 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2124 std::vector<const CBlockIndex*> vBlocks;
2127 vBlocks.push_back(*it);
2131 return AbortNode(state,
"Failed to write to block index database");
2135 if (fFlushForPrune) {
2143 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2145 coins_count, coins_mem_usage / 1000));
2153 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2157 return AbortNode(state,
"Failed to write to coin database");
2159 full_flush_completed =
true;
2162 if (full_flush_completed) {
2166 }
catch (
const std::runtime_error& e) {
2167 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2191 static bool fWarned =
false;
2206 void CChainState::UpdateTip(
const CBlockIndex* pindexNew)
2235 LogPrintf(
"%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__,
2261 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2264 return error(
"DisconnectTip(): Failed to read block");
2273 bool flushed = view.
Flush();
2284 for (
auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
2297 UpdateTip(pindexDelete->
pprev);
2364 std::shared_ptr<const CBlock> pthisBlock;
2366 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2368 return AbortNode(state,
"Failed to read block");
2370 pthisBlock = pblockNew;
2372 pthisBlock = pblock;
2374 const CBlock& blockConnecting = *pthisBlock;
2381 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view);
2391 bool flushed = view.
Flush();
2409 UpdateTip(pindexNew);
2438 bool fInvalidAncestor =
false;
2448 if (fFailedChain || fMissingData) {
2450 if (fFailedChain && (pindexBestInvalid ==
nullptr || pindexNew->
nChainWork > pindexBestInvalid->nChainWork))
2451 pindexBestInvalid = pindexNew;
2454 while (pindexTest != pindexFailed) {
2457 }
else if (fMissingData) {
2462 std::make_pair(pindexFailed->
pprev, pindexFailed));
2465 pindexFailed = pindexFailed->
pprev;
2468 fInvalidAncestor =
true;
2471 pindexTest = pindexTest->
pprev;
2473 if (!fInvalidAncestor)
2505 bool fBlocksDisconnected =
false;
2516 AbortNode(state,
"Failed to disconnect block; see debug.log for details");
2519 fBlocksDisconnected =
true;
2523 std::vector<CBlockIndex*> vpindexToConnect;
2524 bool fContinue =
true;
2529 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
2530 vpindexToConnect.clear();
2531 vpindexToConnect.reserve(nTargetHeight -
nHeight);
2534 vpindexToConnect.push_back(pindexIter);
2535 pindexIter = pindexIter->
pprev;
2541 if (!
ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2548 fInvalidFound =
true;
2569 if (fBlocksDisconnected) {
2589 bool fNotify =
false;
2590 bool fInitialBlockDownload =
false;
2597 if (pindexHeader != pindexHeaderOld) {
2599 fInitialBlockDownload = chainstate.IsInitialBlockDownload();
2600 pindexHeaderOld = pindexHeader;
2649 bool blocks_connected =
false;
2655 if (pindexMostWork ==
nullptr) {
2660 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
2664 bool fInvalidFound =
false;
2665 std::shared_ptr<const CBlock> nullBlockPtr;
2666 if (!
ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
2670 blocks_connected =
true;
2672 if (fInvalidFound) {
2674 pindexMostWork =
nullptr;
2679 assert(trace.pblock && trace.pindex);
2683 if (!blocks_connected)
return true;
2690 if (pindexFork != pindexNewTip) {
2707 }
while (pindexNewTip != pindexMostWork);
2751 if (pindex->
nHeight == 0)
return false;
2754 bool pindex_was_in_chain =
false;
2755 int disconnected = 0;
2769 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
2773 for (
const auto& entry :
m_blockman.m_block_index) {
2784 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
2801 pindex_was_in_chain =
true;
2814 if (!ret)
return false;
2834 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
2835 while (candidate_it != candidate_blocks_by_work.end()) {
2838 candidate_it = candidate_blocks_by_work.erase(candidate_it);
2846 to_mark_failed = invalid_walk_tip;
2871 BlockMap::iterator it =
m_blockman.m_block_index.begin();
2872 while (it !=
m_blockman.m_block_index.end()) {
2883 if (pindex_was_in_chain) {
2895 BlockMap::iterator it =
m_blockman.m_block_index.begin();
2896 while (it !=
m_blockman.m_block_index.end()) {
2897 if (!it->second->IsValid() && it->second->GetAncestor(
nHeight) == pindex) {
2903 if (it->second == pindexBestInvalid) {
2905 pindexBestInvalid =
nullptr;
2913 while (pindex !=
nullptr) {
2919 pindex = pindex->
pprev;
2929 BlockMap::iterator it = m_block_index.find(hash);
2930 if (it != m_block_index.end())
2939 BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
2941 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
2942 if (miPrev != m_block_index.end())
2944 pindexNew->
pprev = (*miPrev).second;
2962 pindexNew->
nTx = block.
vtx.size();
2976 std::deque<CBlockIndex*> queue;
2977 queue.push_back(pindexNew);
2980 while (!queue.empty()) {
2991 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
2992 while (range.first != range.second) {
2993 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
2994 queue.push_back(it->second);
3001 m_blockman.m_blocks_unlinked.insert(std::make_pair(pindexNew->
pprev, pindexNew));
3033 if (fCheckMerkleRoot) {
3057 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3059 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3060 if (block.
vtx[i]->IsCoinBase())
3065 for (
const auto& tx : block.
vtx) {
3075 unsigned int nSigOps = 0;
3076 for (
const auto& tx : block.
vtx)
3083 if (fCheckPOW && fCheckMerkleRoot)
3092 static const std::vector<unsigned char> nonce(32, 0x00);
3095 tx.
vin[0].scriptWitness.stack.resize(1);
3096 tx.
vin[0].scriptWitness.stack[0] = nonce;
3103 std::vector<unsigned char> commitment;
3105 std::vector<unsigned char> ret(32, 0x00);
3122 tx.vout.push_back(out);
3134 for (
const MapCheckpoints::value_type& i :
reverse_iterate(checkpoints))
3136 const uint256& hash = i.second;
3156 assert(pindexPrev !=
nullptr);
3157 const int nHeight = pindexPrev->nHeight + 1;
3169 CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
3170 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
3171 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
3177 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
3189 strprintf(
"rejected nVersion=0x%08x block", block.nVersion));
3203 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3206 int nLockTimeFlags = 0;
3208 assert(pindexPrev !=
nullptr);
3217 for (
const auto& tx : block.
vtx) {
3227 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3228 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3241 bool fHaveWitness =
false;
3245 bool malleated =
false;
3250 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3254 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3257 fHaveWitness =
true;
3262 if (!fHaveWitness) {
3263 for (
const auto& tx : block.
vtx) {
3288 BlockMap::iterator miSelf = m_block_index.find(hash);
3290 if (miSelf != m_block_index.end()) {
3296 LogPrintf(
"ERROR: %s: block %s is marked invalid\n", __func__, hash.
ToString());
3309 BlockMap::iterator mi = m_block_index.find(block.
hashPrevBlock);
3310 if (mi == m_block_index.end()) {
3311 LogPrintf(
"ERROR: %s: prev block not found\n", __func__);
3314 pindexPrev = (*mi).second;
3316 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
3320 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.
ToString(), state.
ToString());
3347 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
3350 while (invalid_walk != failedit) {
3353 invalid_walk = invalid_walk->
pprev;
3355 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
3377 bool accepted = m_blockman.AcceptBlockHeader(
3378 header, state, chainparams, &pindex);
3400 const CBlock& block = *pblock;
3402 if (fNewBlock) *fNewBlock =
false;
3406 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3411 if (!accepted_header)
3433 if (fAlreadyHave)
return true;
3435 if (pindex->
nTx != 0)
return true;
3436 if (!fHasMoreOrSameWork)
return true;
3437 if (fTooFarAhead)
return true;
3461 if (fNewBlock) *fNewBlock =
true;
3465 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3469 }
catch (
const std::runtime_error& e) {
3470 return AbortNode(state, std::string(
"System error: ") + e.what());
3486 if (new_block) *new_block =
false;
3505 return error(
"%s: AcceptBlock FAILED (%s)", __func__, state.
ToString());
3513 return error(
"%s: ActivateBestChain failed (%s)", __func__, state.
ToString());
3525 bool fCheckMerkleRoot)
3532 indexDummy.pprev = pindexPrev;
3534 indexDummy.phashBlock = &block_hash;
3538 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.
ToString());
3540 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
3542 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__, state.
ToString());
3543 if (!chainstate.
ConnectBlock(block, state, &indexDummy, viewNew,
true)) {
3560 for (
const auto& entry : m_block_index) {
3562 if (pindex->
nFile == fileNumber) {
3575 while (range.first != range.second) {
3576 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
3578 if (_it->second == pindex) {
3594 if (chain_tip_height < 0) {
3599 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight, chain_tip_height -
MIN_BLOCKS_TO_KEEP);
3601 for (
int fileNumber = 0; fileNumber <
nLastBlockFile; fileNumber++) {
3606 setFilesToPrune.insert(fileNumber);
3609 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune,
count);
3628 if ((uint64_t)chain_tip_height <= nPruneAfterHeight) {
3632 unsigned int nLastBlockWeCanPrune = std::min(prune_height, chain_tip_height - static_cast<int>(
MIN_BLOCKS_TO_KEEP));
3638 uint64_t nBytesToPrune;
3651 for (
int fileNumber = 0; fileNumber <
nLastBlockFile; fileNumber++) {
3663 if (
vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
3669 setFilesToPrune.insert(fileNumber);
3670 nCurrentUsage -= nBytesToPrune;
3675 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
3677 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
3678 nLastBlockWeCanPrune,
count);
3689 BlockMap::iterator mi = m_block_index.find(hash);
3690 if (mi != m_block_index.end())
3691 return (*mi).second;
3695 mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
3704 std::set<CBlockIndex*, CBlockIndexWorkComparator>& block_index_candidates)
3710 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
3711 vSortedByHeight.reserve(m_block_index.size());
3712 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index)
3715 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
3717 sort(vSortedByHeight.begin(), vSortedByHeight.end());
3718 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
3726 if (pindex->
nTx > 0) {
3727 if (pindex->
pprev) {
3743 block_index_candidates.insert(pindex);
3746 pindexBestInvalid = pindex;
3760 for (
const BlockMap::value_type& entry : m_block_index) {
3761 delete entry.second;
3764 m_block_index.clear();
3785 if (
pblocktree->ReadBlockFileInfo(nFile, info)) {
3793 LogPrintf(
"Checking all blk files are present...\n");
3794 std::set<int> setBlkDataFiles;
3795 for (
const std::pair<const uint256, CBlockIndex*>& item :
m_blockman.m_block_index) {
3798 setBlkDataFiles.insert(pindex->
nFile);
3801 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
3812 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
3815 bool fReindexing =
false;
3838 if (tip && tip->GetBlockHash() == coins_cache.
GetBestBlock()) {
3851 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
3852 tip->GetBlockHash().ToString(),
3861 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, 0,
false);
3873 int nCheckLevel,
int nCheckDepth)
3881 if (nCheckDepth <= 0 || nCheckDepth > chainstate.
m_chain.
Height())
3883 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3884 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
3888 int nGoodTransactions = 0;
3896 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
3897 if (reportDone < percentageDone/10) {
3900 reportDone = percentageDone/10;
3902 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
3908 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
3917 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
3920 if (nCheckLevel >= 2 && pindex) {
3938 nGoodTransactions = 0;
3939 pindexFailure = pindex;
3941 nGoodTransactions += block.
vtx.size();
3947 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.
m_chain.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
3953 if (nCheckLevel >= 4) {
3955 const int percentageDone = std::max(1, std::min(99, 100 - (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (double)nCheckDepth * 50)));
3956 if (reportDone < percentageDone/10) {
3959 reportDone = percentageDone/10;
3961 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
3966 if (!chainstate.
ConnectBlock(block, state, pindex, coins)) {
3974 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
3989 if (!tx->IsCoinBase()) {
3990 for (
const CTxIn &txin : tx->vin) {
4008 if (hashHeads.empty())
return true;
4009 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4011 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, 0,
false);
4018 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
4019 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4021 pindexNew =
m_blockman.m_block_index[hashHeads[0]];
4023 if (!hashHeads[1].IsNull()) {
4024 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
4025 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4027 pindexOld =
m_blockman.m_block_index[hashHeads[1]];
4029 assert(pindexFork !=
nullptr);
4033 while (pindexOld != pindexFork) {
4049 pindexOld = pindexOld->
pprev;
4053 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4057 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, (
int) ((
nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
4079 block = block->
pprev;
4097 pindexBestInvalid =
nullptr;
4099 if (mempool) mempool->
clear();
4106 warningcache[b].clear();
4118 if (!ret)
return false;
4119 needs_init = m_blockman.m_block_index.empty();
4129 LogPrintf(
"Initializing databases...\n");
4149 return error(
"%s: writing genesis block to disk failed", __func__);
4152 }
catch (
const std::runtime_error& e) {
4153 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4159 void CChainState::LoadExternalBlockFile(FILE* fileIn,
FlatFilePos* dbp)
4162 static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
4169 uint64_t nRewind = blkdat.GetPos();
4170 while (!blkdat.eof()) {
4173 blkdat.SetPos(nRewind);
4176 unsigned int nSize = 0;
4181 nRewind = blkdat.GetPos()+1;
4190 }
catch (
const std::exception&) {
4196 uint64_t nBlockPos = blkdat.GetPos();
4198 dbp->
nPos = nBlockPos;
4199 blkdat.SetLimit(nBlockPos + nSize);
4200 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4203 nRewind = blkdat.GetPos();
4205 uint256 hash = block.GetHash();
4211 block.hashPrevBlock.ToString());
4213 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
4221 if (
AcceptBlock(pblock, state,
nullptr,
true, dbp,
nullptr)) {
4243 std::deque<uint256> queue;
4244 queue.push_back(hash);
4245 while (!queue.empty()) {
4248 std::pair<std::multimap<uint256, FlatFilePos>::iterator, std::multimap<uint256, FlatFilePos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
4249 while (range.first != range.second) {
4250 std::multimap<uint256, FlatFilePos>::iterator it = range.first;
4251 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4253 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4257 if (
AcceptBlock(pblockrecursive, dummy,
nullptr,
true, &it->second,
nullptr)) {
4259 queue.push_back(pblockrecursive->GetHash());
4263 mapBlocksUnknownParent.erase(it);
4267 }
catch (
const std::exception& e) {
4268 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
4271 }
catch (
const std::runtime_error& e) {
4272 AbortNode(std::string(
"System error: ") + e.what());
4294 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4295 for (
const std::pair<const uint256, CBlockIndex*>& entry :
m_blockman.m_block_index) {
4296 forward.insert(std::make_pair(entry.second->pprev, entry.second));
4301 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4303 rangeGenesis.first++;
4304 assert(rangeGenesis.first == rangeGenesis.second);
4315 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4317 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4318 while (pindex !=
nullptr) {
4322 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4329 if (pindex->
pprev ==
nullptr) {
4340 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4353 assert(pindexFirstNotTreeValid ==
nullptr);
4357 if (pindexFirstInvalid ==
nullptr) {
4362 if (pindexFirstInvalid ==
nullptr) {
4367 if (pindexFirstMissing ==
nullptr || pindex ==
m_chain.
Tip()) {
4378 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
m_blockman.
m_blocks_unlinked.equal_range(pindex->
pprev);
4379 bool foundInUnlinked =
false;
4380 while (rangeUnlinked.first != rangeUnlinked.second) {
4381 assert(rangeUnlinked.first->first == pindex->
pprev);
4382 if (rangeUnlinked.first->second == pindex) {
4383 foundInUnlinked =
true;
4386 rangeUnlinked.first++;
4388 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4393 if (pindexFirstMissing ==
nullptr)
assert(!foundInUnlinked);
4394 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4406 if (pindexFirstInvalid ==
nullptr) {
4415 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4416 if (range.first != range.second) {
4418 pindex = range.first->second;
4427 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4428 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4429 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4430 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4431 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4432 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4433 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4437 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4438 while (rangePar.first->second != pindex) {
4439 assert(rangePar.first != rangePar.second);
4444 if (rangePar.first != rangePar.second) {
4446 pindex = rangePar.first->second;
4458 assert(nNodes == forward.size());
4464 return strprintf(
"Chainstate [%s] @ height %d (%s)",
4469 bool CChainState::ResizeCoinsCaches(
size_t coinstip_size,
size_t coinsdb_size)
4481 LogPrintf(
"[%s] resized coinsdb cache to %.1f MiB\n",
4482 this->
ToString(), coinsdb_size * (1.0 / 1024 / 1024));
4483 LogPrintf(
"[%s] resized coinstip cache to %.1f MiB\n",
4484 this->
ToString(), coinstip_size * (1.0 / 1024 / 1024));
4489 if (coinstip_size > old_coinstip_size) {
4509 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
4514 int64_t expired = 0;
4516 int64_t already_there = 0;
4517 int64_t unbroadcast = 0;
4536 CAmount amountdelta = nFeeDelta;
4540 if (nTime > nNow - nExpiryTimeout) {
4550 if (pool.
exists(tx->GetHash())) {
4562 std::map<uint256, CAmount> mapDeltas;
4565 for (
const auto& i : mapDeltas) {
4569 std::set<uint256> unbroadcast_txids;
4570 file >> unbroadcast_txids;
4571 unbroadcast = unbroadcast_txids.size();
4572 for (
const auto& txid : unbroadcast_txids) {
4577 }
catch (
const std::exception& e) {
4578 LogPrintf(
"Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
4582 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);
4590 std::map<uint256, CAmount> mapDeltas;
4591 std::vector<TxMempoolInfo> vinfo;
4592 std::set<uint256> unbroadcast_txids;
4594 static Mutex dump_mutex;
4599 for (
const auto &i : pool.mapDeltas) {
4600 mapDeltas[i.first] = i.second;
4609 FILE* filestr{mockable_fopen_function(
gArgs.
GetDataDirNet() /
"mempool.dat.new",
"wb")};
4619 file << (uint64_t)vinfo.size();
4620 for (
const auto& i : vinfo) {
4623 file << int64_t{i.nFeeDelta};
4624 mapDeltas.erase(i.tx->GetHash());
4629 LogPrintf(
"Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
4630 file << unbroadcast_txids;
4633 throw std::runtime_error(
"FileCommit failed");
4636 throw std::runtime_error(
"Rename failed");
4639 LogPrintf(
"Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*
MICRO, (last-mid)*
MICRO);
4640 }
catch (
const std::exception& e) {
4641 LogPrintf(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
4650 if (pindex ==
nullptr)
4653 int64_t nNow = time(
nullptr);
4663 return std::min<double>(pindex->
nChainTx / fTxTotal, 1.0);
4669 if (m_active_chainstate && m_active_chainstate->m_from_snapshot_blockhash) {
4671 return m_active_chainstate->m_from_snapshot_blockhash;
4673 return std::nullopt;
4679 std::vector<CChainState*> out;
4682 out.push_back(m_ibd_chainstate.get());
4685 if (m_snapshot_chainstate) {
4686 out.push_back(m_snapshot_chainstate.get());
4692 CChainState& ChainstateManager::InitializeChainstate(
4693 CTxMemPool* mempool,
const std::optional<uint256>& snapshot_blockhash)
4695 bool is_snapshot = snapshot_blockhash.has_value();
4696 std::unique_ptr<CChainState>& to_modify =
4697 is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
4700 throw std::logic_error(
"should not be overwriting a chainstate");
4702 to_modify.reset(
new CChainState(mempool, m_blockman, snapshot_blockhash));
4705 if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
4706 LogPrintf(
"Switching active chainstate to %s\n", to_modify->ToString());
4707 m_active_chainstate = to_modify.get();
4709 throw std::logic_error(
"unexpected chainstate activation");
4719 const auto assumeutxo_found = valid_assumeutxos_map.find(height);
4721 if (assumeutxo_found != valid_assumeutxos_map.end()) {
4722 return &assumeutxo_found->second;
4735 LogPrintf(
"[snapshot] can't activate a snapshot-based chainstate more than once\n");
4739 int64_t current_coinsdb_cache_size{0};
4740 int64_t current_coinstip_cache_size{0};
4748 static constexpr
double IBD_CACHE_PERC = 0.01;
4749 static constexpr
double SNAPSHOT_CACHE_PERC = 0.99;
4767 static_cast<size_t>(current_coinstip_cache_size * IBD_CACHE_PERC),
4768 static_cast<size_t>(current_coinsdb_cache_size * IBD_CACHE_PERC));
4771 auto snapshot_chainstate =
WITH_LOCK(::
cs_main,
return std::make_unique<CChainState>(
4772 nullptr, m_blockman, base_blockhash));
4776 snapshot_chainstate->InitCoinsDB(
4777 static_cast<size_t>(current_coinsdb_cache_size * SNAPSHOT_CACHE_PERC),
4778 in_memory,
false,
"chainstate");
4779 snapshot_chainstate->InitCoinsCache(
4780 static_cast<size_t>(current_coinstip_cache_size * SNAPSHOT_CACHE_PERC));
4784 *snapshot_chainstate, coins_file, metadata);
4793 assert(!m_snapshot_chainstate);
4794 m_snapshot_chainstate.swap(snapshot_chainstate);
4795 const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip();
4798 m_active_chainstate = m_snapshot_chainstate.get();
4800 LogPrintf(
"[snapshot] successfully activated snapshot %s\n", base_blockhash.
ToString());
4802 m_snapshot_chainstate->CoinsTip().DynamicMemoryUsage() / (1000 * 1000));
4804 this->MaybeRebalanceCaches();
4822 if (!snapshot_start_block) {
4824 LogPrintf(
"[snapshot] Did not find snapshot start blockheader %s\n",
4825 base_blockhash.ToString());
4829 int base_height = snapshot_start_block->
nHeight;
4832 if (!maybe_au_data) {
4833 LogPrintf(
"[snapshot] assumeutxo height in snapshot metadata not recognized " 4834 "(%d) - refusing to load snapshot\n", base_height);
4845 LogPrintf(
"[snapshot] loading coins from snapshot %s\n", base_blockhash.ToString());
4846 int64_t flush_now{0};
4847 int64_t coins_processed{0};
4849 while (coins_left > 0) {
4851 coins_file >> outpoint;
4853 }
catch (
const std::ios_base::failure&) {
4854 LogPrintf(
"[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n",
4855 coins_count - coins_left);
4858 if (coin.
nHeight > base_height ||
4859 outpoint.
n >= std::numeric_limits<decltype(outpoint.
n)>::max()
4861 LogPrintf(
"[snapshot] bad snapshot data after deserializing %d coins\n",
4862 coins_count - coins_left);
4871 if (coins_processed % 1000000 == 0) {
4872 LogPrintf(
"[snapshot] %d coins loaded (%.2f%%, %.2f MB)\n",
4874 static_cast<float>(coins_processed) * 100 / static_cast<float>(coins_count),
4882 if (coins_processed % 120000 == 0) {
4888 return snapshot_chainstate.GetCoinsCacheSizeState());
4890 if (snapshot_cache_state >=
4892 LogPrintf(
"[snapshot] flushing coins cache (%.2f MB)... ",
4901 coins_cache.
Flush();
4914 bool out_of_coins{
false};
4916 coins_file >> outpoint;
4917 }
catch (
const std::ios_base::failure&) {
4919 out_of_coins =
true;
4921 if (!out_of_coins) {
4922 LogPrintf(
"[snapshot] bad snapshot - coins left over after deserializing %d coins\n",
4927 LogPrintf(
"[snapshot] loaded %d (%.2f MB) coins from snapshot %s\n",
4930 base_blockhash.ToString());
4932 LogPrintf(
"[snapshot] flushing snapshot chainstate to disk\n");
4934 coins_cache.
Flush();
4939 auto breakpoint_fnc = [] { };
4946 LogPrintf(
"[snapshot] failed to generate coins stats\n");
4952 LogPrintf(
"[snapshot] bad snapshot content hash: expected %s, got %s\n",
4964 for (
int i = 0; i <= snapshot_chainstate.
m_chain.
Height(); ++i) {
4965 index = snapshot_chainstate.
m_chain[i];
4986 LogPrintf(
"[snapshot] validated snapshot (%.2f MB)\n",
4994 assert(m_active_chainstate);
4995 return *m_active_chainstate;
5001 return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get();
5008 return *m_snapshot_chainstate.get();
5010 assert(m_ibd_chainstate);
5011 return *m_ibd_chainstate.get();
5017 return (m_snapshot_chainstate && chainstate == m_ibd_chainstate.get());
5020 void ChainstateManager::Unload()
5023 chainstate->m_chain.SetTip(
nullptr);
5024 chainstate->UnloadBlockIndex();
5027 m_blockman.Unload();
5030 void ChainstateManager::Reset()
5033 m_ibd_chainstate.reset();
5034 m_snapshot_chainstate.reset();
5035 m_active_chainstate =
nullptr;
5039 void ChainstateManager::MaybeRebalanceCaches()
5041 if (m_ibd_chainstate && !m_snapshot_chainstate) {
5042 LogPrintf(
"[snapshot] allocating all cache to the IBD chainstate\n");
5046 else if (m_snapshot_chainstate && !m_ibd_chainstate) {
5047 LogPrintf(
"[snapshot] allocating all cache to the snapshot chainstate\n");
5051 else if (m_ibd_chainstate && m_snapshot_chainstate) {
5055 if (m_snapshot_chainstate->IsInitialBlockDownload()) {
5056 m_ibd_chainstate->ResizeCoinsCaches(
5058 m_snapshot_chainstate->ResizeCoinsCaches(
5061 m_snapshot_chainstate->ResizeCoinsCaches(
5063 m_ibd_chainstate->ResizeCoinsCaches(
std::shared_ptr< const CTransaction > CTransactionRef
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
static bool IsCurrentForFeeEstimation(CChainState &active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool fCheckForPruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted...
CSHA256 & Write(const unsigned char *data, size_t len)
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT
Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors.
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
bool IsSpent() const
Either this coin never existed (see e.g.
bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
std::vector< Coin > vprevout
int64_t EndTime(const Consensus::Params ¶ms) const override
static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE
Maximum age of our tip for us to be considered current for fee estimation.
void resize(size_type new_size)
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
int GetSpendHeight(const CCoinsViewCache &inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the spend height, which is one more than the inputs.GetBestBlock().
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...
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...
invalid by consensus rules
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...
static const unsigned int DEFAULT_DESCENDANT_LIMIT
Default for -limitdescendantcount, max number of in-mempool descendants.
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
bool LoadBlockIndex(const Consensus::Params &consensus_params, CBlockTreeDB &blocktree, std::set< CBlockIndex *, CBlockIndexWorkComparator > &block_index_candidates) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
const unsigned int nChainTx
Used to populate the nChainTx value, which is used during BlockManager::LoadBlockIndex().
std::condition_variable g_best_block_cv
static const uint32_t MAX_BIP125_RBF_SEQUENCE
bool IsBackgroundIBD(CChainState *chainstate) const
bool Error(const std::string &reject_reason)
SynchronizationState
Current sync state passed to tip changed callbacks.
static const int WITNESS_SCALE_FACTOR
void Finalize(Span< unsigned char > output)
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
std::string GetDebugMessage() const
CChain m_chain
The current chain of blockheaders we consult and build on.
CChainState & ValidatedChainstate() const
Return the most-work chainstate that has been fully validated.
void PruneBlockIndexCandidates()
Delete all entries in setBlockIndexCandidates that are worse than the current tip.
#define LogPrint(category,...)
void Add(std::vector< T > &vChecks)
int64_t GetBlockTime() const
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
int Threshold(const Consensus::Params ¶ms) const override
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
double dTxRate
estimated number of transactions per second after that timestamp
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
descends from failed block
CBlockIndex * pprev
pointer to the index of the predecessor of this block
std::vector< TxMempoolInfo > infoAll() const
uint32_t nStatus
Verification status of this block.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
bool Flush()
Push the modifications applied to this cache to its base.
std::map< int, uint256 > MapCheckpoints
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 int64_t nTimeConnectTotal
void BlockDisconnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void swap(CScriptCheck &check)
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
bool exists(const GenTxid >xid) const
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 ...
We don't have the previous block the checked one is built on.
int64_t GetTimeMillis()
Returns the system time (not mockable)
int64_t BeginTime(const Consensus::Params ¶ms) const override
The cache is at >= 90% capacity.
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
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...
static const uint64_t MEMPOOL_DUMP_VERSION
An in-memory indexed chain of blocks.
static void AlertNotify(const std::string &strMessage)
CBlockIndex * GetLastCheckpoint(const CCheckpointData &data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Returns last CBlockIndex* that is a checkpoint.
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 ...
size_t DynamicMemoryUsage() const
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
const MapAssumeutxo & Assumeutxo() const
Get allowed assumeutxo configuration.
reverse_range< T > reverse_iterate(T &x)
void SetMiscWarning(const bilingual_str &warning)
static const int64_t DEFAULT_MAX_TIP_AGE
void CheckBlockIndex()
Make various assertions about the state of the block index.
uint256 GetRandHash() noexcept
int Period(const Consensus::Params ¶ms) const override
invalid proof of work or time too old
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
std::function< FILE *(const fs::path &, const char *)> FopenFn
static const CAmount COIN
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 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...
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ::ChainActive().Tip() will not be pruned.
static const unsigned int DEFAULT_ANCESTOR_LIMIT
Default for -limitancestorcount, max number of in-mempool ancestors.
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...
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
transaction was missing some of its inputs
static CSHA256 g_scriptExecutionCacheHasher
static int64_t nTimeForks
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool MoneyRange(const CAmount &nValue)
int Height() const
Return the maximal height in the chain.
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
void ForEachBlockFilterIndex(std::function< void(BlockFilterIndex &)> fn)
Iterate over all running block filter indexes, invoking fn on each.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
CTxOut out
unspent transaction output
cache implements a cache with properties similar to a cuckoo-set.
stage after last reached validness failed
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
unsigned int fCoinBase
whether containing transaction was a coinbase
The coins cache is in immediate need of a flush.
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
#define LOG_TIME_SECONDS(end_msg)
CChainState stores and provides an API to update our local knowledge of the current best chain...
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
void ReallocateCache()
Force a reallocation of the cache map.
std::vector< CTxOut > m_spent_outputs
std::set< txiter, CompareIteratorByHash > setEntries
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.
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS
For convenience, standard but not mandatory verify flags.
void addTransaction(const CTransactionRef &tx)
bool PreciousBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as precious and reorganize.
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
static MempoolAcceptResult Success(std::list< CTransactionRef > &&replaced_txns, CAmount fees)
const CBlock & GenesisBlock() const
void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out)
Restore the UTXO in a Coin at a given COutPoint.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
violated mempool's fee/size/descendant/RBF/etc limits
inputs (covered by txid) failed policy rules
undo data available in rev*.dat
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
const ResultType m_result_type
int nFile
Which # file this block is stored in (blk?????.dat)
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
CBlockIndex * LookupBlockIndex(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static bool NotifyHeaderTip(CChainState &chainstate) LOCKS_EXCLUDED(cs_main)
transaction spends a coinbase too early, or violates locktime/sequence locks
std::set< int > setDirtyFileInfo
Dirty block file entries.
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction. ...
bool CheckPackage(const Package &txns, PackageValidationState &state)
Context-free package policy checks:
std::atomic< bool > m_cached_finished_ibd
Whether this chainstate is undergoing initial block download.
bool DisconnectTip(BlockValidationState &state, DisconnectedBlockTransactions *disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Disconnect m_chain's tip.
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
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.
int64_t nTime
UNIX timestamp of last known number of transactions.
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule) ...
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
void removeForReorg(CChainState &active_chainstate, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
const std::vector< CTxIn > vin
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
bool IsWitnessStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check if the transaction is over standard P2WSH resources limit: 3600bytes witnessScript size...
void StartScriptCheckWorkerThreads(int threads_num)
Run instances of script checking worker threads.
size_t GetSerializeSize(const T &t, int nVersion=0)
void TransactionAddedToMempool(const CTransactionRef &, uint64_t mempool_sequence)
std::vector< COutPoint > vNoSpendsRemaining
void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
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.
int nSubsidyHalvingInterval
bool DeploymentEnabled(const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is enabled (can ever be active)
void LoadMempool(const ArgsManager &args)
Load the persisted mempool from disk.
const std::optional< uint256 > m_from_snapshot_blockhash
The blockhash which is the base of the snapshot this chainstate was created from. ...
int64_t nTxCount
total number of transactions between genesis and that timestamp
int64_t CAmount
Amount in satoshis (Can be negative)
void SetBestBlock(const uint256 &hashBlock)
static void LimitMempoolSize(CTxMemPool &pool, CCoinsViewCache &coins_cache, size_t limit, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(pool.cs
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...
uint256 GetBlockHash() const
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams)
static CuckooCache::cache< uint256, SignatureCacheHasher > g_scriptExecutionCache
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
void PruneAndFlush()
Prune blockfiles from the disk if necessary and then flush chainstate changes if we pruned...
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.
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Removed for reorganization.
indexed_disconnected_transactions queuedTx
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
RecursiveMutex m_cs_chainstate
the ChainState CriticalSection A lock that must be held when modifying this ChainState - held in Acti...
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
std::string ToString(const T &t)
Locale-independent version of std::to_string.
uint64_t PruneAfterHeight() const
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...
static const bool DEFAULT_PERSIST_MEMPOOL
Default for -persistmempool.
void SetfLargeWorkInvalidChainFound(bool flag)
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
bool LoadMempool(CTxMemPool &pool, CChainState &active_chainstate, FopenFn mockable_fopen_function)
Load the mempool from disk.
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
bool m_snapshot_validated
If true, the assumed-valid chainstate has been fully validated by the background validation chainstat...
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.
bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Whether the chain state needs to be redownloaded due to lack of witness data.
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
void AddUnbroadcastTx(const uint256 &txid)
Adds a transaction to the unbroadcast set.
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.
void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty...
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 ...
bool IsSnapshotActive() const
bool fPruneMode
True if we're running in -prune mode.
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Access to the block database (blocks/index/)
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
static int64_t nTimeChainState
Abstract view on the open txout dataset.
static int64_t nTimeTotal
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
bool PopulateAndValidateSnapshot(CChainState &snapshot_chainstate, CAutoFile &coins_file, const SnapshotMetadata &metadata)
Internal helper for ActivateSnapshot().
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
this block was cached as being invalid and we didn't store the reason why
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs, bool taproot_active)
Check transaction inputs to mitigate two potential denial-of-service attacks:
void removeForBlock(const std::vector< CTransactionRef > &vtx)
static constexpr unsigned int LOCKTIME_MEDIAN_TIME_PAST
Use GetMedianTimePast() instead of nTime for end point timestamp.
Validation result for package mempool acceptance.
An input of a transaction.
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
const uint256 & GetWitnessHash() const
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
const uint256 & GetHash() const
std::string ToString() const
bilingual_str _(const char *psz)
Translation function.
static CCheckQueue< CScriptCheck > scriptcheckqueue(128)
the block failed to meet one of our checkpoints
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...
bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the block tree and coins database from disk, initializing state if we're running with -reindex...
int BIP34Height
Block height and hash at which BIP34 becomes active.
bool IsSnapshotValidated() const
Is there a snapshot in use and has it been fully validated?
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
uint256 uint256S(const char *str)
int64_t nPowTargetSpacing
std::string ScriptErrorString(const ScriptError serror)
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...
Abstract class that implements BIP9-style threshold logic, and caches results.
std::map< int, const AssumeutxoData > MapAssumeutxo
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
Holds various statistics on transactions within a chain.
static int64_t nTimeIndex
void Finalize(unsigned char hash[OUTPUT_SIZE])
const std::vector< CTxOut > vout
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT
Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants.
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
static const unsigned int DEFAULT_MEMPOOL_EXPIRY
Default for -mempoolexpiry, expiration time for mempool transactions in hours.
static const int DEFAULT_STOPATHEIGHT
Default for -stopatheight.
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
CBlockIndex * AddToBlockIndex(const CBlockHeader &block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::set< CBlockIndex * > setDirtyBlockIndex
Dirty block index entries.
std::shared_ptr< const CBlock > pblock
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main)
CMainSignals & GetMainSignals()
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
void BuildSkip()
Build the skiplist pointer for this entry.
const CMessageHeader::MessageStartChars & MessageStart() const
An output of a transaction.
bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
Mark a block as invalid.
std::string ToString() const
std::unique_ptr< CoinsViews > m_coins_views
Manages the UTXO set, which is a reflection of the contents of m_chain.
bool CheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
const CChainParams & m_params
std::vector< uint256 > vHave
At least one tx is invalid.
void StopScriptCheckWorkerThreads()
Stop all of the script checking worker threads.
uint32_t nMinerConfirmationWindow
Queue for verifications that have to be performed.
Parameters that influence chain consensus.
void ChainStateFlushed(const CBlockLocator &)
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.
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.
An outpoint - a combination of a transaction hash and an index n into its vout.
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).
void AddTransactionsUpdated(unsigned int n)
CChainState(CTxMemPool *mempool, BlockManager &blockman, std::optional< uint256 > from_snapshot_blockhash=std::nullopt)
arith_uint256 nLastPreciousChainwork
chainwork for the last block that preciousblock has been applied to.
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...
Validation result for a single transaction mempool acceptance.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define Assume(val)
Assume is the identity function.
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download...
256-bit unsigned big integer.
int64_t GetMedianTimePast() const
block data in blk*.data was received with a witness-enforcing client
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
static int64_t nTimeCallbacks
CFeeRate incrementalRelayFee
static int64_t nTimeCheck
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
bool ReplayBlocks()
Replay blocks that aren't fully applied to the database.
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
static int64_t nTimeConnect
int64_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Closure representing one script verification Note that this stores references to the spending transac...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
static int64_t nTimeReadFromDisk
VersionBitsCache g_versionbitscache
Global cache for versionbits deployment status.
static bool CheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW=true)
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...
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.
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...
static ThresholdConditionCache warningcache [VERSIONBITS_NUM_BITS] GUARDED_BY(cs_main)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
Transaction is missing a witness.
int64_t GetTimeMicros()
Returns the system time (not mockable)
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 RenameOver(fs::path src, fs::path dest)
int32_t nBlockSequenceId
Blocks loaded from disk are assigned id 0, so start the counter at 1.
static void DoWarning(const bilingual_str &warning)
void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool TestLockPointValidity(CChain &active_chain, const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
int32_t nVersion
block header
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
bool CheckFinalTx(const CBlockIndex *active_chain_tip, const CTransaction &tx, int flags)
Transaction validation functions.
invalid by consensus rules (excluding any below reasons)
const CTransaction * ptxTo
CChainState &InitializeChainstate(CTxMemPool *mempool, const std::optional< uint256 > &snapshot_blockhash=std::nullopt) EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * GetAll)()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
std::atomic_bool fReindex
bool g_parallel_script_checks
Whether there are dedicated script-checking threads running.
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.
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...
static const bool DEFAULT_CHECKPOINTS_ENABLED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, CChain &active_chain, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
void SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
const ChainTxData & TxData() const
the block's data didn't match the data committed to by the PoW
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
static const int64_t MAX_MAX_SIG_CACHE_SIZE
int32_t nBlockReverseSequenceId
Decreasing counter (used by subsequent preciousblock calls).
MapCheckpoints mapCheckpoints
size_t m_coinsdb_cache_size_bytes
The cache size of the on-disk coins view.
#define LOCKS_EXCLUDED(...)
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
bool VerifyDB(CChainState &chainstate, const CChainParams &chainparams, CCoinsView &coinsview, int nCheckLevel, int nCheckDepth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
bool FlushStateToDisk(BlockValidationState &state, FlushStateMode mode, int nManualPruneHeight=0)
Update the on-disk chain state.
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
Undo information for a CTransaction.
std::vector< PerBlockConnectTrace > blocksConnected
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...
CCoinsView backed by the coin database (chainstate/)
static const int PROTOCOL_VERSION
network protocol versioning
bool DeploymentActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is active for the next block.
void InitScriptExecutionCache()
Initializes the script-execution cache.
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
bool m_spent_outputs_ready
Whether m_spent_outputs is initialized.
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...
bool ActivateSnapshot(CAutoFile &coins_file, const SnapshotMetadata &metadata, bool in_memory)
Construct and activate a Chainstate on the basis of UTXO snapshot data.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
A block this one builds on is invalid.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
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 ...
std::string ToString() const
int64_t GetAdjustedTime()
const AssumeutxoData * ExpectedAssumeutxo(const int height, const CChainParams &chainparams)
Return the expected assumeutxo value for a given height, if one exists.
bool AbortNode(BlockValidationState &state, const std::string &strMessage, const bilingual_str &userMessage)
static void AppendWarning(bilingual_str &res, const bilingual_str &warn)
Private helper function that concatenates warning messages.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Clear all data members.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL
Time to wait between writing blocks/block index to disk.
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network) ...
std::set< CBlockIndex *, CBlockIndexWorkComparator > setBlockIndexCandidates
The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and a...
static int64_t nTimeVerify
static int64_t nTimePostConnect
Fee rate in satoshis per kilobyte: CAmount / kB.
Holds configuration for use during UTXO snapshot load and validation.
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all CChainState instances...
#define AssertLockNotHeld(cs)
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST
The maximum number of sigops we're willing to relay/mine in a single tx.
void PruneBlockFilesManual(CChainState &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given size in bytes.
bool LoadBlockIndexGuts(const Consensus::Params &consensusParams, std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
void StartShutdown()
Request shutdown of the application.
int MinBIP9WarningHeight
Don't warn about unknown BIP 9 activations below this height.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
FlatFilePos GetUndoPos() const
A mutable version of CTransaction.
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period...
CTransactionRef get(const uint256 &hash) const
block timestamp was > 2 hours in the future (or our clock is bad)
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
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...
std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
CChainState & ActiveChainstate() const
The most-work chain.
arith_uint256 GetBlockProof(const CBlockIndex &block)
static MempoolAcceptResult Failure(TxValidationState state)
void UnloadBlockIndex(CTxMemPool *mempool, ChainstateManager &chainman)
Unload database information.
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...
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 ...
CClientUIInterface uiInterface
size_t DynamicMemoryUsage() const
The basic transaction that is broadcasted on the network and contained in blocks. ...
int nHeight
height of the entry in the chain. The genesis block has height 0
std::optional< uint256 > SnapshotBlockhash() const
WarningBitsConditionChecker(int bitIn)
const Consensus::Params & GetConsensus() const
std::vector< CBlockFileInfo > vinfoBlockFile
int64_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
RecursiveMutex cs_LastBlockFile
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE
Maximum kilobytes for transactions to store for processing during reorg.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
std::vector< PerBlockConnectTrace > & GetBlocksConnected()
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
std::string GetRejectReason() const
full block available in blk*.dat
bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, const CFeeRate &dust_relay_fee, std::string &reason)
Check for standard transaction types.
bool fHavePruned
Pruning-related variables and constants.
#define LOG_TIME_MILLIS_WITH_CATEGORY(end_msg, log_category)
bool DeploymentActiveAt(const CBlockIndex &index, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep)
Determine if a deployment is active for this block.
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from...
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) ...
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found.
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.
A hasher class for SHA-256.
int64_t GetTime()
Return system time (or mocked time, if set)
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
const AssumeutxoHash hash_serialized
The expected hash of the deserialized UTXO set.
std::atomic_bool fImporting
std::vector< CTxUndo > vtxundo
static SynchronizationState GetSynchronizationState(bool init)
void SetIsLoaded(bool loaded)
Sets the current loaded state.
static int64_t GetBlockWeight(const CBlock &block)
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.
PackageMempoolAcceptResult ProcessNewPackage(CChainState &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept)
Atomically test acceptance of a package.
static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS
Used as the flags parameter to sequence and nLocktime checks in non-consensus code.
static const int32_t VERSIONBITS_NUM_BITS
Total bits available for versionbits.
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.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
bool CheckTransaction(const CTransaction &tx, TxValidationState &state)
CBlockIndex * maxInputBlock
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.
ScriptError GetScriptError() const
static int64_t nBlocksTotal
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
CCoinsView that brings transactions from a mempool into view.
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, int flags)
Compute total signature operation cost of a transaction.
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
bool error(const char *fmt, const Args &... args)
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
CTransactionRef GetTransaction(const CBlockIndex *const block_index, const CTxMemPool *const mempool, const uint256 &hash, const Consensus::Params &consensusParams, uint256 &hashBlock)
Return transaction from the block at block_index.
bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Update the chain tip based on database information, i.e.
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove invalidity status from a block and its descendants.
static int64_t nTimeFlush
void BlockChecked(const CBlock &, const BlockValidationState &)
static unsigned int GetBlockScriptFlags(const CBlockIndex *pindex, const Consensus::Params &chainparams)
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
CHash256 & Write(Span< const unsigned char > input)
otherwise didn't meet our local policy rules
A generic txid reference (txid or wtxid).
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
RecursiveMutex cs_nBlockSequenceId
Every received block is assigned a unique and increasing identifier, so we know which one to give pri...
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
unsigned int nTx
Number of transactions in this block.
bool DumpMempool(const CTxMemPool &pool, FopenFn mockable_fopen_function, bool skip_file_commit)
Dump the mempool to disk.
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
RecursiveMutex * MempoolMutex() const LOCK_RETURNED(m_mempool -> cs)
Indirection necessary to make lock annotations work with an optional mempool.
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Determine what nVersion a new block should use.
void UpdateUncommittedBlockStructures(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Update uncommitted block structures (currently: only the witness reserved value). ...
Non-refcounted RAII wrapper for FILE*.
static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL
Time to wait between flushing chainstate to disk.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
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 fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
void InvalidChainFound(CBlockIndex *pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CTxMemPool * m_mempool
Optional mempool that is kept in sync with the chain.
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
IndexSummary GetSummary() const
Get a summary of the index and its state.
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
PrecomputedTransactionData * txdata
Threshold condition checker that triggers when unknown versionbits are seen on the network...