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;
176 BlockMap::const_iterator
it = g_chainman.
BlockIndex().find(hash);
177 return it == g_chainman.
BlockIndex().end() ?
nullptr : it->second;
216 flags = std::max(flags, 0);
235 return IsFinalTx(tx, nBlockHeight, nBlockTime);
262 assert(tip !=
nullptr);
274 std::pair<int, int64_t> lockPair;
275 if (useExistingLockPoints) {
277 lockPair.first = lp->
height;
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;
300 lp->
height = lockPair.first;
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);
340 pool.TrimToSize(limit, &vNoSpendsRemaining);
341 for (
const COutPoint& removed : vNoSpendsRemaining)
385 if (!fAddToMempool || (*it)->IsCoinBase() ||
391 }
else if (mempool.exists((*it)->GetHash())) {
392 vHashUpdate.push_back((*it)->GetHash());
396 disconnectpool.queuedTx.clear();
402 mempool.UpdateTransactionsFromBlock(vHashUpdate);
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) {
529 if (package_fee < ::minRelayTxFee.
GetFee(package_size)) {
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);
1347 if (pindexBestForkTip && ::
ChainActive().Height() - pindexBestForkTip->
nHeight >= 72)
1348 pindexBestForkTip =
nullptr;
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;
1400 if (pfork && (!pindexBestForkTip || pindexNewForkTip->
nHeight > pindexBestForkTip->
nHeight) &&
1402 ::
ChainActive().Height() - pindexNewForkTip->nHeight < 72)
1404 pindexBestForkTip = pindexNewForkTip;
1414 if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
1415 pindexBestInvalid = pindexNew;
1416 if (pindexBestHeader !=
nullptr && pindexBestHeader->
GetAncestor(pindexNew->nHeight) == 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;
1487 g_scriptExecutionCacheHasher.
Write(nonce.
begin(), 32);
1488 g_scriptExecutionCacheHasher.
Write(nonce.
begin(), 32);
1492 size_t nElems = g_scriptExecutionCache.
setup_bytes(nMaxCacheSize);
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());
1533 if (g_scriptExecutionCache.
contains(hashCacheEntry, !cacheFullScriptStore)) {
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()) {
1575 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
1592 if (cacheFullScriptStore && !pvChecks) {
1595 g_scriptExecutionCache.
insert(hashCacheEntry);
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);
1838 nVersion |=
VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
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;
1992 if (!hashAssumeValid.
IsNull()) {
1998 BlockMap::const_iterator
it =
m_blockman.m_block_index.find(hashAssumeValid);
2000 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
2022 int64_t nTime1 =
GetTimeMicros(); nTimeCheck += nTime1 - nTimeStart;
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;
2124 int64_t nTime2 =
GetTimeMicros(); nTimeForks += nTime2 - nTime1;
2125 LogPrint(
BCLog::BENCH,
" - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks *
MILLI / nBlocksTotal);
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);
2209 int64_t nTime3 =
GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
2210 LogPrint(
BCLog::BENCH,
" - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (
unsigned)block.
vtx.size(),
MILLI * (nTime3 - nTime2),
MILLI * (nTime3 - nTime2) / block.
vtx.size(), nInputs <= 1 ? 0 :
MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect *
MICRO, nTimeConnect *
MILLI /
nBlocksTotal);
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__);
2222 int64_t nTime4 =
GetTimeMicros(); nTimeVerify += nTime4 - nTime2;
2223 LogPrint(
BCLog::BENCH,
" - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1,
MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 :
MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify *
MILLI / nBlocksTotal);
2233 setDirtyBlockIndex.insert(pindex);
2240 int64_t nTime5 =
GetTimeMicros(); nTimeIndex += nTime5 - nTime4;
2241 LogPrint(
BCLog::BENCH,
" - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, nTimeIndex *
MILLI / nBlocksTotal);
2243 int64_t nTime6 =
GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
2244 LogPrint(
BCLog::BENCH,
" - Callbacks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime6 - nTime5), nTimeCallbacks * MICRO, nTimeCallbacks *
MILLI / nBlocksTotal);
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);
2454 LOCK(g_best_block_mutex);
2455 g_best_block = pindexNew->GetBlockHash();
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) {
2582 assert(!blocksConnected.back().pindex);
2585 blocksConnected.back().pindex = pindex;
2586 blocksConnected.back().pblock = std::move(pblock);
2587 blocksConnected.emplace_back();
2596 assert(!blocksConnected.back().pindex);
2597 blocksConnected.pop_back();
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;
2627 int64_t nTime2 =
GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
2632 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
2639 nTime3 =
GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
2640 assert(nBlocksTotal > 0);
2641 LogPrint(
BCLog::BENCH,
" - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal);
2642 bool flushed = view.
Flush();
2645 int64_t nTime4 =
GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
2646 LogPrint(
BCLog::BENCH,
" - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
2650 int64_t nTime5 =
GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
2651 LogPrint(
BCLog::BENCH,
" - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
2659 int64_t nTime6 =
GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
2660 LogPrint(
BCLog::BENCH,
" - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
2661 LogPrint(
BCLog::BENCH,
"- Connect block: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime1) * MILLI, nTimeTotal * MICRO, nTimeTotal * MILLI / nBlocksTotal);
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;
2774 while (fContinue && nHeight != pindexMostWork->
nHeight) {
2777 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->
nHeight);
2778 vpindexToConnect.clear();
2779 vpindexToConnect.reserve(nTargetHeight - nHeight);
2781 while (pindexIter && pindexIter->
nHeight != nHeight) {
2782 vpindexToConnect.push_back(pindexIter);
2783 pindexIter = pindexIter->
pprev;
2785 nHeight = nTargetHeight;
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();
3123 while (it !=
m_blockman.m_block_index.end()) {
3134 if (pindex_was_in_chain) {
3150 BlockMap::iterator it =
m_blockman.m_block_index.begin();
3151 while (it !=
m_blockman.m_block_index.end()) {
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;
3199 pindexNew->phashBlock = &((*mi).first);
3200 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
3201 if (miPrev != m_block_index.end())
3203 pindexNew->pprev = (*miPrev).second;
3204 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
3205 pindexNew->BuildSkip();
3207 pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime);
3208 pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) +
GetBlockProof(*pindexNew);
3210 if (pindexBestHeader ==
nullptr || pindexBestHeader->
nChainWork < pindexNew->nChainWork)
3211 pindexBestHeader = pindexNew;
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())
3528 if((block.nVersion < 2 && nHeight >= consensusParams.
BIP34Height) ||
3529 (block.nVersion < 3 && nHeight >= consensusParams.
BIP66Height) ||
3530 (block.nVersion < 4 && nHeight >= consensusParams.
BIP65Height))
3532 strprintf(
"rejected nVersion=0x%08x block", block.nVersion));
3545 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3548 int nLockTimeFlags = 0;
3549 if (nHeight >= consensusParams.
CSVHeight) {
3550 assert(pindexPrev !=
nullptr);
3559 for (
const auto& tx : block.
vtx) {
3560 if (!
IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
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);
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;
3806 if (pindex->
nChainWork < nMinimumChainWork)
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;
3887 indexDummy.phashBlock = &block_hash;
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());
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);
3968 LOCK2(cs_main, cs_LastBlockFile);
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);
4000 LOCK2(cs_main, cs_LastBlockFile);
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;
4150 pindexBestHeader = 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;
4237 if (tip && tip->GetBlockHash() == coins_cache.
GetBestBlock()) {
4250 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4251 tip->GetBlockHash().ToString(),
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);
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) {
4533 if (tip ==
nullptr || tip->
nHeight < nHeight)
break;
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;
4606 pindexBestHeader =
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();
4717 uint256 hash = block.GetHash();
4723 block.hashPrevBlock.ToString());
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());
4864 assert(pindex->
nHeight == nHeight);
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;
5069 if (version != MEMPOOL_DUMP_VERSION) {
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");
std::shared_ptr< const CTransaction > CTransactionRef
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
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) ...
CSHA256 & Write(const unsigned char *data, size_t len)
static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT
Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors.
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
Display status of an in-progress BIP9 softfork.
static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE
Flags for nSequence and nLockTime locks.
const std::vector< std::string > CHECKLEVEL_DOC
Documentation for argument 'checklevel'.
std::vector< Coin > vprevout
int64_t EndTime(const Consensus::Params ¶ms) const override
static constexpr std::chrono::hours MAX_FEE_ESTIMATION_TIP_AGE
Maximum age of our tip for us to be considered current for fee estimation.
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise pro...
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
CBlockIndex * FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the tip of the chain with the most work in it, that isn't known to be invalid (it's however fa...
invalid by consensus rules
bool CheckTxInputs(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, CAmount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts) This does not m...
static const unsigned int DEFAULT_DESCENDANT_LIMIT
Default for -limitdescendantcount, max number of in-mempool descendants.
bool PreciousBlock(BlockValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
bool fPruneMode
True if we're running in -prune mode.
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
bool FileCommit(FILE *file)
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.
static void FlushUndoFile(int block_file, bool finalize=false)
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
std::condition_variable g_best_block_cv
static const uint32_t MAX_BIP125_RBF_SEQUENCE
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
bool Error(const std::string &reject_reason)
SynchronizationState
Current sync state passed to tip changed callbacks.
CChainState * m_active_chainstate
Points to either the ibd or snapshot chainstate; indicates our most-work chain.
static const int WITNESS_SCALE_FACTOR
void Finalize(Span< unsigned char > output)
CChain m_chain
The current chain of blockheaders we consult and build on.
void PruneBlockIndexCandidates()
Delete all entries in setBlockIndexCandidates that are worse than the current tip.
#define LogPrint(category,...)
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
FILE * fopen(const fs::path &p, const char *mode)
int Threshold(const Consensus::Params ¶ms) const override
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
double dTxRate
estimated number of transactions per second after that timestamp
descends from failed block
std::string FormatISO8601Date(int64_t nTime)
CBlockIndex * pprev
pointer to the index of the predecessor of this block
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, ThresholdConditionCache &cache) const
Returns the state for pindex A based on parent pindexPrev B.
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
bool Flush()
Push the modifications applied to this cache to its base.
std::map< int, uint256 > MapCheckpoints
static int64_t nTimeConnectTotal
void CheckBlockIndex(const Consensus::Params &consensusParams)
Make various assertions about the state of the block index.
void BlockDisconnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void swap(CScriptCheck &check)
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
We don't have the previous block the checked one is built on.
int64_t GetTimeMillis()
Returns the system time (not mockable)
static CBlockIndex * pindexBestForkBase
int64_t BeginTime(const Consensus::Params ¶ms) const override
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
The cache is at >= 90% capacity.
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
bool LoadGenesisBlock(const CChainParams &chainparams)
Ensures we have a genesis block in the block tree, possibly writing one to disk.
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
bool LoadMempool(CTxMemPool &pool)
Load the mempool from disk.
std::string GetRejectReason() const
static const uint64_t MEMPOOL_DUMP_VERSION
An in-memory indexed chain of blocks.
bool VerifyDB(const CChainParams &chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
static void AlertNotify(const std::string &strMessage)
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 ...
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
bool fHavePruned
Pruning-related variables and constants.
static FILE * OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false)
Open an undo file (rev?????.dat)
std::atomic_bool fReindex(false)
reverse_range< T > reverse_iterate(T &x)
void SetMiscWarning(const bilingual_str &warning)
static const int64_t DEFAULT_MAX_TIP_AGE
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos, const CMessageHeader::MessageStartChars &message_start)
uint256 GetRandHash() noexcept
static void LogPrintf(const char *fmt, const Args &...args)
int Period(const Consensus::Params ¶ms) const override
invalid proof of work or time too old
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
static const CAmount COIN
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block...
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ChainActive().Tip() will not be pr...
static const unsigned int DEFAULT_ANCESTOR_LIMIT
Default for -limitancestorcount, max number of in-mempool ancestors.
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
transaction was missing some of its inputs
static CSHA256 g_scriptExecutionCacheHasher
static int64_t nTimeForks
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool exists(const GenTxid >xid) const
bool MoneyRange(const CAmount &nValue)
bool DisconnectTip(BlockValidationState &state, const CChainParams &chainparams, DisconnectedBlockTransactions *disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Disconnect m_chain's tip.
const Consensus::Params & GetConsensus() const
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
static CTransactionRef MakeTransactionRef()
CTxOut out
unspent transaction output
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name...
std::string ToString() const
cache implements a cache with properties similar to a cuckoo-set.
stage after last reached validness failed
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
unsigned int fCoinBase
whether containing transaction was a coinbase
The coins cache is in immediate need of a flush.
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
#define LOG_TIME_SECONDS(end_msg)
CChainState stores and provides an API to update our local knowledge of the current best chain...
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
static FlatFileSeq UndoFileSeq()
int BIP66Height
Block height at which BIP66 becomes active.
Optional< uint256 > SnapshotBlockhash() const
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...
CTransactionRef get(const uint256 &hash) const
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network) ...
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
void ReallocateCache()
Force a reallocation of the cache map.
std::vector< CTxOut > m_spent_outputs
std::set< txiter, CompareIteratorByHash > setEntries
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS
For convenience, standard but not mandatory verify flags.
void addTransaction(const CTransactionRef &tx)
static void CheckForkWarningConditionsOnNewFork(CBlockIndex *pindexNewForkTip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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.
FlatFilePos GetUndoPos() const
ScriptError GetScriptError() const
const fs::path & GetBlocksDir()
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out)
Restore the UTXO in a Coin at a given COutPoint.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
size_t DynamicMemoryUsage() const
violated mempool's fee/size/descendant/RBF/etc limits
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.
inputs (covered by txid) failed policy rules
undo data available in rev*.dat
bool eof() const
check whether we're at the end of the source file
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
uint32_t VersionBitsMask(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
int nFile
Which # file this block is stored in (blk?????.dat)
FlatFilePos GetBlockPos() const
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
transaction spends a coinbase too early, or violates locktime/sequence locks
static bool LoadBlockIndexDB(ChainstateManager &chainman, const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction. ...
std::atomic< bool > m_cached_finished_ibd
Whether this chainstate is undergoing initial block download.
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Determine what nVersion a new block should use.
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
CChainState(CTxMemPool &mempool, BlockManager &blockman, uint256 from_snapshot_blockhash=uint256())
int64_t nTime
UNIX timestamp of last known number of transactions.
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule) ...
bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
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...
static CBlockIndex * pindexBestForkTip
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
int CSVHeight
Block height at which CSV (BIP68, BIP112 and BIP113) becomes active.
static void UpdateMempoolForReorg(CTxMemPool &mempool, DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
void ThreadScriptCheck(int worker_num)
Run an instance of the script checking thread.
unsigned int nHeightLast
highest height of block in file
bool DumpMempool(const CTxMemPool &pool)
Dump the mempool to disk.
Reads data from an underlying stream, while hashing the read data.
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.
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
const std::vector< CTxIn > vin
ThresholdState VersionBitsTipState(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the BIP9 state for a given deployment at the current tip.
bool IsWitnessStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check if the transaction is over standard P2WSH resources limit: 3600bytes witnessScript size...
FILE * Open(const FlatFilePos &pos, bool read_only=false)
Open a handle to the file at the given position.
std::vector< TxMempoolInfo > infoAll() const
size_t GetSerializeSize(const T &t, int nVersion=0)
void TransactionAddedToMempool(const CTransactionRef &, uint64_t mempool_sequence)
static bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, const CMessageHeader::MessageStartChars &messageStart)
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.
std::vector< COutPoint > vNoSpendsRemaining
std::string GetDebugMessage() const
std::string ToString() const
void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
static const unsigned int MAX_BLOCK_WEIGHT
The maximum allowed weight for a block, see BIP 141 (network rule)
static feebumper::Result CheckFeeRate(const CWallet &wallet, const CWalletTx &wtx, const CFeeRate &newFeerate, const int64_t maxTxSize, std::vector< bilingual_str > &errors)
Check if the user provided a valid feeRate.
int nSubsidyHalvingInterval
void LoadMempool(const ArgsManager &args)
Load the persisted mempool from disk.
bool RewindBlockIndex(const CChainParams ¶ms) LOCKS_EXCLUDED(cs_main)
int64_t nTxCount
total number of transactions between genesis and that timestamp
int64_t CAmount
Amount in satoshis (Can be negative)
void SetBestBlock(const uint256 &hashBlock)
static 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.
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...
std::vector< uint256 > vHashUpdate
static CuckooCache::cache< uint256, SignatureCacheHasher > g_scriptExecutionCache
void PruneAndFlush()
Prune blockfiles from the disk if necessary and then flush chainstate changes if we pruned...
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...
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Removed for reorganization.
indexed_disconnected_transactions queuedTx
CBlockPolicyEstimator feeEstimator
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
RecursiveMutex m_cs_chainstate
the ChainState CriticalSection A lock that must be held when modifying this ChainState - held in Acti...
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
std::string ToString(const T &t)
Locale-independent version of std::to_string.
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...
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
static const bool DEFAULT_PERSIST_MEMPOOL
Default for -persistmempool.
void SetfLargeWorkInvalidChainFound(bool flag)
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
int Height() const
Return the maximal height in the chain.
bool error(const char *fmt, const Args &...args)
VersionBitsCache versionbitscache GUARDED_BY(cs_main)
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
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 IsSnapshotValidated() const
Is there a snapshot in use and has it been fully validated?
static CBlockIndex * GetLastCheckpoint(const CCheckpointData &data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Returns last CBlockIndex* that is a checkpoint.
bool m_snapshot_validated
If true, the assumed-valid chainstate has been fully validated by the background validation chainstat...
BIP 9 allows multiple softforks to be deployed in parallel.
uint64_t PruneAfterHeight() const
void AddUnbroadcastTx(const uint256 &txid)
Adds a transaction to the unbroadcast set.
uint64_t nTimeFirst
earliest time of block in file
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
void ResetBlockFailureFlags(CBlockIndex *pindex)
Remove invalidity status from a block and its descendants.
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 ...
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...
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
int GetSpendHeight(const CCoinsViewCache &inputs)
Return the spend height, which is one more than the inputs.GetBestBlock().
int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
fs::path GetBlockPosFilename(const FlatFilePos &pos)
Translation to a filesystem path.
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Access to the block database (blocks/index/)
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
static int64_t nTimeChainState
Abstract view on the open txout dataset.
static void LimitMempoolSize(CTxMemPool &pool, size_t limit, std::chrono::seconds age) EXCLUSIVE_LOCKS_REQUIRED(pool.cs
static int64_t nTimeTotal
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
this block was cached as being invalid and we didn't store the reason why
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs, bool taproot_active)
Check transaction inputs to mitigate two potential denial-of-service attacks:
void removeForBlock(const std::vector< CTransactionRef > &vtx)
static constexpr unsigned int LOCKTIME_MEDIAN_TIME_PAST
Use GetMedianTimePast() instead of nTime for end point timestamp.
An input of a transaction.
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
bool LoadGenesisBlock(const CChainParams &chainparams)
int VersionBitsStateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
The BlockPolicyEstimator is used for estimating the feerate needed for a transaction to be included i...
static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
bilingual_str _(const char *psz)
Translation function.
static CCheckQueue< CScriptCheck > scriptcheckqueue(128)
the block failed to meet one of our checkpoints
CChainState & ActiveChainstate() const
The most-work chain.
int BIP34Height
Block height and hash at which BIP34 becomes active.
size_t DynamicMemoryUsage() const
AssertLockHeld(mempool.cs)
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
uint256 uint256S(const char *str)
std::map< uint256, CAmount > mapDeltas
int64_t nPowTargetSpacing
std::string ScriptErrorString(const ScriptError serror)
Abstract class that implements BIP9-style threshold logic, and caches results.
const fs::path & GetDataDir(bool fNetSpecific)
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
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 CheckInputsFromMempoolAndCache(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &view, const CTxMemPool &pool, unsigned int flags, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Holds various statistics on transactions within a chain.
static int64_t nTimeIndex
void Finalize(unsigned char hash[OUTPUT_SIZE])
const std::vector< CTxOut > vout
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT
Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
static const unsigned int DEFAULT_MEMPOOL_EXPIRY
Default for -mempoolexpiry, expiration time for mempool transactions in hours.
const ChainTxData & TxData() const
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
static const int DEFAULT_STOPATHEIGHT
Default for -stopatheight.
CBlockIndex * AddToBlockIndex(const CBlockHeader &block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool contains(const Element &e, const bool erase) const
contains iterates through the hash locations for a given element and checks to see if it is present...
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.
std::shared_ptr< const CBlock > pblock
constexpr auto AbortError
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
const uint256 m_from_snapshot_blockhash
The blockhash which is the base of the snapshot this chainstate was created from. ...
static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main)
CMainSignals & GetMainSignals()
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
unsigned int nHeightFirst
lowest height of block in file
void BuildSkip()
Build the skiplist pointer for this entry.
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 TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
CChainState & ValidatedChainstate() const
Return the most-work chainstate that has been fully validated.
ChainstateManager g_chainman
const CMessageHeader::MessageStartChars & MessageStart() const
An output of a transaction.
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
static bool NotifyHeaderTip() LOCKS_EXCLUDED(cs_main)
void read(char *pch, size_t nSize)
std::unique_ptr< CoinsViews > m_coins_views
Manages the UTXO set, which is a reflection of the contents of m_chain.
bool CheckBlock(const CBlock &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
std::vector< uint256 > vHave
uint32_t nMinerConfirmationWindow
bool SetPos(uint64_t nPos)
rewind to a given reading position
Queue for verifications that have to be performed.
Parameters that influence chain consensus.
void ChainStateFlushed(const CBlockLocator &)
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
An outpoint - a combination of a transaction hash and an index n into its vout.
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
const uint256 & GetWitnessHash() const
arith_uint256 nLastPreciousChainwork
chainwork for the last block that preciousblock has been applied to.
std::pair< int, int64_t > CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Calculates the block height and previous block's median time past at which the transaction will be co...
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download...
256-bit unsigned big integer.
block data in blk*.data was received with a witness-enforcing client
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
static int64_t nTimeCallbacks
CFeeRate incrementalRelayFee
static int64_t nTimeCheck
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
static FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
static int64_t nTimeConnect
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.
int64_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Check if transaction will be BIP 68 final in the next block to be created.
void insert(Element e)
insert loops at most depth_limit times trying to insert a hash at various locations in the table via ...
int BIP65Height
Block height at which BIP65 becomes active.
static int64_t nTimeReadFromDisk
static bool CheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW=true)
std::set< CBlockIndex * > m_failed_blocks
In order to efficiently track invalidity of headers, we keep the set of blocks which we tried to conn...
uint32_t setup_bytes(size_t bytes)
setup_bytes is a convenience function which accounts for internal memory usage when deciding how many...
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
Transaction is missing a witness.
int64_t GetTimeMicros()
Returns the system time (not mockable)
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &block, BlockValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex=nullptr) LOCKS_EXCLUDED(cs_main)
Process incoming block headers.
bool RenameOver(fs::path src, fs::path dest)
static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown=false)
int32_t nBlockSequenceId
Blocks loaded from disk are assigned id 0, so start the counter at 1.
void LoadExternalBlockFile(const CChainParams &chainparams, FILE *fileIn, FlatFilePos *dbp)
Import blocks from an external file.
static void DoWarning(const bilingual_str &warning)
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
CBlockIndex * LookupBlockIndex(const uint256 &hash)
int32_t nVersion
block header
invalid by consensus rules (excluding any below reasons)
const CTransaction * ptxTo
bool g_parallel_script_checks
Whether there are dedicated script-checking threads running.
DisconnectResult DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view)
Undo the effects of this block (with given index) on the UTXO set represented by coins.
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
static void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
static const bool DEFAULT_CHECKPOINTS_ENABLED
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
void SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
bool IsBackgroundIBD(CChainState *chainstate) const
the block's data didn't match the data committed to by the PoW
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
static const int64_t MAX_MAX_SIG_CACHE_SIZE
int32_t nBlockReverseSequenceId
Decreasing counter (used by subsequent preciousblock calls).
size_t m_coinsdb_cache_size_bytes
The cache size of the on-disk coins view.
#define LOCKS_EXCLUDED(...)
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
void FindByte(char ch)
search for a given byte in the stream, and remain positioned on it
The block chain is a tree shaped structure starting with the genesis block at the root...
const CBlock & GenesisBlock() const
const CChainParams & Params()
Return the currently selected parameters.
static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION
What block version to use for new blocks (pre versionbits)
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
friend CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
std::unique_ptr< CChainState > m_snapshot_chainstate
A chainstate initialized on the basis of a UTXO snapshot.
Undo information for a CTransaction.
std::atomic_bool fImporting(false)
void * memcpy(void *a, const void *b, size_t c)
std::vector< PerBlockConnectTrace > blocksConnected
std::vector< unsigned char > GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
bool GetfLargeWorkForkFound()
static const int PROTOCOL_VERSION
network protocol versioning
static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
void InitScriptExecutionCache()
Initializes the script-execution cache.
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
static bool IsScriptWitnessEnabled(const Consensus::Params ¶ms)
bool m_spent_outputs_ready
Whether m_spent_outputs is initialized.
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
A block this one builds on is invalid.
std::unique_ptr< CChainState > m_ibd_chainstate
The chainstate used under normal operation (i.e.
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 ...
bool InvalidateBlock(BlockValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex)
Mark a block as invalid.
void PruneBlockFilesManual(int nManualPruneHeight)
Prune block files up to a given height.
std::set< uint256 > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
int64_t GetAdjustedTime()
static void AppendWarning(bilingual_str &res, const bilingual_str &warn)
Private helper function that concatenates warning messages.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Clear all data members.
static FlatFileSeq BlockFileSeq()
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL
Time to wait between writing blocks/block index to disk.
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.
void EraseBlockData(CBlockIndex *index) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as not having block data.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
std::set< CBlockIndex *, CBlockIndexWorkComparator > setBlockIndexCandidates
The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and a...
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
static int64_t nTimeVerify
static int64_t nTimePostConnect
std::string ToString() const
Fee rate in satoshis per kilobyte: CAmount / kB.
unsigned int nBlocks
number of blocks stored in file
BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all CChainState instances...
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...
#define AssertLockNotHeld(cs)
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
static const unsigned int MAX_STANDARD_TX_SIGOPS_COST
The maximum number of sigops we're willing to relay/mine in a single tx.
std::string ToString() const
std::string ToString() const
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
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...
bool InvalidateBlock(BlockValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
bool LoadBlockIndexGuts(const Consensus::Params &consensusParams, std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
int MinBIP9WarningHeight
Don't warn about unknown BIP 9 activations below this height.
static for(const COutPoint &removed:vNoSpendsRemaining) bool IsCurrentForFeeEstimation() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
A mutable version of CTransaction.
A writer stream (for serialization) that computes a 256-bit hash.
CTxMemPool & m_mempool
mempool that is kept in sync with the chain
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period...
const uint256 & GetHash() const
block timestamp was > 2 hours in the future (or our clock is bad)
bool IsSnapshotActive() const
static bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams)
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time...
std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
uint64_t nTimeLast
latest time of block in file
int SegwitHeight
Block height at which Segwit (BIP141, BIP143 and BIP147) becomes active.
void Add(std::vector< T > &vChecks)
arith_uint256 GetBlockProof(const CBlockIndex &block)
void UnloadBlockIndex(CTxMemPool *mempool, ChainstateManager &chainman)
Unload database information.
static bool AbortNode(const std::string &strMessage, bilingual_str user_message=bilingual_str())
Abort with a message.
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 ...
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
CClientUIInterface uiInterface
The basic transaction that is broadcasted on the network and contained in blocks. ...
int nHeight
height of the entry in the chain. The genesis block has height 0
boost::optional< T > Optional
Substitute for C++17 std::optional.
WarningBitsConditionChecker(int bitIn)
bool SetLimit(uint64_t nPos=std::numeric_limits< uint64_t >::max())
prevent reading beyond a certain position no argument removes the limit
int64_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
BIP9Stats VersionBitsStatistics(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE
Maximum kilobytes for transactions to store for processing during reorg.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
std::vector< PerBlockConnectTrace > & GetBlocksConnected()
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
full block available in blk*.dat
bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, const CFeeRate &dust_relay_fee, std::string &reason)
Check for standard transaction types.
#define LOG_TIME_MILLIS_WITH_CATEGORY(end_msg, log_category)
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs)
bool ReplayBlocks(const CChainParams ¶ms)
Replay blocks that aren't fully applied to the database.
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from...
int64_t GetBlockTime() const
int GetWitnessCommitmentIndex(const CBlock &block)
Compute at which vout of the block's coinbase transaction the witness commitment occurs, or -1 if not found.
A hasher class for SHA-256.
uint64_t CalculateCurrentUsage()
BLOCK PRUNING CODE.
bool LoadChainTip(const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Update the chain tip based on database information, i.e.
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).
int64_t GetTime()
Return system time (or mocked time, if set)
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
std::vector< CTxUndo > vtxundo
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 SynchronizationState GetSynchronizationState(bool init)
void SetIsLoaded(bool loaded)
Sets the current loaded state.
static int64_t GetBlockWeight(const CBlock &block)
void InitCoinsDB(size_t cache_size_bytes, bool in_memory, bool should_wipe, std::string leveldb_name="chainstate")
Initialize the CoinsViews UTXO set database management data structures.
bool PreciousBlock(BlockValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex)
Mark a block as precious and reorganize.
FlatFileSeq represents a sequence of numbered files storing raw data.
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
void SetfLargeWorkForkFound(bool flag)
static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS
Used as the flags parameter to sequence and nLocktime checks in non-consensus code.
static const int32_t VERSIONBITS_NUM_BITS
Total bits available for versionbits.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
bool CheckTransaction(const CTransaction &tx, TxValidationState &state)
CBlockIndex * maxInputBlock
VersionBitsCache versionbitscache
int64_t GetMedianTimePast() const
static int64_t nBlocksTotal
static bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, const uint256 &hashBlock, const CMessageHeader::MessageStartChars &messageStart)
CCoinsView that brings transactions from a mempool into view.
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, int flags)
Compute total signature operation cost of a transaction.
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
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.
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight) EXCLUSIVE_LOCKS_REQUIRED(cs)
Called when a block is connected.
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static int64_t nTimeFlush
void BlockChecked(const CBlock &, const BlockValidationState &)
static unsigned int GetBlockScriptFlags(const CBlockIndex *pindex, const Consensus::Params &chainparams)
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
CHash256 & Write(Span< const unsigned char > input)
otherwise didn't meet our local policy rules
RecursiveMutex cs_nBlockSequenceId
Every received block is assigned a unique and increasing identifier, so we know which one to give pri...
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
unsigned int nTx
Number of transactions in this block.
bool 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.
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
void UpdateUncommittedBlockStructures(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Update uncommitted block structures (currently: only the witness reserved value). ...
Non-refcounted RAII wrapper for FILE*.
static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL
Time to wait between flushing chainstate to disk.
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...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
Return the time it would take to redo the work difference between from and to, assuming the current h...
uint256 GetBlockHash() const
static void InvalidChainFound(CBlockIndex *pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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...
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
uint64_t GetPos() const
return the current reading position
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
Threshold condition checker that triggers when unknown versionbits are seen on the network...