54 #include <boost/algorithm/string/replace.hpp>
56 #define MICRO 0.000001
78 "level 0 reads the blocks from disk",
79 "level 1 verifies block validity",
80 "level 2 verifies undo data",
81 "level 3 checks disconnection of tip blocks",
82 "level 4 tries to reconnect the blocks",
83 "each level includes the checks of the previous levels",
97 if (pa < pb)
return false;
98 if (pa > pb)
return true;
158 std::vector<CBlockFileInfo> vinfoBlockFile;
159 int nLastBlockFile = 0;
164 bool fCheckForPruning =
false;
167 std::set<CBlockIndex*> setDirtyBlockIndex;
170 std::set<int> setDirtyFileInfo;
235 return IsFinalTx(tx, nBlockHeight, nBlockTime);
262 assert(tip !=
nullptr);
274 std::pair<int, int64_t> lockPair;
275 if (useExistingLockPoints) {
278 lockPair.second =
lp->
time;
283 std::vector<int> prevheights;
284 prevheights.resize(tx.
vin.size());
285 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
286 const CTxIn& txin = tx.
vin[txinIndex];
289 return error(
"%s: Missing input", __func__);
293 prevheights[txinIndex] = tip->
nHeight + 1;
295 prevheights[txinIndex] = coin.
nHeight;
301 lp->
time = lockPair.second;
315 int maxInputHeight = 0;
316 for (
const int height : prevheights) {
318 if (height != tip->
nHeight+1) {
319 maxInputHeight = std::max(maxInputHeight, height);
334 int expired = pool.Expire(GetTime<std::chrono::seconds>() - age);
385 if (!fAddToMempool || (*it)->IsCoinBase() ||
391 }
else if (mempool.exists((*it)->GetHash())) {
396 disconnectpool.queuedTx.clear();
421 assert(!tx.IsCoinBase());
422 for (
const CTxIn& txin : tx.vin) {
428 if (coin.
IsSpent())
return false;
434 assert(txFrom->vout.size() > txin.
prevout.
n);
438 assert(!coinFromDisk.
IsSpent());
439 assert(coinFromDisk.
out == coin.
out);
452 MemPoolAccept(
CTxMemPool& mempool) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&::
ChainstateActive().CoinsTip(), m_pool),
463 const int64_t m_accept_time;
464 std::list<CTransactionRef>* m_replaced_transactions;
465 const bool m_bypass_limits;
473 std::vector<COutPoint>& m_coins_to_uncache;
474 const bool m_test_accept;
485 Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
486 std::set<uint256> m_conflicts;
489 std::unique_ptr<CTxMemPoolEntry> m_entry;
491 bool m_replacement_transaction;
494 size_t m_conflicting_size;
525 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
542 const size_t m_limit_ancestors;
543 const size_t m_limit_ancestor_size;
546 size_t m_limit_descendants;
547 size_t m_limit_descendant_size;
550 bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
554 const uint256& hash = ws.m_hash;
558 const int64_t nAcceptTime = args.m_accept_time;
559 const bool bypass_limits = args.m_bypass_limits;
560 std::vector<COutPoint>& coins_to_uncache = args.m_coins_to_uncache;
563 std::set<uint256>& setConflicts = ws.m_conflicts;
566 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
567 bool& fReplacementTransaction = ws.m_replacement_transaction;
568 CAmount& nModifiedFees = ws.m_modified_fees;
569 CAmount& nConflictingFees = ws.m_conflicting_fees;
570 size_t& nConflictingSize = ws.m_conflicting_size;
599 if (m_pool.exists(hash)) {
607 if (ptxConflicting) {
608 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++) {
667 m_view.GetBestBlock();
672 m_view.SetBackend(m_dummy);
688 if (args.m_fee_out) {
689 *args.m_fee_out = nFees;
693 const auto& params = args.m_chainparams.GetConsensus();
706 nModifiedFees = nFees;
707 m_pool.ApplyDelta(hash, nModifiedFees);
711 bool fSpendsCoinbase =
false;
713 const Coin &coin = m_view.AccessCoin(txin.
prevout);
715 fSpendsCoinbase =
true;
721 fSpendsCoinbase, nSigOpsCost,
lp));
722 unsigned int nSize = entry->GetTxSize();
730 if (!bypass_limits && !
CheckFeeRate(nSize, nModifiedFees, state))
return false;
734 if (setConflicts.size() == 1) {
762 assert(setIterConflicting.size() == 1);
765 m_limit_descendants += 1;
766 m_limit_descendant_size += conflict->GetSizeWithDescendants();
769 std::string errString;
770 if (!m_pool.CalculateMemPoolAncestors(*entry, setAncestors, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants, m_limit_descendant_size, errString)) {
771 setAncestors.clear();
773 std::string dummy_err_string;
786 !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)) {
797 const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
798 if (setConflicts.count(hashAncestor))
801 strprintf(
"%s spends conflicting transaction %s",
809 nConflictingFees = 0;
810 nConflictingSize = 0;
811 uint64_t nConflictingCount = 0;
816 fReplacementTransaction = setConflicts.size();
817 if (fReplacementTransaction)
819 CFeeRate newFeeRate(nModifiedFees, nSize);
820 std::set<uint256> setConflictsParents;
821 const int maxDescendantsToVisit = 100;
822 for (
const auto& mi : setIterConflicting) {
837 CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
838 if (newFeeRate <= oldFeeRate)
841 strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
843 newFeeRate.ToString(),
844 oldFeeRate.ToString()));
847 for (
const CTxIn &txin : mi->GetTx().vin)
852 nConflictingCount += mi->GetCountWithDescendants();
857 if (nConflictingCount <= maxDescendantsToVisit) {
861 m_pool.CalculateDescendants(
it, allConflicting);
864 nConflictingFees +=
it->GetModifiedFee();
865 nConflictingSize +=
it->GetTxSize();
869 strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
872 maxDescendantsToVisit));
875 for (
unsigned int j = 0; j < tx.
vin.size(); j++)
886 if (!setConflictsParents.count(tx.
vin[j].prevout.hash))
891 if (m_pool.exists(tx.
vin[j].prevout.hash)) {
893 strprintf(
"replacement %s adds unconfirmed input, idx %d",
902 if (nModifiedFees < nConflictingFees)
905 strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
911 CAmount nDeltaFees = nModifiedFees - nConflictingFees;
915 strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
934 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, txdata)) {
954 const uint256& hash = ws.m_hash;
976 return error(
"%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
983 bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
986 const uint256& hash = ws.m_hash;
988 const bool bypass_limits = args.m_bypass_limits;
992 const CAmount& nModifiedFees = ws.m_modified_fees;
993 const CAmount& nConflictingFees = ws.m_conflicting_fees;
994 const size_t& nConflictingSize = ws.m_conflicting_size;
995 const bool fReplacementTransaction = ws.m_replacement_transaction;
996 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
1002 it->GetTx().GetHash().ToString(),
1005 (
int)entry->GetTxSize() - (
int)nConflictingSize);
1006 if (args.m_replaced_transactions)
1007 args.m_replaced_transactions->push_back(
it->GetSharedTx());
1016 bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits &&
IsCurrentForFeeEstimation() && m_pool.HasNoInputsOf(tx);
1019 m_pool.addUnchecked(*entry, setAncestors, validForFeeEstimation);
1022 if (!bypass_limits) {
1024 if (!m_pool.exists(hash))
1030 bool MemPoolAccept::AcceptSingleTransaction(
const CTransactionRef& ptx, ATMPArgs& args)
1035 Workspace workspace(ptx);
1037 if (!PreChecks(args, workspace))
return false;
1045 if (!PolicyScriptChecks(args, workspace, txdata))
return false;
1047 if (!ConsensusScriptChecks(args, workspace, txdata))
return false;
1050 if (args.m_test_accept)
return true;
1052 if (!Finalize(args, workspace))
return false;
1063 int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
1066 std::vector<COutPoint> coins_to_uncache;
1067 MemPoolAccept::ATMPArgs args { chainparams, state, nAcceptTime, plTxnReplaced, bypass_limits, coins_to_uncache, test_accept, fee_out };
1068 bool res = MemPoolAccept(pool).AcceptSingleTransaction(tx, args);
1075 for (
const COutPoint& hashTx : coins_to_uncache)
1085 std::list<CTransactionRef>* plTxnReplaced,
1086 bool bypass_limits,
bool test_accept,
CAmount* fee_out)
1099 for (
const auto& tx : block.
vtx) {
1110 if (ptx)
return ptx;
1114 if (
g_txindex->FindTx(hash, hashBlock, tx))
return tx;
1129 return error(
"WriteBlockToDisk: OpenBlockFile failed");
1133 fileout << messageStart << nSize;
1136 long fileOutPos = ftell(fileout.
Get());
1138 return error(
"WriteBlockToDisk: ftell failed");
1139 pos.
nPos = (
unsigned int)fileOutPos;
1152 return error(
"ReadBlockFromDisk: OpenBlockFile failed for %s", pos.
ToString());
1158 catch (
const std::exception& e) {
1159 return error(
"%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.
ToString());
1164 return error(
"ReadBlockFromDisk: Errors in block header at %s", pos.
ToString());
1168 return error(
"ReadBlockFromDisk: Errors in block solution at %s", pos.
ToString());
1185 return error(
"ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
1196 return error(
"%s: OpenBlockFile failed for %s", __func__, pos.
ToString());
1201 unsigned int blk_size;
1203 filein >> blk_start >> blk_size;
1206 return error(
"%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.
ToString(),
1212 return error(
"%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.
ToString(),
1216 block.resize(blk_size);
1217 filein.
read((
char*)block.data(), blk_size);
1218 }
catch(
const std::exception& e) {
1219 return error(
"%s: Read from block file failed: %s for %s", __func__, e.what(), pos.
ToString());
1245 nSubsidy >>= halvings;
1250 std::string ldb_name,
1251 size_t cache_size_bytes,
1253 bool should_wipe) : m_dbview(
1254 GetDataDir() / ldb_name, cache_size_bytes, in_memory, should_wipe),
1255 m_catcherview(&m_dbview) {}
1257 void CoinsViews::InitCache()
1259 m_cacheview = MakeUnique<CCoinsViewCache>(&m_catcherview);
1263 : m_blockman(blockman),
1265 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1268 size_t cache_size_bytes,
1271 std::string leveldb_name)
1278 leveldb_name, cache_size_bytes, in_memory, should_wipe);
1281 void CChainState::InitCoinsCache(
size_t cache_size_bytes)
1310 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1321 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1322 if (strCmd.empty())
return;
1327 std::string singleQuote(
"'");
1329 safeStatus = singleQuote+safeStatus+singleQuote;
1330 boost::replace_all(strCmd,
"%s", safeStatus);
1332 std::thread t(runCommand, strCmd);
1354 std::string warning = std::string(
"'Warning: Large-work fork detected, forking after block ") +
1360 LogPrintf(
"%s: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", __func__,
1367 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1384 while (pfork && pfork != plonger)
1387 plonger = plonger->
pprev;
1388 if (pfork == plonger)
1390 pfork = pfork->
pprev;
1402 ::
ChainActive().Height() - pindexNewForkTip->nHeight < 72)
1414 if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
1415 pindexBestInvalid = pindexNew;
1420 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
1421 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
1425 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
1437 setDirtyBlockIndex.insert(pindex);
1474 return pindexPrev->
nHeight + 1;
1493 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1494 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1521 pvChecks->reserve(tx.
vin.size());
1538 std::vector<CTxOut> spent_outputs;
1539 spent_outputs.reserve(tx.
vin.size());
1541 for (
const auto& txin : tx.
vin) {
1543 const Coin& coin = inputs.AccessCoin(prevout);
1545 spent_outputs.emplace_back(coin.
out);
1547 txdata.
Init(tx, std::move(spent_outputs));
1551 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1563 check.
swap(pvChecks->back());
1564 }
else if (!check()) {
1592 if (cacheFullScriptStore && !pvChecks) {
1606 return error(
"%s: OpenUndoFile failed", __func__);
1610 fileout << messageStart << nSize;
1613 long fileOutPos = ftell(fileout.
Get());
1615 return error(
"%s: ftell failed", __func__);
1616 pos.
nPos = (
unsigned int)fileOutPos;
1617 fileout << blockundo;
1621 hasher << hashBlock;
1622 hasher << blockundo;
1632 return error(
"%s: no undo data available", __func__);
1638 return error(
"%s: OpenUndoFile failed", __func__);
1645 verifier >> blockundo;
1646 filein >> hashChecksum;
1648 catch (
const std::exception& e) {
1649 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1653 if (hashChecksum != verifier.
GetHash())
1654 return error(
"%s: Checksum mismatch", __func__);
1664 if (user_message.empty()) {
1665 user_message =
_(
"A fatal internal error occurred, see debug.log for details");
1675 return state.
Error(strMessage);
1689 if (view.
HaveCoin(out)) fClean =
false;
1691 if (undo.nHeight == 0) {
1697 undo.nHeight = alternate.
nHeight;
1708 view.
AddCoin(out, std::move(undo), !fClean);
1721 error(
"DisconnectBlock(): failure reading undo data");
1725 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1726 error(
"DisconnectBlock(): block and undo data inconsistent");
1731 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1738 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1739 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1742 bool is_spent = view.
SpendCoin(out, &coin);
1753 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1756 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1774 FlatFilePos undo_pos_old(block_file, vinfoBlockFile[block_file].nUndoSize);
1775 if (!
UndoFileSeq().Flush(undo_pos_old, finalize)) {
1776 AbortNode(
"Flushing undo file to disk failed. This is likely the result of an I/O error.");
1782 LOCK(cs_LastBlockFile);
1783 FlatFilePos block_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nSize);
1785 AbortNode(
"Flushing block file to disk failed. This is likely the result of an I/O error.");
1789 if (!fFinalize || finalize_undo)
FlushUndoFile(nLastBlockFile, finalize_undo);
1800 return error(
"ConnectBlock(): FindUndoPos failed");
1802 return AbortNode(state,
"Failed to write undo data");
1808 if (_pos.
nFile < nLastBlockFile &&
static_cast<uint32_t
>(pindex->
nHeight) == vinfoBlockFile[_pos.
nFile].nHeightLast) {
1815 setDirtyBlockIndex.insert(pindex);
1878 return params.
SegwitHeight != std::numeric_limits<int>::max();
1891 if (consensusparams.BIP16Exception.IsNull() ||
1892 pindex->phashBlock ==
nullptr ||
1893 *pindex->phashBlock != consensusparams.BIP16Exception)
1905 if (pindex->nHeight >= consensusparams.BIP66Height) {
1910 if (pindex->nHeight >= consensusparams.BIP65Height) {
1915 if (pindex->nHeight >= consensusparams.CSVHeight) {
1972 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
1974 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
1991 bool fScriptChecks =
true;
2000 if (
it->second->GetAncestor(pindex->
nHeight) == pindex &&
2037 bool fEnforceBIP30 = !((pindex->
nHeight==91842 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
2038 (pindex->
nHeight==91880 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
2066 static constexpr
int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
2096 assert(pindex->
pprev);
2104 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
2105 for (
const auto& tx : block.
vtx) {
2106 for (
size_t o = 0; o < tx->
vout.size(); o++) {
2108 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
2116 int nLockTimeFlags = 0;
2135 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
2137 std::vector<int> prevheights;
2140 int64_t nSigOpsCost = 0;
2141 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
2142 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2146 nInputs += tx.
vin.size();
2160 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n", __func__);
2167 prevheights.resize(tx.
vin.size());
2168 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2172 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
2173 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
2184 LogPrintf(
"ERROR: ConnectBlock(): too many sigops\n");
2190 std::vector<CScriptCheck> vChecks;
2191 bool fCacheResults = fJustCheck;
2197 return error(
"ConnectBlock(): CheckInputScripts on %s failed with %s",
2200 control.
Add(vChecks);
2213 if (block.
vtx[0]->GetValueOut() > blockReward) {
2214 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.
vtx[0]->GetValueOut(), blockReward);
2218 if (!control.
Wait()) {
2219 LogPrintf(
"ERROR: %s: CheckQueue failed\n", __func__);
2233 setDirtyBlockIndex.insert(pindex);
2251 return this->GetCoinsCacheSizeState(
2259 size_t max_coins_cache_size_bytes,
2260 size_t max_mempool_size_bytes)
2264 int64_t nTotalSpace =
2265 max_coins_cache_size_bytes + std::max<int64_t>(max_mempool_size_bytes - nMempoolUsage, 0);
2268 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
2269 int64_t large_threshold =
2270 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2272 if (cacheSize > nTotalSpace) {
2273 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
2275 }
else if (cacheSize > large_threshold) {
2281 bool CChainState::FlushStateToDisk(
2285 int nManualPruneHeight)
2288 assert(this->CanFlushToDisk());
2289 static std::chrono::microseconds nLastWrite{0};
2290 static std::chrono::microseconds nLastFlush{0};
2291 std::set<int> setFilesToPrune;
2292 bool full_flush_completed =
false;
2299 bool fFlushForPrune =
false;
2300 bool fDoFullFlush =
false;
2302 LOCK(cs_LastBlockFile);
2304 if (nManualPruneHeight > 0) {
2312 fCheckForPruning =
false;
2314 if (!setFilesToPrune.empty()) {
2315 fFlushForPrune =
true;
2317 pblocktree->WriteFlag(
"prunedblockfiles",
true);
2322 const auto nNow = GetTime<std::chrono::microseconds>();
2324 if (nLastWrite.count() == 0) {
2327 if (nLastFlush.count() == 0) {
2339 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2341 if (fDoFullFlush || fPeriodicWrite) {
2344 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2357 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2358 vFiles.reserve(setDirtyFileInfo.size());
2359 for (std::set<int>::iterator
it = setDirtyFileInfo.begin();
it != setDirtyFileInfo.end(); ) {
2360 vFiles.push_back(std::make_pair(*
it, &vinfoBlockFile[*
it]));
2361 setDirtyFileInfo.erase(
it++);
2363 std::vector<const CBlockIndex*> vBlocks;
2364 vBlocks.reserve(setDirtyBlockIndex.size());
2365 for (std::set<CBlockIndex*>::iterator
it = setDirtyBlockIndex.begin();
it != setDirtyBlockIndex.end(); ) {
2366 vBlocks.push_back(*
it);
2367 setDirtyBlockIndex.erase(
it++);
2369 if (!
pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
2370 return AbortNode(state,
"Failed to write to block index database");
2374 if (fFlushForPrune) {
2382 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2384 coins_count, coins_mem_usage / 1000));
2392 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2396 return AbortNode(state,
"Failed to write to coin database");
2398 full_flush_completed =
true;
2401 if (full_flush_completed) {
2405 }
catch (
const std::runtime_error& e) {
2406 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2421 fCheckForPruning =
true;
2431 static bool fWarned =
false;
2451 mempool.AddTransactionsUpdated(1);
2460 int num_unexpected_version = 0;
2477 for (
int i = 0; i < 100 && pindex !=
nullptr; i++)
2481 ++num_unexpected_version;
2482 pindex = pindex->
pprev;
2485 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__,
2486 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
2487 log(pindexNew->nChainWork.getdouble())/log(2.0), (
unsigned long)pindexNew->nChainTx,
2492 if (num_unexpected_version > 0) {
2513 assert(pindexDelete);
2515 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2518 return error(
"DisconnectTip(): Failed to read block");
2526 bool flushed = view.
Flush();
2534 if (disconnectpool) {
2536 for (
auto it = block.
vtx.rbegin();
it != block.
vtx.rend(); ++
it) {
2616 std::shared_ptr<const CBlock> pthisBlock;
2618 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2620 return AbortNode(state,
"Failed to read block");
2621 pthisBlock = pblockNew;
2623 pthisBlock = pblock;
2625 const CBlock& blockConnecting = *pthisBlock;
2632 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
2642 bool flushed = view.
Flush();
2686 bool fInvalidAncestor =
false;
2696 if (fFailedChain || fMissingData) {
2698 if (fFailedChain && (pindexBestInvalid ==
nullptr || pindexNew->
nChainWork > pindexBestInvalid->nChainWork))
2699 pindexBestInvalid = pindexNew;
2702 while (pindexTest != pindexFailed) {
2705 }
else if (fMissingData) {
2710 std::make_pair(pindexFailed->
pprev, pindexFailed));
2713 pindexFailed = pindexFailed->
pprev;
2716 fInvalidAncestor =
true;
2719 pindexTest = pindexTest->
pprev;
2721 if (!fInvalidAncestor)
2753 bool fBlocksDisconnected =
false;
2764 AbortNode(state,
"Failed to disconnect block; see debug.log for details");
2767 fBlocksDisconnected =
true;
2771 std::vector<CBlockIndex*> vpindexToConnect;
2772 bool fContinue =
true;
2777 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
2778 vpindexToConnect.clear();
2779 vpindexToConnect.reserve(nTargetHeight -
nHeight);
2782 vpindexToConnect.push_back(pindexIter);
2783 pindexIter = pindexIter->
pprev;
2789 if (!
ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2796 fInvalidFound =
true;
2817 if (fBlocksDisconnected) {
2841 bool fNotify =
false;
2842 bool fInitialBlockDownload =
false;
2849 if (pindexHeader != pindexHeaderOld) {
2852 pindexHeaderOld = pindexHeader;
2899 bool blocks_connected =
false;
2905 if (pindexMostWork ==
nullptr) {
2910 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
2914 bool fInvalidFound =
false;
2915 std::shared_ptr<const CBlock> nullBlockPtr;
2916 if (!
ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
2920 blocks_connected =
true;
2922 if (fInvalidFound) {
2924 pindexMostWork =
nullptr;
2929 assert(trace.pblock && trace.pindex);
2933 if (!blocks_connected)
return true;
2940 if (pindexFork != pindexNewTip) {
2957 }
while (pindexNewTip != pindexMostWork);
3007 bool pindex_was_in_chain =
false;
3008 int disconnected = 0;
3022 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
3026 for (
const auto& entry :
m_blockman.m_block_index) {
3037 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
3052 pindex_was_in_chain =
true;
3058 bool ret =
DisconnectTip(state, chainparams, &disconnectpool);
3065 if (!ret)
return false;
3074 setDirtyBlockIndex.insert(invalid_walk_tip);
3081 setDirtyBlockIndex.insert(to_mark_failed);
3085 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
3086 while (candidate_it != candidate_blocks_by_work.end()) {
3089 candidate_it = candidate_blocks_by_work.erase(candidate_it);
3097 to_mark_failed = invalid_walk_tip;
3111 setDirtyBlockIndex.insert(to_mark_failed);
3122 BlockMap::iterator
it =
m_blockman.m_block_index.begin();
3134 if (pindex_was_in_chain) {
3150 BlockMap::iterator
it =
m_blockman.m_block_index.begin();
3152 if (!
it->second->IsValid() &&
it->second->GetAncestor(
nHeight) == pindex) {
3154 setDirtyBlockIndex.insert(
it->second);
3158 if (
it->second == pindexBestInvalid) {
3160 pindexBestInvalid =
nullptr;
3168 while (pindex !=
nullptr) {
3171 setDirtyBlockIndex.insert(pindex);
3174 pindex = pindex->
pprev;
3188 BlockMap::iterator
it = m_block_index.find(hash);
3189 if (
it != m_block_index.end())
3198 BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
3200 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
3201 if (miPrev != m_block_index.end())
3203 pindexNew->
pprev = (*miPrev).second;
3213 setDirtyBlockIndex.insert(pindexNew);
3221 pindexNew->
nTx = block.
vtx.size();
3231 setDirtyBlockIndex.insert(pindexNew);
3235 std::deque<CBlockIndex*> queue;
3236 queue.push_back(pindexNew);
3239 while (!queue.empty()) {
3250 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
3251 while (range.first != range.second) {
3252 std::multimap<CBlockIndex*, CBlockIndex*>::iterator
it = range.first;
3253 queue.push_back(
it->second);
3260 m_blockman.m_blocks_unlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
3267 LOCK(cs_LastBlockFile);
3269 unsigned int nFile = fKnown ? pos.
nFile : nLastBlockFile;
3270 if (vinfoBlockFile.size() <= nFile) {
3271 vinfoBlockFile.resize(nFile + 1);
3274 bool finalize_undo =
false;
3282 if (vinfoBlockFile.size() <= nFile) {
3283 vinfoBlockFile.resize(nFile + 1);
3287 pos.
nPos = vinfoBlockFile[nFile].nSize;
3290 if ((
int)nFile != nLastBlockFile) {
3292 LogPrintf(
"Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].
ToString());
3295 nLastBlockFile = nFile;
3298 vinfoBlockFile[nFile].AddBlock(
nHeight, nTime);
3300 vinfoBlockFile[nFile].nSize = std::max(pos.
nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3302 vinfoBlockFile[nFile].nSize += nAddSize;
3308 return AbortNode(
"Disk space is too low!",
_(
"Disk space is too low!"));
3311 fCheckForPruning =
true;
3315 setDirtyFileInfo.insert(nFile);
3323 LOCK(cs_LastBlockFile);
3325 pos.
nPos = vinfoBlockFile[nFile].nUndoSize;
3326 vinfoBlockFile[nFile].nUndoSize += nAddSize;
3327 setDirtyFileInfo.insert(nFile);
3332 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
3335 fCheckForPruning =
true;
3368 if (fCheckMerkleRoot) {
3392 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3394 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3395 if (block.
vtx[i]->IsCoinBase())
3400 for (
const auto& tx : block.
vtx) {
3410 unsigned int nSigOps = 0;
3411 for (
const auto& tx : block.
vtx)
3418 if (fCheckPOW && fCheckMerkleRoot)
3426 int height = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3433 static const std::vector<unsigned char> nonce(32, 0x00);
3436 tx.
vin[0].scriptWitness.stack.resize(1);
3437 tx.
vin[0].scriptWitness.stack[0] = nonce;
3444 std::vector<unsigned char> commitment;
3446 std::vector<unsigned char> ret(32, 0x00);
3447 if (consensusParams.
SegwitHeight != std::numeric_limits<int>::max()) {
3463 tx.
vout.push_back(out);
3476 for (
const MapCheckpoints::value_type& i :
reverse_iterate(checkpoints))
3478 const uint256& hash = i.second;
3498 assert(pindexPrev !=
nullptr);
3499 const int nHeight = pindexPrev->nHeight + 1;
3512 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
3513 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
3519 if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
3532 strprintf(
"rejected nVersion=0x%08x block", block.nVersion));
3545 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3548 int nLockTimeFlags = 0;
3550 assert(pindexPrev !=
nullptr);
3559 for (
const auto& tx : block.
vtx) {
3569 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3570 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3583 bool fHaveWitness =
false;
3587 bool malleated =
false;
3592 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3596 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3599 fHaveWitness =
true;
3604 if (!fHaveWitness) {
3605 for (
const auto& tx : block.
vtx) {
3630 BlockMap::iterator miSelf = m_block_index.find(hash);
3633 if (miSelf != m_block_index.end()) {
3635 pindex = miSelf->second;
3639 LogPrintf(
"ERROR: %s: block %s is marked invalid\n", __func__, hash.
ToString());
3652 BlockMap::iterator mi = m_block_index.find(block.
hashPrevBlock);
3653 if (mi == m_block_index.end()) {
3654 LogPrintf(
"ERROR: %s: prev block not found\n", __func__);
3657 pindexPrev = (*mi).second;
3659 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
3663 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.
ToString(), state.
ToString());
3690 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
3693 while (invalid_walk != failedit) {
3695 setDirtyBlockIndex.insert(invalid_walk);
3696 invalid_walk = invalid_walk->
pprev;
3698 LogPrintf(
"ERROR: %s: prev block invalid\n", __func__);
3704 if (pindex ==
nullptr)
3721 bool accepted = m_blockman.AcceptBlockHeader(
3722 header, state, chainparams, &pindex);
3734 if (::
ChainstateActive().IsInitialBlockDownload() && ppindex && *ppindex) {
3735 LogPrintf(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n", (*ppindex)->nHeight, 100.0/((*ppindex)->nHeight+(
GetAdjustedTime() - (*ppindex)->GetBlockTime()) /
Params().GetConsensus().nPowTargetSpacing) * (*ppindex)->nHeight);
3748 error(
"%s: FindBlockPos failed", __func__);
3751 if (dbp ==
nullptr) {
3763 const CBlock& block = *pblock;
3765 if (fNewBlock) *fNewBlock =
false;
3769 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3774 if (!accepted_header)
3796 if (fAlreadyHave)
return true;
3798 if (pindex->
nTx != 0)
return true;
3799 if (!fHasMoreOrSameWork)
return true;
3800 if (fTooFarAhead)
return true;
3813 setDirtyBlockIndex.insert(pindex);
3824 if (fNewBlock) *fNewBlock =
true;
3828 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3832 }
catch (
const std::runtime_error& e) {
3833 return AbortNode(state, std::string(
"System error: ") + e.what());
3849 if (fNewBlock) *fNewBlock =
false;
3865 return error(
"%s: AcceptBlock FAILED (%s)", __func__, state.
ToString());
3873 return error(
"%s: ActivateBestChain failed (%s)", __func__, state.
ToString());
3881 assert(pindexPrev && pindexPrev == ::
ChainActive().Tip());
3885 indexDummy.
pprev = pindexPrev;
3891 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.
ToString());
3893 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
3895 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__, state.
ToString());
3896 if (!::
ChainstateActive().ConnectBlock(block, state, &indexDummy, viewNew, chainparams,
true))
3910 LOCK(cs_LastBlockFile);
3912 uint64_t retval = 0;
3914 retval += file.nSize + file.nUndoSize;
3922 LOCK(cs_LastBlockFile);
3924 for (
const auto& entry : m_block_index) {
3926 if (pindex->
nFile == fileNumber) {
3932 setDirtyBlockIndex.insert(pindex);
3939 while (range.first != range.second) {
3940 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
3942 if (_it->second == pindex) {
3949 vinfoBlockFile[fileNumber].SetNull();
3950 setDirtyFileInfo.insert(fileNumber);
3956 for (std::set<int>::iterator
it = setFilesToPrune.begin();
it != setFilesToPrune.end(); ++
it) {
3960 LogPrintf(
"Prune: %s deleted blk/rev (%05u)\n", __func__, *
it);
3966 assert(
fPruneMode && nManualPruneHeight > 0);
3969 if (chain_tip_height < 0) {
3974 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight, chain_tip_height -
MIN_BLOCKS_TO_KEEP);
3976 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
3977 if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
3981 setFilesToPrune.insert(fileNumber);
3984 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune,
count);
4004 if ((uint64_t)chain_tip_height <= nPruneAfterHeight) {
4014 uint64_t nBytesToPrune;
4027 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4028 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
4030 if (vinfoBlockFile[fileNumber].nSize == 0) {
4039 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
4045 setFilesToPrune.insert(fileNumber);
4046 nCurrentUsage -= nBytesToPrune;
4051 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
4053 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4054 nLastBlockWeCanPrune,
count);
4089 BlockMap::iterator mi = m_block_index.find(hash);
4090 if (mi != m_block_index.end())
4091 return (*mi).second;
4095 mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
4104 std::set<CBlockIndex*, CBlockIndexWorkComparator>& block_index_candidates)
4110 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
4111 vSortedByHeight.reserve(m_block_index.size());
4112 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index)
4115 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
4117 sort(vSortedByHeight.begin(), vSortedByHeight.end());
4118 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
4126 if (pindex->
nTx > 0) {
4127 if (pindex->
pprev) {
4140 setDirtyBlockIndex.insert(pindex);
4143 block_index_candidates.insert(pindex);
4146 pindexBestInvalid = pindex;
4160 for (
const BlockMap::value_type& entry : m_block_index) {
4161 delete entry.second;
4164 m_block_index.clear();
4169 if (!chainman.m_blockman.LoadBlockIndex(
4176 pblocktree->ReadLastBlockFile(nLastBlockFile);
4177 vinfoBlockFile.resize(nLastBlockFile + 1);
4178 LogPrintf(
"%s: last block file = %i\n", __func__, nLastBlockFile);
4179 for (
int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4180 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
4182 LogPrintf(
"%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].
ToString());
4183 for (
int nFile = nLastBlockFile + 1;
true; nFile++) {
4185 if (
pblocktree->ReadBlockFileInfo(nFile, info)) {
4186 vinfoBlockFile.push_back(info);
4193 LogPrintf(
"Checking all blk files are present...\n");
4194 std::set<int> setBlkDataFiles;
4195 for (
const std::pair<const uint256, CBlockIndex*>& item : chainman.BlockIndex()) {
4198 setBlkDataFiles.insert(pindex->
nFile);
4201 for (std::set<int>::iterator
it = setBlkDataFiles.begin();
it != setBlkDataFiles.end();
it++)
4212 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
4215 bool fReindexing =
false;
4250 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4260 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, 0,
false);
4277 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4278 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4282 int nGoodTransactions = 0;
4287 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(::
ChainActive().Height() - pindex->
nHeight)) / (
double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
4288 if (reportDone < percentageDone/10) {
4291 reportDone = percentageDone/10;
4293 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, percentageDone,
false);
4298 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
4307 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
4310 if (nCheckLevel >= 2 && pindex) {
4326 nGoodTransactions = 0;
4327 pindexFailure = pindex;
4329 nGoodTransactions += block.
vtx.size();
4335 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", ::
ChainActive().Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
4341 if (nCheckLevel >= 4) {
4343 const int percentageDone = std::max(1, std::min(99, 100 - (
int)(((
double)(::
ChainActive().Height() - pindex->
nHeight)) / (
double)nCheckDepth * 50)));
4344 if (reportDone < percentageDone/10) {
4347 reportDone = percentageDone/10;
4349 uiInterface.ShowProgress(
_(
"Verifying blocks...").translated, percentageDone,
false);
4354 if (!::
ChainstateActive().ConnectBlock(block, state, pindex, coins, chainparams))
4361 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
4376 if (!tx->IsCoinBase()) {
4377 for (
const CTxIn &txin : tx->vin) {
4395 if (hashHeads.empty())
return true;
4396 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4398 uiInterface.ShowProgress(
_(
"Replaying blocks...").translated, 0,
false);
4405 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
4406 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4408 pindexNew =
m_blockman.m_block_index[hashHeads[0]];
4410 if (!hashHeads[1].IsNull()) {
4411 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
4412 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4414 pindexOld =
m_blockman.m_block_index[hashHeads[1]];
4416 assert(pindexFork !=
nullptr);
4420 while (pindexOld != pindexFork) {
4436 pindexOld = pindexOld->
pprev;
4440 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4444 uiInterface.ShowProgress(
_(
"Replaying blocks...").translated, (
int) ((
nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
4473 setDirtyBlockIndex.insert(index);
4477 while (ret.first != ret.second) {
4478 if (ret.first->second == index) {
4499 for (
const auto& entry :
m_blockman.m_block_index) {
4545 return error(
"RewindBlockIndex: unable to disconnect block at height %i (%s)", tip->
nHeight, state.
ToString());
4565 LogPrintf(
"RewindBlockIndex: unable to flush state to disk (%s)\n", state.
ToString());
4584 LogPrintf(
"RewindBlockIndex: unable to flush state to disk (%s)\n", state.
ToString());
4605 pindexBestInvalid =
nullptr;
4607 if (mempool) mempool->
clear();
4608 vinfoBlockFile.clear();
4610 setDirtyBlockIndex.clear();
4611 setDirtyFileInfo.clear();
4614 warningcache[b].clear();
4626 if (!ret)
return false;
4627 needs_init = m_blockman.m_block_index.empty();
4637 LogPrintf(
"Initializing databases...\n");
4657 return error(
"%s: writing genesis block to disk failed", __func__);
4660 }
catch (
const std::runtime_error& e) {
4661 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4675 static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
4682 uint64_t nRewind = blkdat.
GetPos();
4683 while (!blkdat.
eof()) {
4689 unsigned int nSize = 0;
4694 nRewind = blkdat.
GetPos()+1;
4702 }
catch (
const std::exception&) {
4708 uint64_t nBlockPos = blkdat.
GetPos();
4710 dbp->
nPos = nBlockPos;
4711 blkdat.
SetLimit(nBlockPos + nSize);
4712 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4715 nRewind = blkdat.
GetPos();
4725 mapBlocksUnknownParent.insert(std::make_pair(block.
hashPrevBlock, *dbp));
4733 if (::
ChainstateActive().AcceptBlock(pblock, state, chainparams,
nullptr,
true, dbp,
nullptr)) {
4755 std::deque<uint256> queue;
4756 queue.push_back(hash);
4757 while (!queue.empty()) {
4760 std::pair<std::multimap<uint256, FlatFilePos>::iterator, std::multimap<uint256, FlatFilePos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
4761 while (range.first != range.second) {
4762 std::multimap<uint256, FlatFilePos>::iterator
it = range.first;
4763 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4766 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4770 if (::
ChainstateActive().AcceptBlock(pblockrecursive, dummy, chainparams,
nullptr,
true, &
it->second,
nullptr))
4773 queue.push_back(pblockrecursive->GetHash());
4777 mapBlocksUnknownParent.erase(
it);
4781 }
catch (
const std::exception& e) {
4782 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
4785 }
catch (
const std::runtime_error& e) {
4786 AbortNode(std::string(
"System error: ") + e.what());
4803 assert(
m_blockman.m_block_index.size() <= 1);
4808 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4809 for (
const std::pair<const uint256, CBlockIndex*>& entry :
m_blockman.m_block_index) {
4810 forward.insert(std::make_pair(entry.second->pprev, entry.second));
4813 assert(forward.size() ==
m_blockman.m_block_index.size());
4815 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4817 rangeGenesis.first++;
4818 assert(rangeGenesis.first == rangeGenesis.second);
4829 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4831 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4832 while (pindex !=
nullptr) {
4836 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4843 if (pindex->
pprev ==
nullptr) {
4854 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4863 assert((pindexFirstNotTransactionsValid ==
nullptr) == pindex->
HaveTxsDownloaded());
4867 assert(pindexFirstNotTreeValid ==
nullptr);
4871 if (pindexFirstInvalid ==
nullptr) {
4876 if (pindexFirstInvalid ==
nullptr) {
4881 if (pindexFirstMissing ==
nullptr || pindex ==
m_chain.
Tip()) {
4892 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
m_blockman.
m_blocks_unlinked.equal_range(pindex->
pprev);
4893 bool foundInUnlinked =
false;
4894 while (rangeUnlinked.first != rangeUnlinked.second) {
4895 assert(rangeUnlinked.first->first == pindex->
pprev);
4896 if (rangeUnlinked.first->second == pindex) {
4897 foundInUnlinked =
true;
4900 rangeUnlinked.first++;
4902 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4904 assert(foundInUnlinked);
4907 if (pindexFirstMissing ==
nullptr) assert(!foundInUnlinked);
4908 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4920 if (pindexFirstInvalid ==
nullptr) {
4921 assert(foundInUnlinked);
4929 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4930 if (range.first != range.second) {
4932 pindex = range.first->second;
4941 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4942 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4943 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4944 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4945 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4946 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4947 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4951 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4952 while (rangePar.first->second != pindex) {
4953 assert(rangePar.first != rangePar.second);
4958 if (rangePar.first != rangePar.second) {
4960 pindex = rangePar.first->second;
4972 assert(nNodes == forward.size());
4978 return strprintf(
"Chainstate [%s] @ height %d (%s)",
4983 bool CChainState::ResizeCoinsCaches(
size_t coinstip_size,
size_t coinsdb_size)
4995 LogPrintf(
"[%s] resized coinsdb cache to %.1f MiB\n",
4996 this->
ToString(), coinsdb_size * (1.0 / 1024 / 1024));
4997 LogPrintf(
"[%s] resized coinstip cache to %.1f MiB\n",
4998 this->
ToString(), coinstip_size * (1.0 / 1024 / 1024));
5005 if (coinstip_size > old_coinstip_size) {
5023 LOCK(cs_LastBlockFile);
5025 return &vinfoBlockFile.at(n);
5055 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
5060 int64_t expired = 0;
5062 int64_t already_there = 0;
5063 int64_t unbroadcast = 0;
5082 CAmount amountdelta = nFeeDelta;
5087 if (nTime > nNow - nExpiryTimeout) {
5099 if (pool.
exists(tx->GetHash())) {
5111 std::map<uint256, CAmount> mapDeltas;
5114 for (
const auto& i : mapDeltas) {
5119 std::set<uint256> unbroadcast_txids;
5121 file >> unbroadcast_txids;
5122 unbroadcast = unbroadcast_txids.size();
5123 }
catch (
const std::exception&) {
5127 for (
const auto& txid : unbroadcast_txids) {
5132 }
catch (
const std::exception& e) {
5133 LogPrintf(
"Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
5137 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);
5145 std::map<uint256, CAmount> mapDeltas;
5146 std::vector<TxMempoolInfo> vinfo;
5147 std::set<uint256> unbroadcast_txids;
5149 static Mutex dump_mutex;
5155 mapDeltas[i.first] = i.second;
5174 file << (uint64_t)vinfo.size();
5175 for (
const auto& i : vinfo) {
5178 file << int64_t{i.nFeeDelta};
5179 mapDeltas.erase(i.tx->GetHash());
5184 LogPrintf(
"Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
5185 file << unbroadcast_txids;
5188 throw std::runtime_error(
"FileCommit failed");
5192 LogPrintf(
"Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*
MICRO, (last-mid)*
MICRO);
5193 }
catch (
const std::exception& e) {
5194 LogPrintf(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
5203 if (pindex ==
nullptr)
5206 int64_t nNow = time(
nullptr);
5216 return std::min<double>(pindex->
nChainTx / fTxTotal, 1.0);
5229 std::vector<CChainState*> out;
5244 bool is_snapshot = !snapshot_blockhash.
IsNull();
5245 std::unique_ptr<CChainState>& to_modify =
5249 throw std::logic_error(
"should not be overwriting a chainstate");
5251 to_modify.reset(
new CChainState(mempool, m_blockman, snapshot_blockhash));
5255 LogPrintf(
"Switching active chainstate to %s\n", to_modify->ToString());
5258 throw std::logic_error(
"unexpected chainstate activation");
5289 void ChainstateManager::Unload()
5292 chainstate->m_chain.SetTip(
nullptr);
5293 chainstate->UnloadBlockIndex();
5296 m_blockman.Unload();
5299 void ChainstateManager::Reset()
5307 void ChainstateManager::MaybeRebalanceCaches()
5310 LogPrintf(
"[snapshot] allocating all cache to the IBD chainstate\n");
5315 LogPrintf(
"[snapshot] allocating all cache to the snapshot chainstate\n");
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
static const CAmount COIN
arith_uint256 GetBlockProof(const CBlockIndex &block)
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
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...
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends,...
@ BLOCK_VALID_MASK
All validity bits.
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
@ BLOCK_HAVE_DATA
full block available in blk*.dat
@ BLOCK_FAILED_CHILD
descends from failed block
@ BLOCK_FAILED_VALID
stage after last reached validness failed
@ BLOCK_OPT_WITNESS
block data in blk*.data was received with a witness-enforcing client
static constexpr int64_t MAX_FUTURE_BLOCK_TIME
Maximum amount of time that a block timestamp is allowed to exceed the current network-adjusted time ...
const CChainParams & Params()
Return the currently selected parameters.
std::map< int, uint256 > MapCheckpoints
Abstract class that implements BIP9-style threshold logic, and caches results.
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, ThresholdConditionCache &cache) const
Returns the state for pindex A based on parent pindexPrev B.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
CBlockIndex * AddToBlockIndex(const CBlockHeader &block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::set< CBlockIndex * > m_failed_blocks
In order to efficiently track invalidity of headers, we keep the set of blocks which we tried to conn...
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Clear all data members.
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.
bool AcceptBlockHeader(const CBlockHeader &block, BlockValidationState &state, const CChainParams &chainparams, CBlockIndex **ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
If a block header hasn't already been seen, call CheckBlockHeader on it, ensure that it doesn't desce...
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
void FindFilesToPrune(std::set< int > &setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_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...
Non-refcounted RAII wrapper for FILE*.
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
void read(char *pch, size_t nSize)
uint64_t nTimeFirst
earliest time of block in file
uint64_t nTimeLast
latest time of block in file
std::string ToString() const
unsigned int nHeightFirst
lowest height of block in file
unsigned int nHeightLast
highest height of block in file
unsigned int nBlocks
number of blocks stored in file
unsigned int nSize
number of used bytes of block file
std::vector< CTransactionRef > vtx
The block chain is a tree shaped structure starting with the genesis block at the root,...
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
std::string ToString() const
CBlockIndex * pprev
pointer to the index of the predecessor of this block
void BuildSkip()
Build the skiplist pointer for this entry.
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
int nFile
Which # file this block is stored in (blk?????.dat)
FlatFilePos GetBlockPos() const
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
uint256 GetBlockHash() const
int64_t GetBlockTime() const
int64_t GetMedianTimePast() const
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
unsigned int nTx
Number of transactions in this block.
FlatFilePos GetUndoPos() const
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
int32_t nVersion
block header
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
int nHeight
height of the entry in the chain. The genesis block has height 0
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
The BlockPolicyEstimator is used for estimating the feerate needed for a transaction to be included i...
Access to the block database (blocks/index/)
bool LoadBlockIndexGuts(const Consensus::Params &consensusParams, std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
Undo information for a CBlock.
std::vector< CTxUndo > vtxundo
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from.
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
prevent reading beyond a certain position no argument removes the limit
void FindByte(char ch)
search for a given byte in the stream, and remain positioned on it
uint64_t GetPos() const
return the current reading position
bool SetPos(uint64_t nPos)
rewind to a given reading position
bool eof() const
check whether we're at the end of the source file
An in-memory indexed chain of blocks.
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip).
int Height() const
Return the maximal height in the chain.
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
void SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
const ChainTxData & TxData() const
const CMessageHeader::MessageStartChars & MessageStart() const
const Consensus::Params & GetConsensus() const
uint64_t PruneAfterHeight() const
const CBlock & GenesisBlock() const
CChainState stores and provides an API to update our local knowledge of the current best chain.
int32_t nBlockSequenceId
Blocks loaded from disk are assigned id 0, so start the counter at 1.
bool RewindBlockIndex(const CChainParams ¶ms) LOCKS_EXCLUDED(cs_main)
std::atomic< bool > m_cached_finished_ibd
Whether this chainstate is undergoing initial block download.
arith_uint256 nLastPreciousChainwork
chainwork for the last block that preciousblock has been applied to.
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
RecursiveMutex cs_nBlockSequenceId
Every received block is assigned a unique and increasing identifier, so we know which one to give pri...
const uint256 m_from_snapshot_blockhash
The blockhash which is the base of the snapshot this chainstate was created from.
bool ReplayBlocks(const CChainParams ¶ms)
Replay blocks that aren't fully applied to the database.
bool PreciousBlock(BlockValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void CheckBlockIndex(const Consensus::Params &consensusParams)
Make various assertions about the state of the block index.
bool ActivateBestChain(BlockValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock) LOCKS_EXCLUDED(cs_main)
Make the best chain active, in multiple steps.
RecursiveMutex m_cs_chainstate
the ChainState CriticalSection A lock that must be held when modifying this ChainState - held in Acti...
std::set< CBlockIndex *, CBlockIndexWorkComparator > setBlockIndexCandidates
The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and a...
void PruneAndFlush()
Prune blockfiles from the disk if necessary and then flush chainstate changes if we pruned.
bool ConnectBlock(const CBlock &block, BlockValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, const CChainParams &chainparams, bool fJustCheck=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of this block (with given index) on the UTXO set represented by coins.
bool LoadGenesisBlock(const CChainParams &chainparams)
void PruneBlockIndexCandidates()
Delete all entries in setBlockIndexCandidates that are worse than the current tip.
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
size_t m_coinsdb_cache_size_bytes
The cache size of the on-disk coins view.
CTxMemPool & m_mempool
mempool that is kept in sync with the chain
DisconnectResult DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view)
Undo the effects of this block (with given index) on the UTXO set represented by coins.
void InitCoinsDB(size_t cache_size_bytes, bool in_memory, bool should_wipe, std::string leveldb_name="chainstate")
Initialize the CoinsViews UTXO set database management data structures.
CChainState(CTxMemPool &mempool, BlockManager &blockman, uint256 from_snapshot_blockhash=uint256())
bool ActivateBestChainStep(BlockValidationState &state, const CChainParams &chainparams, 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.
std::unique_ptr< CoinsViews > m_coins_views
Manages the UTXO set, which is a reflection of the contents of m_chain.
void EraseBlockData(CBlockIndex *index) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as not having block data.
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network)
int32_t nBlockReverseSequenceId
Decreasing counter (used by subsequent preciousblock calls).
bool LoadChainTip(const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Update the chain tip based on database information, i.e.
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, const CChainParams ¶ms) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of a block on the utxo cache, ignoring that it may already have been applied.
BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all CChainState instances.
bool InvalidateBlock(BlockValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
bool AcceptBlock(const std::shared_ptr< const CBlock > &pblock, BlockValidationState &state, const CChainParams &chainparams, CBlockIndex **ppindex, bool fRequested, const FlatFilePos *dbp, bool *fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Store block on disk.
bool ConnectTip(BlockValidationState &state, const CChainParams &chainparams, 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.
CChain m_chain
The current chain of blockheaders we consult and build on.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool DisconnectTip(BlockValidationState &state, const CChainParams &chainparams, DisconnectedBlockTransactions *disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Disconnect m_chain's tip.
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
void LoadMempool(const ArgsManager &args)
Load the persisted mempool from disk.
CBlockIndex * FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the tip of the chain with the most work in it, that isn't known to be invalid (it's however fa...
void ReceivedBlockTransactions(const CBlock &block, CBlockIndex *pindexNew, const FlatFilePos &pos, const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
void Add(std::vector< T > &vChecks)
Queue for verifications that have to be performed.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
void SetBestBlock(const uint256 &hashBlock)
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
bool Flush()
Push the modifications applied to this cache to its base.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
void ReallocateCache()
Force a reallocation of the cache map.
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
Abstract view on the open txout dataset.
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
CCoinsView that brings transactions from a mempool into view.
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Fee rate in satoshis per kilobyte: CAmount / kB.
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
CHash256 & Write(Span< const unsigned char > input)
void Finalize(Span< unsigned char > output)
Reads data from an underlying stream, while hashing the read data.
A writer stream (for serialization) that computes a 256-bit hash.
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
void TransactionAddedToMempool(const CTransactionRef &, uint64_t mempool_sequence)
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
void BlockDisconnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void BlockChecked(const CBlock &, const BlockValidationState &)
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
void ChainStateFlushed(const CBlockLocator &)
An outpoint - a combination of a transaction hash and an index n into its vout.
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Check if transaction will be BIP 68 final in the next block to be created.
ScriptError GetScriptError() const
PrecomputedTransactionData * txdata
void swap(CScriptCheck &check)
const CTransaction * ptxTo
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const uint256 & GetHash() const
const std::vector< CTxIn > vin
const uint256 & GetWitnessHash() const
An input of a transaction.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
void AddUnbroadcastTx(const uint256 &txid)
Adds a transaction to the unbroadcast set.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
CTransactionRef get(const uint256 &hash) const
size_t DynamicMemoryUsage() const
std::vector< TxMempoolInfo > infoAll() const
void SetIsLoaded(bool loaded)
Sets the current loaded state.
std::map< uint256, CAmount > mapDeltas
std::set< txiter, CompareIteratorByHash > setEntries
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
bool exists(const GenTxid >xid) const
An output of a transaction.
Undo information for a CTransaction.
std::vector< Coin > vprevout
bool VerifyDB(const CChainParams &chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
CChainState &InitializeChainstate(CTxMemPool &mempool, const uint256 &snapshot_blockhash=uint256()) EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * > GetAll()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
int64_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
bool IsBackgroundIBD(CChainState *chainstate) const
CChainState & ValidatedChainstate() const
Return the most-work chainstate that has been fully validated.
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
int64_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
CChainState * m_active_chainstate
Points to either the ibd or snapshot chainstate; indicates our most-work chain.
std::unique_ptr< CChainState > m_snapshot_chainstate
A chainstate initialized on the basis of a UTXO snapshot.
CChainState & ActiveChainstate() const
The most-work chain.
Optional< uint256 > SnapshotBlockhash() const
friend CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
bool IsSnapshotActive() const
bool m_snapshot_validated
If true, the assumed-valid chainstate has been fully validated by the background validation chainstat...
BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
std::unique_ptr< CChainState > m_ibd_chainstate
The chainstate used under normal operation (i.e.
bool LoadBlockIndex(const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the block tree and coins database from disk, initializing state if we're running with -reindex.
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 IsSnapshotValidated() const
Is there a snapshot in use and has it been fully validated?
CTxOut out
unspent transaction output
uint32_t nHeight
at which height this containing transaction was included in the active block chain
unsigned int fCoinBase
whether containing transaction was a coinbase
CoinsViews(std::string ldb_name, size_t cache_size_bytes, bool in_memory, bool should_wipe)
This constructor initializes CCoinsViewDB and CCoinsViewErrorCatcher instances, but it does not creat...
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
std::vector< PerBlockConnectTrace > blocksConnected
std::vector< PerBlockConnectTrace > & GetBlocksConnected()
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
cache implements a cache with properties similar to a cuckoo-set.
FlatFileSeq represents a sequence of numbered files storing raw data.
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space)
Allocate additional space in a file after the given starting position.
FILE * Open(const FlatFilePos &pos, bool read_only=false)
Open a handle to the file at the given position.
std::string GetRejectReason() const
std::string GetDebugMessage() const
bool Error(const std::string &reject_reason)
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
std::string ToString() const
Threshold condition checker that triggers when unknown versionbits are seen on the network.
int64_t EndTime(const Consensus::Params ¶ms) const override
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
WarningBitsConditionChecker(int bitIn)
int Threshold(const Consensus::Params ¶ms) const override
int64_t BeginTime(const Consensus::Params ¶ms) const override
int Period(const Consensus::Params ¶ms) const override
256-bit unsigned big integer.
std::string ToString() const
void resize(size_type new_size)
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction.
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
static int64_t GetBlockWeight(const CBlock &block)
@ BLOCK_CHECKPOINT
the block failed to meet one of our checkpoints
@ BLOCK_INVALID_HEADER
invalid proof of work or time too old
@ BLOCK_CACHED_INVALID
this block was cached as being invalid and we didn't store the reason why
@ BLOCK_CONSENSUS
invalid by consensus rules (excluding any below reasons)
@ BLOCK_MISSING_PREV
We don't have the previous block the checked one is built on.
@ BLOCK_INVALID_PREV
A block this one builds on is invalid.
@ BLOCK_MUTATED
the block's data didn't match the data committed to by the PoW
@ BLOCK_TIME_FUTURE
block timestamp was > 2 hours in the future (or our clock is bad)
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs,...
@ TX_MISSING_INPUTS
transaction was missing some of its inputs
@ TX_MEMPOOL_POLICY
violated mempool's fee/size/descendant/RBF/etc limits
@ TX_PREMATURE_SPEND
transaction spends a coinbase too early, or violates locktime/sequence locks
@ TX_INPUTS_NOT_STANDARD
inputs (covered by txid) failed policy rules
@ TX_WITNESS_STRIPPED
Transaction is missing a witness.
@ TX_CONFLICT
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
@ TX_NOT_STANDARD
otherwise didn't meet our local policy rules
@ TX_WITNESS_MUTATED
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
@ TX_CONSENSUS
invalid by consensus rules
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
static constexpr unsigned int LOCKTIME_MEDIAN_TIME_PAST
Use GetMedianTimePast() instead of nTime for end point timestamp.
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule)
static const int WITNESS_SCALE_FACTOR
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.
void * memcpy(void *a, const void *b, size_t c)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
@ SCRIPT_VERIFY_NULLDUMMY
@ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY
@ SCRIPT_VERIFY_CLEANSTACK
@ SCRIPT_VERIFY_CHECKSEQUENCEVERIFY
static void LogPrintf(const char *fmt, const Args &... args)
#define LogPrint(category,...)
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, CAmount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts) This does not m...
@ MAX_VERSION_BITS_DEPLOYMENTS
FILE * fopen(const fs::path &p, const char *mode)
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
boost::optional< T > Optional
Substitute for C++17 std::optional.
CFeeRate incrementalRelayFee
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs, bool taproot_active)
Check transaction inputs to mitigate two potential denial-of-service attacks:
bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, const CFeeRate &dust_relay_fee, std::string &reason)
Check for standard transaction types.
bool IsWitnessStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check if the transaction is over standard P2WSH resources limit: 3600bytes witnessScript size,...
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST
The maximum number of sigops we're willing to relay/mine in a single tx.
static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS
Used as the flags parameter to sequence and nLocktime checks in non-consensus code.
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
static const unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE
The minimum non-witness size for transactions we're willing to relay/mine (1 segwit input + 1 P2WPKH ...
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS
For convenience, standard but not mandatory verify flags.
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
static CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
uint256 GetRandHash() noexcept
reverse_range< T > reverse_iterate(T &x)
std::string ScriptErrorString(const ScriptError serror)
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
size_t GetSerializeSize(const T &t, int nVersion=0)
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
static const int64_t MAX_MAX_SIG_CACHE_SIZE
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Display status of an in-progress BIP9 softfork.
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
A mutable version of CTransaction.
std::vector< CTxOut > vout
Holds various statistics on transactions within a chain.
double dTxRate
estimated number of transactions per second after that timestamp
int64_t nTime
UNIX timestamp of last known number of transactions.
int64_t nTxCount
total number of transactions between genesis and that timestamp
Parameters that influence chain consensus.
int BIP65Height
Block height at which BIP65 becomes active.
int CSVHeight
Block height at which CSV (BIP68, BIP112 and BIP113) becomes active.
uint32_t nMinerConfirmationWindow
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
int SegwitHeight
Block height at which Segwit (BIP141, BIP143 and BIP147) becomes active.
int BIP34Height
Block height and hash at which BIP34 becomes active.
int nSubsidyHalvingInterval
int MinBIP9WarningHeight
Don't warn about unknown BIP 9 activations below this height.
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,...
int BIP66Height
Block height at which BIP66 becomes active.
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
indexed_disconnected_transactions queuedTx
void removeForBlock(const std::vector< CTransactionRef > &vtx)
size_t DynamicMemoryUsage() const
void addTransaction(const CTransactionRef &tx)
std::string ToString() const
CBlockIndex * maxInputBlock
std::shared_ptr< const CBlock > pblock
bool m_spent_outputs_ready
Whether m_spent_outputs is initialized.
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs)
std::vector< CTxOut > m_spent_outputs
BIP 9 allows multiple softforks to be deployed in parallel.
#define AssertLockNotHeld(cs)
bool RenameOver(fs::path src, fs::path dest)
const fs::path & GetDataDir(bool fNetSpecific)
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
const fs::path & GetBlocksDir()
bool FileCommit(FILE *file)
bool error(const char *fmt, const Args &... args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define LOCKS_EXCLUDED(...)
int64_t GetTimeMicros()
Returns the system time (not mockable)
int64_t GetTimeMillis()
Returns the system time (not mockable)
std::string FormatISO8601Date(int64_t nTime)
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
int64_t GetAdjustedTime()
#define LOG_TIME_MILLIS_WITH_CATEGORY(end_msg, log_category)
#define LOG_TIME_SECONDS(end_msg)
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
bool CheckTransaction(const CTransaction &tx, TxValidationState &state)
std::pair< int, int64_t > CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Calculates the block height and previous block's median time past at which the transaction will be co...
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, int flags)
Compute total signature operation cost of a transaction.
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block.
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time.
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
@ REPLACED
Removed for replacement.
@ REORG
Removed for reorganization.
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0....
CClientUIInterface uiInterface
constexpr auto AbortError
uint256 uint256S(const char *str)
static const uint32_t MAX_BIP125_RBF_SEQUENCE
static FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
static CSHA256 g_scriptExecutionCacheHasher
bool CheckInputScripts(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData &txdata, std::vector< CScriptCheck > *pvChecks=nullptr)
Check whether all of this transaction's input scripts succeed.
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Determine what nVersion a new block should use.
CBlockPolicyEstimator feeEstimator
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static void FlushUndoFile(int block_file, bool finalize=false)
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
bool LoadGenesisBlock(const CChainParams &chainparams)
Ensures we have a genesis block in the block tree, possibly writing one to disk.
static const uint64_t MEMPOOL_DUMP_VERSION
std::vector< COutPoint > vNoSpendsRemaining
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
static int64_t nTimeCallbacks
static int64_t nTimeConnectTotal
static bool ContextualCheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, const CChainParams ¶ms, const CBlockIndex *pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Context-dependent validity checks.
BIP9Stats VersionBitsTipStatistics(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the numerical statistics for the BIP9 state for a given deployment at the current tip.
void PruneBlockFilesManual(int nManualPruneHeight)
Prune block files up to a given height.
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
std::condition_variable g_best_block_cv
static const unsigned int EXTRA_DESCENDANT_TX_SIZE_LIMIT
An extra transaction can be added to a package, as long as it only has one ancestor and is no larger ...
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE
Maximum kilobytes for transactions to store for processing during reorg.
void LoadExternalBlockFile(const CChainParams &chainparams, FILE *fileIn, FlatFilePos *dbp)
Import blocks from an external file.
bool TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain.
std::vector< uint256 > vHashUpdate
VersionBitsCache versionbitscache GUARDED_BY(cs_main)
static bool AcceptToMemoryPoolWithTime(const CChainParams &chainparams, CTxMemPool &pool, TxValidationState &state, const CTransactionRef &tx, int64_t nAcceptTime, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, bool test_accept, CAmount *fee_out=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
(try to) add transaction to memory pool with a specified acceptance time
static void AlertNotify(const std::string &strMessage)
std::atomic_bool fImporting(false)
static for(const COutPoint &removed :vNoSpendsRemaining) bool IsCurrentForFeeEstimation() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void ResetBlockFailureFlags(CBlockIndex *pindex)
Remove invalidity status from a block and its descendants.
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 fHavePruned
Pruning-related variables and constants.
static int64_t nBlocksTotal
bool g_parallel_script_checks
Whether there are dedicated script-checking threads running.
static int64_t nTimePostConnect
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
static SynchronizationState GetSynchronizationState(bool init)
static bool ContextualCheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
NOTE: This function is not currently invoked by ConnectBlock(), so we should consider upgrade issues ...
static int64_t nTimeFlush
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out)
Restore the UTXO in a Coin at a given COutPoint.
bool InvalidateBlock(BlockValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex)
Mark a block as invalid.
bool DumpMempool(const CTxMemPool &pool)
Dump the mempool to disk.
bool LoadMempool(CTxMemPool &pool)
Load the mempool from disk.
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
uint64_t CalculateCurrentUsage()
BLOCK PRUNING CODE.
static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL
Time to wait between flushing chainstate to disk.
static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown=false)
static FlatFileSeq BlockFileSeq()
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...
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
ChainstateManager g_chainman
static void AppendWarning(bilingual_str &res, const bilingual_str &warn)
Private helper function that concatenates warning messages.
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
static bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams)
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
void UnloadBlockIndex(CTxMemPool *mempool, ChainstateManager &chainman)
Unload database information.
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos, const CMessageHeader::MessageStartChars &message_start)
void InitScriptExecutionCache()
Initializes the script-execution cache.
static int64_t nTimeVerify
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
bool PreciousBlock(BlockValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex)
Mark a block as precious and reorganize.
static void LimitMempoolSize(CTxMemPool &pool, size_t limit, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(pool.cs
static void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
static void UpdateMempoolForReorg(CTxMemPool &mempool, DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main)
void UpdateUncommittedBlockStructures(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Update uncommitted block structures (currently: only the witness reserved value).
void ThreadScriptCheck(int worker_num)
Run an instance of the script checking thread.
AssertLockHeld(mempool.cs)
fs::path GetBlockPosFilename(const FlatFilePos &pos)
Translation to a filesystem path.
static void InvalidChainFound(CBlockIndex *pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, const CMessageHeader::MessageStartChars &messageStart)
std::atomic_bool fReindex(false)
static CBlockIndex * pindexBestForkBase
CBlockIndex * LookupBlockIndex(const uint256 &hash)
static int64_t nTimeTotal
static int64_t nTimeConnect
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
ThresholdState VersionBitsTipState(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the BIP9 state for a given deployment at the current tip.
static bool CheckInputsFromMempoolAndCache(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &view, const CTxMemPool &pool, unsigned int flags, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool CheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE
Maximum age of our tip for us to be considered current for fee estimation.
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
bool TestBlockValidity(BlockValidationState &state, const CChainParams &chainparams, 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)
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.
static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
static int64_t nTimeIndex
static void CheckForkWarningConditionsOnNewFork(CBlockIndex *pindexNewForkTip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool fPruneMode
True if we're running in -prune mode.
static unsigned int GetBlockScriptFlags(const CBlockIndex *pindex, const Consensus::Params &chainparams)
static CuckooCache::cache< uint256, SignatureCacheHasher > g_scriptExecutionCache
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static FILE * OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false)
Open an undo file (rev?????.dat)
static CBlockIndex * pindexBestForkTip
bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
bool ActivateBestChain(BlockValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Find the best known block, and make it the tip of the block chain.
static bool CheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW=true)
static CBlockIndex * GetLastCheckpoint(const CCheckpointData &data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Returns last CBlockIndex* that is a checkpoint.
int VersionBitsTipStateSinceHeight(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the block height at which the BIP9 deployment switched into the state for the block building on t...
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for a block, and whether to enforce NULLDUMMY (BIP 147...
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
static FlatFileSeq UndoFileSeq()
static int64_t nTimeForks
int GetSpendHeight(const CCoinsViewCache &inputs)
Return the spend height, which is one more than the inputs.GetBestBlock().
static int64_t nTimeCheck
static bool LoadBlockIndexDB(ChainstateManager &chainman, const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static void UpdateTip(CTxMemPool &mempool, const CBlockIndex *pindexNew, const CChainParams &chainParams) EXCLUSIVE_LOCKS_REQUIRED(
Check warning conditions and do some notifications on new chain tip set.
static bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, const uint256 &hashBlock, const CMessageHeader::MessageStartChars &messageStart)
static bool IsScriptWitnessEnabled(const Consensus::Params ¶ms)
static bool NotifyHeaderTip() LOCKS_EXCLUDED(cs_main)
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
static bool AbortNode(const std::string &strMessage, bilingual_str user_message=bilingual_str())
Abort with a message.
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL
Time to wait between writing blocks/block index to disk.
static int64_t nTimeChainState
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
static CCheckQueue< CScriptCheck > scriptcheckqueue(128)
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download.
static int64_t nTimeReadFromDisk
static void DoWarning(const bilingual_str &warning)
bool AcceptToMemoryPool(CTxMemPool &pool, TxValidationState &state, const CTransactionRef &tx, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, bool test_accept, CAmount *fee_out)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
static const bool DEFAULT_CHECKPOINTS_ENABLED
static const unsigned int DEFAULT_DESCENDANT_LIMIT
Default for -limitdescendantcount, max number of in-mempool descendants.
VersionBitsCache versionbitscache
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT
Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants.
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ChainActive().Tip() will not be pr...
SynchronizationState
Current sync state passed to tip changed callbacks.
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
static const unsigned int DEFAULT_MEMPOOL_EXPIRY
Default for -mempoolexpiry, expiration time for mempool transactions in hours.
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT
Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors.
@ LARGE
The cache is at >= 90% capacity.
@ CRITICAL
The coins cache is in immediate need of a flush.
static const unsigned int DEFAULT_ANCESTOR_LIMIT
Default for -limitancestorcount, max number of in-mempool ancestors.
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
static const int64_t DEFAULT_MAX_TIP_AGE
static const bool DEFAULT_PERSIST_MEMPOOL
Default for -persistmempool.
static const int DEFAULT_STOPATHEIGHT
Default for -stopatheight.
CMainSignals & GetMainSignals()
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
static const int PROTOCOL_VERSION
network protocol versioning
uint32_t VersionBitsMask(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
BIP9Stats VersionBitsStatistics(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
int VersionBitsStateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
static const int32_t VERSIONBITS_NUM_BITS
Total bits available for versionbits.
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION
What block version to use for new blocks (pre versionbits)
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
void SetfLargeWorkInvalidChainFound(bool flag)
void SetfLargeWorkForkFound(bool flag)
bool GetfLargeWorkForkFound()
void SetMiscWarning(const bilingual_str &warning)