85 #define MICRO 0.000001 97 "level 0 reads the blocks from disk",
98 "level 1 verifies block validity",
99 "level 2 verifies undo data",
100 "level 3 checks disconnection of tip blocks",
101 "level 4 tries to reconnect the blocks",
102 "each level includes the checks of the previous levels",
157 std::vector<CScriptCheck>* pvChecks =
nullptr)
170 const int nBlockHeight = active_chain_tip.nHeight + 1;
177 const int64_t nBlockTime{active_chain_tip.GetMedianTimePast()};
179 return IsFinalTx(tx, nBlockHeight, nBlockTime);
186 bool useExistingLockPoints)
200 std::pair<int, int64_t> lockPair;
201 if (useExistingLockPoints) {
204 lockPair.second =
lp->
time;
207 std::vector<int> prevheights;
208 prevheights.resize(tx.
vin.size());
209 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
210 const CTxIn& txin = tx.
vin[txinIndex];
213 return error(
"%s: Missing input", __func__);
217 prevheights[txinIndex] = tip->
nHeight + 1;
219 prevheights[txinIndex] = coin.
nHeight;
225 lp->
time = lockPair.second;
239 int maxInputHeight = 0;
240 for (
const int height : prevheights) {
242 if (height != tip->
nHeight+1) {
243 maxInputHeight = std::max(maxInputHeight, height);
265 int expired = pool.Expire(GetTime<std::chrono::seconds>() - pool.m_expiry);
270 std::vector<COutPoint> vNoSpendsRemaining;
271 pool.TrimToSize(pool.m_max_size_bytes, &vNoSpendsRemaining);
272 for (
const COutPoint& removed : vNoSpendsRemaining)
273 coins_cache.Uncache(removed);
279 if (active_chainstate.IsInitialBlockDownload())
283 if (active_chainstate.m_chain.Height() < active_chainstate.m_chainman.m_best_header->nHeight - 1) {
297 std::vector<uint256> vHashUpdate;
307 if (!fAddToMempool || (*it)->IsCoinBase() ||
315 vHashUpdate.push_back((*it)->GetHash());
350 }
else if (!validLP) {
357 if (it->GetSpendsCoinbase()) {
358 for (
const CTxIn& txin : tx.vin) {
365 if (coin.IsCoinBase() && mempool_spend_height - coin.nHeight <
COINBASE_MATURITY) {
400 if (coin.
IsSpent())
return false;
412 const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.
prevout);
427 explicit MemPoolAccept(
CTxMemPool& mempool,
Chainstate& active_chainstate) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&active_chainstate.CoinsTip(), m_pool), m_active_chainstate(active_chainstate),
428 m_limit_ancestors(m_pool.m_limits.ancestor_count),
429 m_limit_ancestor_size(m_pool.m_limits.ancestor_size_vbytes),
430 m_limit_descendants(m_pool.m_limits.descendant_count),
431 m_limit_descendant_size(m_pool.m_limits.descendant_size_vbytes) {
438 const int64_t m_accept_time;
439 const bool m_bypass_limits;
447 std::vector<COutPoint>& m_coins_to_uncache;
448 const bool m_test_accept;
452 const bool m_allow_replacement;
457 const bool m_package_submission;
461 const bool m_package_feerates;
464 static ATMPArgs SingleAccept(
const CChainParams& chainparams, int64_t accept_time,
465 bool bypass_limits, std::vector<COutPoint>& coins_to_uncache,
467 return ATMPArgs{ chainparams,
479 static ATMPArgs PackageTestAccept(
const CChainParams& chainparams, int64_t accept_time,
480 std::vector<COutPoint>& coins_to_uncache) {
481 return ATMPArgs{ chainparams,
493 static ATMPArgs PackageChildWithParents(
const CChainParams& chainparams, int64_t accept_time,
494 std::vector<COutPoint>& coins_to_uncache) {
495 return ATMPArgs{ chainparams,
507 static ATMPArgs SingleInPackageAccept(
const ATMPArgs& package_args) {
508 return ATMPArgs{ package_args.m_chainparams,
509 package_args.m_accept_time,
511 package_args.m_coins_to_uncache,
512 package_args.m_test_accept,
525 std::vector<COutPoint>& coins_to_uncache,
527 bool allow_replacement,
528 bool package_submission,
529 bool package_feerates)
530 : m_chainparams{chainparams},
531 m_accept_time{accept_time},
532 m_bypass_limits{bypass_limits},
533 m_coins_to_uncache{coins_to_uncache},
534 m_test_accept{test_accept},
535 m_allow_replacement{allow_replacement},
536 m_package_submission{package_submission},
537 m_package_feerates{package_feerates}
562 explicit Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
564 std::set<uint256> m_conflicts;
574 std::unique_ptr<CTxMemPoolEntry> m_entry;
578 std::list<CTransactionRef> m_replaced_transactions;
590 size_t m_conflicting_size{0};
612 bool PackageMempoolChecks(
const std::vector<CTransactionRef>& txns,
635 std::map<const uint256, const MempoolAcceptResult>& results)
643 CAmount mempoolRejectFee = m_pool.GetMinFee().GetFee(package_size);
644 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
648 if (package_fee < m_pool.m_min_relay_feerate.GetFee(package_size)) {
650 strprintf(
"%d < %d", package_fee, m_pool.m_min_relay_feerate.GetFee(package_size)));
664 const size_t m_limit_ancestors;
665 const size_t m_limit_ancestor_size;
668 size_t m_limit_descendants;
669 size_t m_limit_descendant_size;
675 bool MemPoolAccept::PreChecks(ATMPArgs&
args, Workspace& ws)
681 const uint256& hash = ws.m_hash;
684 const int64_t nAcceptTime =
args.m_accept_time;
685 const bool bypass_limits =
args.m_bypass_limits;
686 std::vector<COutPoint>& coins_to_uncache =
args.m_coins_to_uncache;
690 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
702 if (m_pool.m_require_standard && !
IsStandardTx(tx, m_pool.m_max_datacarrier_bytes, m_pool.m_permit_bare_multisig, m_pool.m_dust_relay_feerate, reason)) {
733 if (ptxConflicting) {
734 if (!
args.m_allow_replacement) {
738 if (!ws.m_conflicts.count(ptxConflicting->
GetHash()))
754 ws.m_conflicts.insert(ptxConflicting->
GetHash());
760 m_view.SetBackend(m_viewmempool);
766 coins_to_uncache.push_back(txin.
prevout);
772 if (!m_view.HaveCoin(txin.
prevout)) {
774 for (
size_t out = 0; out < tx.
vout.size(); out++) {
787 m_view.GetBestBlock();
792 m_view.SetBackend(m_dummy);
794 assert(m_active_chainstate.m_blockman.LookupBlockIndex(m_view.GetBestBlock()) == m_active_chainstate.m_chain.Tip());
815 if (tx.HasWitness() && m_pool.m_require_standard && !
IsWitnessStandard(tx, m_view)) {
822 ws.m_modified_fees = ws.m_base_fees;
823 m_pool.ApplyDelta(hash, ws.m_modified_fees);
827 bool fSpendsCoinbase =
false;
828 for (
const CTxIn &txin : tx.vin) {
829 const Coin &coin = m_view.AccessCoin(txin.
prevout);
831 fSpendsCoinbase =
true;
836 entry.reset(
new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
837 fSpendsCoinbase, nSigOpsCost,
lp));
838 ws.m_vsize = entry->GetTxSize();
847 if (!bypass_limits && !
args.m_package_feerates && !
CheckFeeRate(ws.m_vsize, ws.m_modified_fees, state))
return false;
849 ws.m_iters_conflicting = m_pool.GetIterSet(ws.m_conflicts);
851 if (ws.m_conflicts.size() == 1) {
879 assert(ws.m_iters_conflicting.size() == 1);
882 m_limit_descendants += 1;
883 m_limit_descendant_size += conflict->GetSizeWithDescendants();
886 std::string errString;
887 if (!m_pool.CalculateMemPoolAncestors(*entry, ws.m_ancestors, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants, m_limit_descendant_size, errString)) {
888 ws.m_ancestors.clear();
890 std::string dummy_err_string;
903 !m_pool.CalculateMemPoolAncestors(*entry, ws.m_ancestors, 2, m_limit_ancestor_size, m_limit_descendants + 1, m_limit_descendant_size +
EXTRA_DESCENDANT_TX_SIZE_LIMIT, dummy_err_string)) {
918 m_rbf = !ws.m_conflicts.empty();
922 bool MemPoolAccept::ReplacementChecks(Workspace& ws)
928 const uint256& hash = ws.m_hash;
931 CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize);
946 if (
const auto err_string{
GetEntriesForConflicts(tx, m_pool, ws.m_iters_conflicting, ws.m_all_conflicting)}) {
948 "too many potential replacements", *err_string);
953 "replacement-adds-unconfirmed", *err_string);
958 ws.m_conflicting_fees += it->GetModifiedFee();
959 ws.m_conflicting_size += it->GetTxSize();
961 if (
const auto err_string{
PaysForRBF(ws.m_conflicting_fees, ws.m_modified_fees, ws.m_vsize,
962 m_pool.m_incremental_relay_feerate, hash)}) {
968 bool MemPoolAccept::PackageMempoolChecks(
const std::vector<CTransactionRef>& txns,
975 assert(std::all_of(txns.cbegin(), txns.cend(), [
this](
const auto& tx)
978 std::string err_string;
979 if (!m_pool.CheckPackageLimits(txns, m_limit_ancestors, m_limit_ancestor_size, m_limit_descendants,
980 m_limit_descendant_size, err_string)) {
987 bool MemPoolAccept::PolicyScriptChecks(
const ATMPArgs&
args, Workspace& ws)
998 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, ws.m_precomputed_txdata)) {
1015 bool MemPoolAccept::ConsensusScriptChecks(
const ATMPArgs&
args, Workspace& ws)
1020 const uint256& hash = ws.m_hash;
1038 unsigned int currentBlockScriptVerifyFlags{
GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
1040 ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
1041 LogPrintf(
"BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.
ToString(), state.
ToString());
1048 bool MemPoolAccept::Finalize(
const ATMPArgs&
args, Workspace& ws)
1053 const uint256& hash = ws.m_hash;
1055 const bool bypass_limits =
args.m_bypass_limits;
1057 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
1063 it->GetTx().GetHash().ToString(),
1065 FormatMoney(ws.m_modified_fees - ws.m_conflicting_fees),
1066 (int)entry->GetTxSize() - (int)ws.m_conflicting_size);
1067 ws.m_replaced_transactions.push_back(it->GetSharedTx());
1077 bool validForFeeEstimation = !bypass_limits && !
args.m_package_submission &&
IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
1080 m_pool.addUnchecked(*entry, ws.m_ancestors, validForFeeEstimation);
1086 if (!
args.m_package_submission && !bypass_limits) {
1094 bool MemPoolAccept::SubmitPackage(
const ATMPArgs&
args, std::vector<Workspace>& workspaces,
1096 std::map<const uint256, const MempoolAcceptResult>& results)
1102 assert(std::all_of(workspaces.cbegin(), workspaces.cend(), [
this](
const auto& ws){
1103 return !m_pool.exists(
GenTxid::Txid(ws.m_ptx->GetHash())); }));
1105 bool all_submitted =
true;
1110 for (Workspace& ws : workspaces) {
1111 if (!ConsensusScriptChecks(
args, ws)) {
1115 all_submitted =
false;
1117 strprintf(
"BUG! PolicyScriptChecks succeeded but ConsensusScriptChecks failed: %s",
1118 ws.m_ptx->GetHash().ToString()));
1123 std::string unused_err_string;
1124 if(!m_pool.CalculateMemPoolAncestors(*ws.m_entry, ws.m_ancestors, m_limit_ancestors,
1125 m_limit_ancestor_size, m_limit_descendants,
1126 m_limit_descendant_size, unused_err_string)) {
1130 all_submitted =
false;
1132 strprintf(
"BUG! Mempool ancestors or descendants were underestimated: %s",
1133 ws.m_ptx->GetHash().ToString()));
1140 if (!Finalize(
args, ws)) {
1144 all_submitted =
false;
1146 strprintf(
"BUG! Adding to mempool failed: %s", ws.m_ptx->GetHash().ToString()));
1156 for (Workspace& ws : workspaces) {
1158 results.emplace(ws.m_ptx->GetWitnessHash(),
1162 all_submitted =
false;
1167 return all_submitted;
1188 if (
args.m_test_accept) {
1207 std::vector<Workspace> workspaces{};
1208 workspaces.reserve(txns.size());
1209 std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
1210 [](
const auto& tx) {
return Workspace(tx); });
1211 std::map<const uint256, const MempoolAcceptResult> results;
1216 for (Workspace& ws : workspaces) {
1217 if (!PreChecks(
args, ws)) {
1228 m_viewmempool.PackageAddTransaction(ws.m_ptx);
1234 const auto m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
1235 [](int64_t
sum,
auto& ws) {
return sum + ws.m_vsize; });
1236 const auto m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(),
CAmount{0},
1237 [](
CAmount sum,
auto& ws) {
return sum + ws.m_modified_fees; });
1238 const CFeeRate package_feerate(m_total_modified_fees, m_total_vsize);
1240 if (
args.m_package_feerates &&
1241 !
CheckFeeRate(m_total_vsize, m_total_modified_fees, placeholder_state)) {
1249 std::string err_string;
1250 if (txns.size() > 1 && !PackageMempoolChecks(txns, package_state)) {
1254 for (Workspace& ws : workspaces) {
1255 if (!PolicyScriptChecks(
args, ws)) {
1261 if (
args.m_test_accept) {
1264 results.emplace(ws.m_ptx->GetWitnessHash(),
1266 ws.m_vsize, ws.m_base_fees));
1272 if (!SubmitPackage(
args, workspaces, package_state, results)) {
1299 assert(package.size() > 1);
1302 const auto& child = package.back();
1303 std::unordered_set<uint256, SaltedTxidHasher> unconfirmed_parent_txids;
1304 std::transform(package.cbegin(), package.cend() - 1,
1305 std::inserter(unconfirmed_parent_txids, unconfirmed_parent_txids.end()),
1306 [](
const auto& tx) {
return tx->
GetHash(); });
1313 const CCoinsViewCache& coins_tip_cache = m_active_chainstate.CoinsTip();
1314 for (
const auto& input : child->vin) {
1315 if (!coins_tip_cache.HaveCoinInCache(input.prevout)) {
1316 args.m_coins_to_uncache.push_back(input.prevout);
1322 m_view.SetBackend(m_active_chainstate.CoinsTip());
1323 const auto package_or_confirmed = [
this, &unconfirmed_parent_txids](
const auto& input) {
1324 return unconfirmed_parent_txids.count(input.prevout.hash) > 0 || m_view.HaveCoin(input.prevout);
1326 if (!std::all_of(child->vin.cbegin(), child->vin.cend(), package_or_confirmed)) {
1332 m_view.SetBackend(m_dummy);
1335 std::map<const uint256, const MempoolAcceptResult> results;
1344 ATMPArgs single_args = ATMPArgs::SingleInPackageAccept(
args);
1345 bool quit_early{
false};
1346 std::vector<CTransactionRef> txns_new;
1347 for (
const auto& tx : package) {
1349 const auto& txid = tx->
GetHash();
1355 auto iter = m_pool.GetIter(txid);
1356 assert(iter != std::nullopt);
1366 auto iter = m_pool.GetIter(txid);
1367 assert(iter != std::nullopt);
1373 const auto single_res = AcceptSingleTransaction(tx, single_args);
1378 results.emplace(wtxid, single_res);
1392 txns_new.push_back(tx);
1398 if (quit_early || txns_new.empty()) {
1403 auto submission_result = AcceptMultipleTransactions(txns_new,
args);
1405 for (
const auto& [wtxid, mempoolaccept_res] : results) {
1406 submission_result.m_tx_results.emplace(wtxid, mempoolaccept_res);
1408 if (submission_result.m_state.IsValid())
assert(submission_result.m_package_feerate.has_value());
1409 return submission_result;
1415 int64_t accept_time,
bool bypass_limits,
bool test_accept)
1419 const CChainParams& chainparams{active_chainstate.m_params};
1420 assert(active_chainstate.GetMempool() !=
nullptr);
1421 CTxMemPool& pool{*active_chainstate.GetMempool()};
1423 std::vector<COutPoint> coins_to_uncache;
1424 auto args = MemPoolAccept::ATMPArgs::SingleAccept(chainparams, accept_time, bypass_limits, coins_to_uncache, test_accept);
1432 for (
const COutPoint& hashTx : coins_to_uncache)
1433 active_chainstate.CoinsTip().Uncache(hashTx);
1442 const Package& package,
bool test_accept)
1445 assert(!package.empty());
1446 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){
return tx !=
nullptr;}));
1448 std::vector<COutPoint> coins_to_uncache;
1453 auto args = MemPoolAccept::ATMPArgs::PackageTestAccept(chainparams,
GetTime(), coins_to_uncache);
1454 return MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package,
args);
1456 auto args = MemPoolAccept::ATMPArgs::PackageChildWithParents(chainparams,
GetTime(), coins_to_uncache);
1457 return MemPoolAccept(pool, active_chainstate).AcceptPackage(package,
args);
1462 if (test_accept || result.m_state.IsInvalid()) {
1463 for (
const COutPoint& hashTx : coins_to_uncache) {
1482 nSubsidy >>= halvings;
1488 size_t cache_size_bytes,
1490 bool should_wipe) : m_dbview(
1491 gArgs.GetDataDirNet() / ldb_name, cache_size_bytes, in_memory, should_wipe),
1492 m_catcherview(&m_dbview) {}
1494 void CoinsViews::InitCache()
1497 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
1504 std::optional<uint256> from_snapshot_blockhash)
1505 : m_mempool(mempool),
1506 m_blockman(blockman),
1507 m_params(chainman.GetParams()),
1508 m_chainman(chainman),
1509 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1512 size_t cache_size_bytes,
1522 leveldb_name, cache_size_bytes, in_memory, should_wipe);
1525 void Chainstate::InitCoinsCache(
size_t cache_size_bytes)
1538 bool Chainstate::IsInitialBlockDownload()
const 1555 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1564 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1565 if (strCmd.empty())
return;
1570 std::string singleQuote(
"'");
1572 safeStatus = singleQuote+safeStatus+singleQuote;
1575 std::thread
t(runCommand, strCmd);
1586 if (IsInitialBlockDownload()) {
1591 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1609 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
1614 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
1669 if (!setup_results)
return false;
1671 const auto [num_elems, approx_size_bytes] = *setup_results;
1672 LogPrintf(
"Using %zu MiB out of %zu MiB requested for script execution cache, able to store %zu elements\n",
1673 approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
1699 std::vector<CScriptCheck>* pvChecks)
1704 pvChecks->reserve(tx.
vin.size());
1721 std::vector<CTxOut> spent_outputs;
1722 spent_outputs.reserve(tx.
vin.size());
1724 for (
const auto& txin : tx.
vin) {
1728 spent_outputs.emplace_back(coin.
out);
1730 txdata.
Init(tx, std::move(spent_outputs));
1734 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1746 check.
swap(pvChecks->back());
1747 }
else if (!check()) {
1775 if (cacheFullScriptStore && !pvChecks) {
1787 return state.
Error(strMessage);
1801 if (view.
HaveCoin(out)) fClean =
false;
1803 if (undo.nHeight == 0) {
1809 undo.nHeight = alternate.
nHeight;
1820 view.
AddCoin(out, std::move(undo), !fClean);
1834 error(
"DisconnectBlock(): failure reading undo data");
1838 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1839 error(
"DisconnectBlock(): block and undo data inconsistent");
1844 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1851 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1852 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1855 bool is_spent = view.
SpendCoin(out, &coin);
1866 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1869 for (
unsigned int j = tx.
vin.size(); j > 0;) {
1924 static std::array<ThresholdConditionCache, VERSIONBITS_NUM_BITS> warningcache
GUARDED_BY(
cs_main);
2009 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
2011 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
2028 bool fScriptChecks =
true;
2037 if (it->second.GetAncestor(pindex->
nHeight) == pindex &&
2072 bool fEnforceBIP30 = !((pindex->
nHeight==91842 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
2073 (pindex->
nHeight==91880 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
2101 static constexpr
int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
2138 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
2139 for (
const auto& tx : block.
vtx) {
2140 for (
size_t o = 0; o < tx->
vout.size(); o++) {
2142 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
2150 int nLockTimeFlags = 0;
2169 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
2171 std::vector<int> prevheights;
2174 int64_t nSigOpsCost = 0;
2175 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
2176 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2180 nInputs += tx.
vin.size();
2194 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n", __func__);
2201 prevheights.resize(tx.
vin.size());
2202 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2206 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
2207 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
2218 LogPrintf(
"ERROR: ConnectBlock(): too many sigops\n");
2224 std::vector<CScriptCheck> vChecks;
2225 bool fCacheResults = fJustCheck;
2231 return error(
"ConnectBlock(): CheckInputScripts on %s failed with %s",
2234 control.
Add(vChecks);
2247 if (block.
vtx[0]->GetValueOut() > blockReward) {
2248 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.
vtx[0]->GetValueOut(), blockReward);
2252 if (!control.
Wait()) {
2253 LogPrintf(
"ERROR: %s: CheckQueue failed\n", __func__);
2280 TRACE6(validation, block_connected,
2295 return this->GetCoinsCacheSizeState(
2301 size_t max_coins_cache_size_bytes,
2302 size_t max_mempool_size_bytes)
2307 int64_t nTotalSpace =
2308 max_coins_cache_size_bytes + std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
2311 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
2312 int64_t large_threshold =
2313 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2315 if (cacheSize > nTotalSpace) {
2316 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
2318 }
else if (cacheSize > large_threshold) {
2327 int nManualPruneHeight)
2330 assert(this->CanFlushToDisk());
2331 static std::chrono::microseconds nLastWrite{0};
2332 static std::chrono::microseconds nLastFlush{0};
2333 std::set<int> setFilesToPrune;
2334 bool full_flush_completed =
false;
2341 bool fFlushForPrune =
false;
2342 bool fDoFullFlush =
false;
2350 std::optional<std::string> limiting_lock;
2352 for (
const auto& prune_lock :
m_blockman.m_prune_locks) {
2353 if (prune_lock.second.height_first == std::numeric_limits<int>::max())
continue;
2356 last_prune = std::max(1, std::min(last_prune, lock_height));
2357 if (last_prune == lock_height) {
2358 limiting_lock = prune_lock.first;
2362 if (limiting_lock) {
2363 LogPrint(
BCLog::PRUNE,
"%s limited pruning to height %d\n", limiting_lock.value(), last_prune);
2366 if (nManualPruneHeight > 0) {
2376 if (!setFilesToPrune.empty()) {
2377 fFlushForPrune =
true;
2379 m_blockman.m_block_tree_db->WriteFlag(
"prunedblockfiles",
true);
2384 const auto nNow = GetTime<std::chrono::microseconds>();
2386 if (nLastWrite.count() == 0) {
2389 if (nLastFlush.count() == 0) {
2401 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2403 if (fDoFullFlush || fPeriodicWrite) {
2406 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2420 return AbortNode(state,
"Failed to write to block index database");
2424 if (fFlushForPrune) {
2432 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2442 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2446 return AbortNode(state,
"Failed to write to coin database");
2448 full_flush_completed =
true;
2452 (uint64_t)coins_count,
2453 (uint64_t)coins_mem_usage,
2454 (bool)fFlushForPrune);
2457 if (full_flush_completed) {
2461 }
catch (
const std::runtime_error& e) {
2462 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2486 static bool fWarned =
false;
2505 const std::string& func_name,
2506 const std::string&
prefix,
2511 LogPrintf(
"%s%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n",
2513 tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion,
2514 log(tip->nChainWork.getdouble()) / log(2.0), (
unsigned long)tip->nChainTx,
2517 coins_tip.DynamicMemoryUsage() * (1.0 / (1 << 20)),
2518 coins_tip.GetCacheSize(),
2519 !warning_messages.empty() ?
strprintf(
" warning='%s'", warning_messages) :
"");
2522 void Chainstate::UpdateTip(
const CBlockIndex* pindexNew)
2525 const auto& coins_tip = this->
CoinsTip();
2531 constexpr
int BACKGROUND_LOG_INTERVAL = 2000;
2532 if (pindexNew->
nHeight % BACKGROUND_LOG_INTERVAL == 0) {
2550 if (!this->IsInitialBlockDownload()) {
2587 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2590 return error(
"DisconnectTip(): Failed to read block");
2597 if (DisconnectBlock(block, pindexDelete, view) !=
DISCONNECT_OK)
2599 bool flushed = view.
Flush();
2606 const int max_height_first{pindexDelete->
nHeight - 1};
2607 for (
auto& prune_lock :
m_blockman.m_prune_locks) {
2608 if (prune_lock.second.height_first <= max_height_first)
continue;
2610 prune_lock.second.height_first = max_height_first;
2611 LogPrint(
BCLog::PRUNE,
"%s prune lock moved back to %d\n", prune_lock.first, max_height_first);
2622 for (
auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
2635 UpdateTip(pindexDelete->
pprev);
2702 std::shared_ptr<const CBlock> pthisBlock;
2704 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2706 return AbortNode(state,
"Failed to read block");
2708 pthisBlock = pblockNew;
2711 pthisBlock = pblock;
2713 const CBlock& blockConnecting = *pthisBlock;
2720 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view);
2730 bool flushed = view.
Flush();
2748 UpdateTip(pindexNew);
2779 bool fInvalidAncestor =
false;
2789 if (fFailedChain || fMissingData) {
2796 while (pindexTest != pindexFailed) {
2799 }
else if (fMissingData) {
2804 std::make_pair(pindexFailed->
pprev, pindexFailed));
2807 pindexFailed = pindexFailed->
pprev;
2810 fInvalidAncestor =
true;
2813 pindexTest = pindexTest->
pprev;
2815 if (!fInvalidAncestor)
2847 bool fBlocksDisconnected =
false;
2858 AbortNode(state,
"Failed to disconnect block; see debug.log for details");
2861 fBlocksDisconnected =
true;
2865 std::vector<CBlockIndex*> vpindexToConnect;
2866 bool fContinue =
true;
2871 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
2872 vpindexToConnect.clear();
2873 vpindexToConnect.reserve(nTargetHeight -
nHeight);
2876 vpindexToConnect.push_back(pindexIter);
2877 pindexIter = pindexIter->
pprev;
2883 if (!
ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2890 fInvalidFound =
true;
2911 if (fBlocksDisconnected) {
2931 bool fNotify =
false;
2932 bool fInitialBlockDownload =
false;
2937 pindexHeader = chainstate.m_chainman.m_best_header;
2939 if (pindexHeader != pindexHeaderOld) {
2941 fInitialBlockDownload = chainstate.IsInitialBlockDownload();
2942 pindexHeaderOld = pindexHeader;
2960 bool Chainstate::ActivateBestChain(
BlockValidationState& state, std::shared_ptr<const CBlock> pblock)
2993 bool blocks_connected =
false;
2999 if (pindexMostWork ==
nullptr) {
3004 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
3008 bool fInvalidFound =
false;
3009 std::shared_ptr<const CBlock> nullBlockPtr;
3010 if (!
ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
3014 blocks_connected =
true;
3016 if (fInvalidFound) {
3018 pindexMostWork =
nullptr;
3023 assert(trace.pblock && trace.pindex);
3027 if (!blocks_connected)
return true;
3030 bool fInitialDownload = IsInitialBlockDownload();
3034 if (pindexFork != pindexNewTip) {
3051 }
while (pindexNewTip != pindexMostWork);
3090 return ActivateBestChain(state, std::shared_ptr<const CBlock>());
3100 if (pindex->
nHeight == 0)
return false;
3103 bool pindex_was_in_chain =
false;
3104 int disconnected = 0;
3118 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
3122 for (
auto& entry :
m_blockman.m_block_index) {
3133 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
3150 pindex_was_in_chain =
true;
3163 if (!
ret)
return false;
3183 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
3184 while (candidate_it != candidate_blocks_by_work.end()) {
3187 candidate_it = candidate_blocks_by_work.erase(candidate_it);
3195 to_mark_failed = invalid_walk_tip;
3220 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3230 if (pindex_was_in_chain) {
3242 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3243 if (!block_index.IsValid() && block_index.GetAncestor(
nHeight) == pindex) {
3249 if (&block_index ==
m_chainman.m_best_invalid) {
3258 while (pindex !=
nullptr) {
3264 pindex = pindex->
pprev;
3272 pindexNew->
nTx = block.
vtx.size();
3274 pindexNew->nFile = pos.
nFile;
3275 pindexNew->nDataPos = pos.
nPos;
3276 pindexNew->nUndoPos = 0;
3286 std::deque<CBlockIndex*> queue;
3287 queue.push_back(pindexNew);
3290 while (!queue.empty()) {
3298 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
3299 while (range.first != range.second) {
3300 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3301 queue.push_back(it->second);
3340 if (fCheckMerkleRoot) {
3364 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3366 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3367 if (block.
vtx[i]->IsCoinBase())
3372 for (
const auto& tx : block.
vtx) {
3382 unsigned int nSigOps = 0;
3383 for (
const auto& tx : block.
vtx)
3390 if (fCheckPOW && fCheckMerkleRoot)
3396 void ChainstateManager::UpdateUncommittedBlockStructures(
CBlock& block,
const CBlockIndex* pindexPrev)
const 3399 static const std::vector<unsigned char>
nonce(32, 0x00);
3402 tx.
vin[0].scriptWitness.stack.resize(1);
3403 tx.
vin[0].scriptWitness.stack[0] =
nonce;
3410 std::vector<unsigned char> commitment;
3412 std::vector<unsigned char>
ret(32, 0x00);
3428 tx.vout.push_back(out);
3431 UpdateUncommittedBlockStructures(block, pindexPrev);
3437 return std::all_of(headers.cbegin(), headers.cend(),
3438 [&](
const auto& header) {
return CheckProofOfWork(header.GetHash(), header.nBits, consensusParams);});
3463 assert(pindexPrev !=
nullptr);
3476 const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
3477 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
3478 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
3511 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3514 bool enforce_locktime_median_time_past{
false};
3516 assert(pindexPrev !=
nullptr);
3517 enforce_locktime_median_time_past =
true;
3520 const int64_t nLockTimeCutoff{enforce_locktime_median_time_past ?
3525 for (
const auto& tx : block.
vtx) {
3535 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3536 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3549 bool fHaveWitness =
false;
3553 bool malleated =
false;
3558 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3562 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3565 fHaveWitness =
true;
3570 if (!fHaveWitness) {
3571 for (
const auto& tx : block.
vtx) {
3597 BlockMap::iterator miSelf{
m_blockman.m_block_index.find(hash)};
3599 if (miSelf !=
m_blockman.m_block_index.end()) {
3623 pindexPrev = &((*mi).second);
3658 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
3661 while (invalid_walk != failedit) {
3664 invalid_walk = invalid_walk->
pprev;
3672 if (!min_pow_checked) {
3707 const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
3708 LogPrintf(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
3726 auto now = std::chrono::steady_clock::now();
3727 if (now < m_last_presync_update + std::chrono::milliseconds{250})
return;
3728 m_last_presync_update = now;
3730 bool initial_download = chainstate.IsInitialBlockDownload();
3732 if (initial_download) {
3734 const double progress{100.0 * height / (height + blocks_left)};
3735 LogPrintf(
"Pre-synchronizing blockheaders, height: %d (~%.2f%%)\n", height, progress);
3742 const CBlock& block = *pblock;
3744 if (fNewBlock) *fNewBlock =
false;
3748 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3753 if (!accepted_header)
3776 if (fAlreadyHave)
return true;
3778 if (pindex->
nTx != 0)
return true;
3779 if (!fHasMoreOrSameWork)
return true;
3780 if (fTooFarAhead)
return true;
3804 if (fNewBlock) *fNewBlock =
true;
3807 if (blockPos.IsNull()) {
3808 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3812 }
catch (
const std::runtime_error& e) {
3813 return AbortNode(state, std::string(
"System error: ") + e.what());
3829 if (new_block) *new_block =
false;
3848 return error(
"%s: AcceptBlock FAILED (%s)", __func__, state.
ToString());
3856 return error(
"%s: ActivateBestChain failed (%s)", __func__, state.
ToString());
3883 bool fCheckMerkleRoot)
3890 indexDummy.pprev = pindexPrev;
3892 indexDummy.phashBlock = &block_hash;
3896 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.
ToString());
3898 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
3900 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__, state.
ToString());
3901 if (!chainstate.
ConnectBlock(block, state, &indexDummy, viewNew,
true)) {
3933 if (tip && tip->GetBlockHash() == coins_cache.
GetBestBlock()) {
3946 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
3947 tip->GetBlockHash().ToString(),
3956 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, 0,
false);
3968 int nCheckLevel,
int nCheckDepth)
3977 if (nCheckDepth <= 0 || nCheckDepth > chainstate.
m_chain.
Height()) {
3980 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3981 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
3985 int nGoodTransactions = 0;
3993 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
3994 if (reportDone < percentageDone / 10) {
3997 reportDone = percentageDone / 10;
3999 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
4006 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
4015 if (nCheckLevel >= 1 && !
CheckBlock(block, state, consensus_params)) {
4016 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
4020 if (nCheckLevel >= 2 && pindex) {
4038 nGoodTransactions = 0;
4039 pindexFailure = pindex;
4041 nGoodTransactions += block.
vtx.size();
4046 if (pindexFailure) {
4047 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.
m_chain.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
4054 if (nCheckLevel >= 4) {
4056 const int percentageDone = std::max(1, std::min(99, 100 - (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (double)nCheckDepth * 50)));
4057 if (reportDone < percentageDone / 10) {
4060 reportDone = percentageDone / 10;
4062 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
4067 if (!chainstate.
ConnectBlock(block, state, pindex, coins)) {
4075 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
4091 if (!tx->IsCoinBase()) {
4092 for (
const CTxIn &txin : tx->vin) {
4110 if (hashHeads.empty())
return true;
4111 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4113 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, 0,
false);
4120 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
4121 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4123 pindexNew = &(
m_blockman.m_block_index[hashHeads[0]]);
4125 if (!hashHeads[1].IsNull()) {
4126 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
4127 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4129 pindexOld = &(
m_blockman.m_block_index[hashHeads[1]]);
4131 assert(pindexFork !=
nullptr);
4135 while (pindexOld != pindexFork) {
4151 pindexOld = pindexOld->
pprev;
4155 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4160 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, (
int) ((
nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
4182 block = block->pprev;
4188 void Chainstate::UnloadBlockIndex()
4191 nBlockSequenceId = 1;
4202 if (!
ret)
return false;
4204 std::vector<CBlockIndex*> vSortedByHeight{
m_blockman.GetAllBlockIndices()};
4205 std::sort(vSortedByHeight.begin(), vSortedByHeight.end(),
4209 int first_assumed_valid_height = std::numeric_limits<int>::max();
4211 for (
const CBlockIndex* block : vSortedByHeight) {
4212 if (block->IsAssumedValid()) {
4213 auto chainstates =
GetAll();
4219 auto any_chain = [&](
auto fnc) {
return std::any_of(chainstates.cbegin(), chainstates.cend(), fnc); };
4223 first_assumed_valid_height = block->nHeight;
4259 pindex->
nHeight < first_assumed_valid_height) {
4265 m_best_invalid = pindex;
4271 needs_init =
m_blockman.m_block_index.empty();
4281 LogPrintf(
"Initializing databases...\n");
4300 if (blockPos.IsNull()) {
4301 return error(
"%s: writing genesis block to disk failed", __func__);
4305 }
catch (
const std::runtime_error& e) {
4306 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4312 void Chainstate::LoadExternalBlockFile(
4315 std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent)
4320 assert(!dbp == !blocks_with_unknown_parent);
4322 const auto start{SteadyClock::now()};
4328 uint64_t nRewind = blkdat.GetPos();
4329 while (!blkdat.eof()) {
4332 blkdat.SetPos(nRewind);
4335 unsigned int nSize = 0;
4340 nRewind = blkdat.GetPos() + 1;
4349 }
catch (
const std::exception&) {
4355 uint64_t nBlockPos = blkdat.GetPos();
4357 dbp->
nPos = nBlockPos;
4358 blkdat.SetLimit(nBlockPos + nSize);
4359 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4362 nRewind = blkdat.GetPos();
4364 uint256 hash = block.GetHash();
4370 block.hashPrevBlock.ToString());
4371 if (dbp && blocks_with_unknown_parent) {
4372 blocks_with_unknown_parent->emplace(block.hashPrevBlock, *dbp);
4381 if (
AcceptBlock(pblock, state,
nullptr,
true, dbp,
nullptr,
true)) {
4395 if (!ActivateBestChain(state,
nullptr)) {
4402 if (!blocks_with_unknown_parent)
continue;
4405 std::deque<uint256> queue;
4406 queue.push_back(hash);
4407 while (!queue.empty()) {
4410 auto range = blocks_with_unknown_parent->equal_range(head);
4411 while (range.first != range.second) {
4412 std::multimap<uint256, FlatFilePos>::iterator it = range.first;
4413 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4415 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4419 if (
AcceptBlock(pblockrecursive, dummy,
nullptr,
true, &it->second,
nullptr,
true)) {
4421 queue.push_back(pblockrecursive->GetHash());
4425 blocks_with_unknown_parent->erase(it);
4429 }
catch (
const std::exception& e) {
4430 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
4433 }
catch (
const std::runtime_error& e) {
4434 AbortNode(std::string(
"System error: ") + e.what());
4436 LogPrintf(
"Loaded %i blocks from external file in %dms\n", nLoaded, Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
4456 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4457 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
4458 forward.emplace(block_index.pprev, &block_index);
4463 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4465 rangeGenesis.first++;
4466 assert(rangeGenesis.first == rangeGenesis.second);
4477 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4479 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4480 while (pindex !=
nullptr) {
4482 if (pindexFirstInvalid ==
nullptr && pindex->nStatus &
BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
4486 pindexFirstMissing = pindex;
4488 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4495 if (pindexFirstNotTransactionsValid ==
nullptr &&
4497 pindexFirstNotTransactionsValid = pindex;
4500 if (pindexFirstNotChainValid ==
nullptr &&
4502 pindexFirstNotChainValid = pindex;
4505 if (pindexFirstNotScriptsValid ==
nullptr &&
4507 pindexFirstNotScriptsValid = pindex;
4512 if (pindex->
pprev ==
nullptr) {
4525 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4547 assert(pindexFirstNotTreeValid ==
nullptr);
4551 if (pindexFirstInvalid ==
nullptr) {
4556 if (pindexFirstInvalid ==
nullptr) {
4567 if (is_active && (pindexFirstMissing ==
nullptr || pindex ==
m_chain.
Tip())) {
4578 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
m_blockman.
m_blocks_unlinked.equal_range(pindex->
pprev);
4579 bool foundInUnlinked =
false;
4580 while (rangeUnlinked.first != rangeUnlinked.second) {
4581 assert(rangeUnlinked.first->first == pindex->
pprev);
4582 if (rangeUnlinked.first->second == pindex) {
4583 foundInUnlinked =
true;
4586 rangeUnlinked.first++;
4588 if (pindex->
pprev && (pindex->nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4593 if (pindexFirstMissing ==
nullptr)
assert(!foundInUnlinked);
4594 if (pindex->
pprev && (pindex->nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4606 if (pindexFirstInvalid ==
nullptr) {
4615 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4616 if (range.first != range.second) {
4618 pindex = range.first->second;
4627 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4628 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4629 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4630 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4631 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4632 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4633 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4637 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4638 while (rangePar.first->second != pindex) {
4639 assert(rangePar.first != rangePar.second);
4644 if (rangePar.first != rangePar.second) {
4646 pindex = rangePar.first->second;
4658 assert(nNodes == forward.size());
4665 return strprintf(
"Chainstate [%s] @ height %d (%s)",
4670 bool Chainstate::ResizeCoinsCaches(
size_t coinstip_size,
size_t coinsdb_size)
4683 LogPrintf(
"[%s] resized coinsdb cache to %.1f MiB\n",
4684 this->
ToString(), coinsdb_size * (1.0 / 1024 / 1024));
4685 LogPrintf(
"[%s] resized coinstip cache to %.1f MiB\n",
4686 this->
ToString(), coinstip_size * (1.0 / 1024 / 1024));
4691 if (coinstip_size > old_coinstip_size) {
4705 if (pindex ==
nullptr)
4708 int64_t nNow = time(
nullptr);
4718 return std::min<double>(pindex->
nChainTx / fTxTotal, 1.0);
4724 if (m_active_chainstate && m_active_chainstate->m_from_snapshot_blockhash) {
4726 return m_active_chainstate->m_from_snapshot_blockhash;
4728 return std::nullopt;
4734 std::vector<Chainstate*> out;
4737 out.push_back(m_ibd_chainstate.get());
4740 if (m_snapshot_chainstate) {
4741 out.push_back(m_snapshot_chainstate.get());
4747 Chainstate& ChainstateManager::InitializeChainstate(
4748 CTxMemPool* mempool,
const std::optional<uint256>& snapshot_blockhash)
4751 bool is_snapshot = snapshot_blockhash.has_value();
4752 std::unique_ptr<Chainstate>& to_modify =
4753 is_snapshot ? m_snapshot_chainstate : m_ibd_chainstate;
4756 throw std::logic_error(
"should not be overwriting a chainstate");
4761 if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
4762 LogPrintf(
"Switching active chainstate to %s\n", to_modify->ToString());
4763 m_active_chainstate = to_modify.get();
4765 throw std::logic_error(
"unexpected chainstate activation");
4775 const auto assumeutxo_found = valid_assumeutxos_map.find(height);
4777 if (assumeutxo_found != valid_assumeutxos_map.end()) {
4778 return &assumeutxo_found->second;
4791 LogPrintf(
"[snapshot] can't activate a snapshot-based chainstate more than once\n");
4795 int64_t current_coinsdb_cache_size{0};
4796 int64_t current_coinstip_cache_size{0};
4804 static constexpr
double IBD_CACHE_PERC = 0.01;
4805 static constexpr
double SNAPSHOT_CACHE_PERC = 0.99;
4823 static_cast<size_t>(current_coinstip_cache_size * IBD_CACHE_PERC),
4824 static_cast<size_t>(current_coinsdb_cache_size * IBD_CACHE_PERC));
4828 return std::make_unique<Chainstate>(
4829 nullptr,
m_blockman, *
this, base_blockhash));
4833 snapshot_chainstate->InitCoinsDB(
4834 static_cast<size_t>(current_coinsdb_cache_size * SNAPSHOT_CACHE_PERC),
4835 in_memory,
false,
"chainstate");
4836 snapshot_chainstate->InitCoinsCache(
4837 static_cast<size_t>(current_coinstip_cache_size * SNAPSHOT_CACHE_PERC));
4841 *snapshot_chainstate, coins_file, metadata);
4850 assert(!m_snapshot_chainstate);
4851 m_snapshot_chainstate.swap(snapshot_chainstate);
4852 const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip();
4855 m_active_chainstate = m_snapshot_chainstate.get();
4857 LogPrintf(
"[snapshot] successfully activated snapshot %s\n", base_blockhash.
ToString());
4859 m_snapshot_chainstate->CoinsTip().DynamicMemoryUsage() / (1000 * 1000));
4861 this->MaybeRebalanceCaches();
4870 snapshot_loaded ?
"saving snapshot chainstate" :
"flushing coins cache",
4874 coins_cache.
Flush();
4890 if (!snapshot_start_block) {
4893 LogPrintf(
"[snapshot] Did not find snapshot start blockheader %s\n",
4894 base_blockhash.ToString());
4898 int base_height = snapshot_start_block->
nHeight;
4901 if (!maybe_au_data) {
4902 LogPrintf(
"[snapshot] assumeutxo height in snapshot metadata not recognized " 4903 "(%d) - refusing to load snapshot\n", base_height);
4914 LogPrintf(
"[snapshot] loading coins from snapshot %s\n", base_blockhash.ToString());
4915 int64_t coins_processed{0};
4917 while (coins_left > 0) {
4919 coins_file >> outpoint;
4921 }
catch (
const std::ios_base::failure&) {
4922 LogPrintf(
"[snapshot] bad snapshot format or truncated snapshot after deserializing %d coins\n",
4923 coins_count - coins_left);
4926 if (coin.
nHeight > base_height ||
4927 outpoint.
n >= std::numeric_limits<decltype(outpoint.
n)>::max()
4929 LogPrintf(
"[snapshot] bad snapshot data after deserializing %d coins\n",
4930 coins_count - coins_left);
4939 if (coins_processed % 1000000 == 0) {
4940 LogPrintf(
"[snapshot] %d coins loaded (%.2f%%, %.2f MB)\n",
4942 static_cast<float>(coins_processed) * 100 / static_cast<float>(coins_count),
4950 if (coins_processed % 120000 == 0) {
4956 return snapshot_chainstate.GetCoinsCacheSizeState());
4977 bool out_of_coins{
false};
4979 coins_file >> outpoint;
4980 }
catch (
const std::ios_base::failure&) {
4982 out_of_coins =
true;
4984 if (!out_of_coins) {
4985 LogPrintf(
"[snapshot] bad snapshot - coins left over after deserializing %d coins\n",
4990 LogPrintf(
"[snapshot] loaded %d (%.2f MB) coins from snapshot %s\n",
4993 base_blockhash.ToString());
5000 auto breakpoint_fnc = [] { };
5006 const std::optional<CCoinsStats> maybe_stats =
ComputeUTXOStats(CoinStatsHashType::HASH_SERIALIZED, snapshot_coinsdb,
m_blockman, breakpoint_fnc);
5007 if (!maybe_stats.has_value()) {
5008 LogPrintf(
"[snapshot] failed to generate coins stats\n");
5014 LogPrintf(
"[snapshot] bad snapshot content hash: expected %s, got %s\n",
5031 constexpr
int AFTER_GENESIS_START{1};
5033 for (
int i = AFTER_GENESIS_START; i <= snapshot_chainstate.
m_chain.
Height(); ++i) {
5034 index = snapshot_chainstate.
m_chain[i];
5069 LogPrintf(
"[snapshot] validated snapshot (%.2f MB)\n",
5077 assert(m_active_chainstate);
5078 return *m_active_chainstate;
5084 return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get();
5087 void ChainstateManager::MaybeRebalanceCaches()
5090 if (m_ibd_chainstate && !m_snapshot_chainstate) {
5091 LogPrintf(
"[snapshot] allocating all cache to the IBD chainstate\n");
5095 else if (m_snapshot_chainstate && !m_ibd_chainstate) {
5096 LogPrintf(
"[snapshot] allocating all cache to the snapshot chainstate\n");
5100 else if (m_ibd_chainstate && m_snapshot_chainstate) {
5104 if (m_snapshot_chainstate->IsInitialBlockDownload()) {
5105 m_ibd_chainstate->ResizeCoinsCaches(
5107 m_snapshot_chainstate->ResizeCoinsCaches(
5110 m_snapshot_chainstate->ResizeCoinsCaches(
5112 m_ibd_chainstate->ResizeCoinsCaches(
5125 for (
auto& i : warningcache) {
std::optional< std::string > PaysForRBF(CAmount original_fees, CAmount replacement_fees, size_t replacement_vsize, CFeeRate relay_fee, const uint256 &txid)
The replacement transaction must pay more fees than the original transactions.
std::shared_ptr< const CTransaction > CTransactionRef
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
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.
static unsigned int GetBlockScriptFlags(const CBlockIndex &block_index, const ChainstateManager &chainman)
CSHA256 & Write(const unsigned char *data, size_t len)
static void UpdateTipLog(const CCoinsViewCache &coins_tip, const CBlockIndex *tip, const CChainParams ¶ms, const std::string &func_name, const std::string &prefix, const std::string &warning_messages) EXCLUSIVE_LOCKS_REQUIRED(
void PruneBlockFilesManual(Chainstate &active_chainstate, int nManualPruneHeight)
Prune block files up to a given height.
bool IsSpent() const
Either this coin never existed (see e.g.
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
const std::optional< uint256 > m_from_snapshot_blockhash
The blockhash which is the base of the snapshot this chainstate was created from. ...
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
void InvalidChainFound(CBlockIndex *pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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.
CTxMemPool * m_mempool
Optional mempool that is kept in sync with the chain.
void resize(size_type new_size)
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
bool ReplayBlocks()
Replay blocks that aren't fully applied to the database.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
bool PopulateAndValidateSnapshot(Chainstate &snapshot_chainstate, AutoFile &coins_file, const node::SnapshotMetadata &metadata)
Internal helper for ActivateSnapshot().
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...
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...
void UpdateLockPoints(const LockPoints &lp)
std::chrono::time_point< NodeClock > time_point
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
std::optional< std::string > PaysMoreThanConflicts(const CTxMemPool::setEntries &iters_conflicting, CFeeRate replacement_feerate, const uint256 &txid)
Check that the feerate of the replacement transaction(s) is higher than the feerate of each of the tr...
RecursiveMutex * MempoolMutex() const LOCK_RETURNED(m_mempool -> cs)
Indirection necessary to make lock annotations work with an optional mempool.
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
static GenTxid Wtxid(const uint256 &hash)
const unsigned int nChainTx
Used to populate the nChainTx value, which is used during BlockManager::LoadBlockIndex().
bool m_check_for_pruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted...
std::condition_variable g_best_block_cv
static void FlushSnapshotToDisk(CCoinsViewCache &coins_cache, bool snapshot_loaded)
bool Error(const std::string &reject_reason)
SynchronizationState
Current sync state passed to tip changed callbacks.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
bool IsStandardTx(const CTransaction &tx, const std::optional< unsigned > &max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate &dust_relay_fee, std::string &reason)
Check for standard transaction types.
static const int WITNESS_SCALE_FACTOR
void Finalize(Span< unsigned char > output)
std::string GetDebugMessage() const
std::set< CBlockIndex *, node::CBlockIndexWorkComparator > setBlockIndexCandidates
The set of all CBlockIndex entries with either BLOCK_VALID_TRANSACTIONS (for itself and all ancestors...
CClientUIInterface uiInterface
CBlockIndex * m_best_header
Best header we've seen so far (used for getheaders queries' starting points).
#define LogPrint(category,...)
void Add(std::vector< T > &vChecks)
int64_t GetBlockTime() const
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
int Threshold(const Consensus::Params ¶ms) const override
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
double dTxRate
estimated number of transactions per second after that timestamp
virtual bool GetCoin(const COutPoint &outpoint, Coin &coin) const
Retrieve the Coin (unspent transaction output) for a given outpoint.
descends from failed block
static std::array< ThresholdConditionCache, VERSIONBITS_NUM_BITS > warningcache GUARDED_BY(cs_main)
CBlockIndex * pprev
pointer to the index of the predecessor of this block
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or coinEmpty if not found.
The package itself is invalid (e.g. too many transactions).
bool Flush()
Push the modifications applied to this cache to its base.
std::atomic_bool fReindex
std::optional< std::string > HasNoNewUnconfirmed(const CTransaction &tx, const CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting)
The replacement transaction may only include an unconfirmed input if that input was included in one o...
static int64_t nTimeConnectTotal
void BlockDisconnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances...
bool exists(const GenTxid >xid) const
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs
UpdateTransactionsFromBlock is called when adding transactions from a disconnected block back to the ...
bool CheckSequenceLocksAtTip(CBlockIndex *tip, const CCoinsView &coins_view, const CTransaction &tx, LockPoints *lp, bool useExistingLockPoints)
bool IsChildWithParents(const Package &package)
Context-free check that a package is exactly one child and its parents; not all parents need to be pr...
We don't have the previous block the checked one is built on.
int64_t BeginTime(const Consensus::Params ¶ms) const override
RecursiveMutex cs_LastBlockFile
The cache is at >= 90% capacity.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
void FindFilesToPrune(std::set< int > &setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, int prune_height, bool is_ibd)
Prune block and undo files (blk???.dat and rev???.dat) so that the disk space used is less than a use...
static void AlertNotify(const std::string &strMessage)
const int64_t m_max_size_bytes
size_t DynamicMemoryUsage() const
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
const MapAssumeutxo & Assumeutxo() const
Get allowed assumeutxo configuration.
reverse_range< T > reverse_iterate(T &x)
void SetMiscWarning(const bilingual_str &warning)
static const int64_t DEFAULT_MAX_TIP_AGE
uint256 GetRandHash() noexcept
int Period(const Consensus::Params ¶ms) const override
invalid proof of work or time too old
size_t m_coinsdb_cache_size_bytes
The cache size of the on-disk coins view.
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > &prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block...
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
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
std::unique_ptr< CoinsViews > m_coins_views
Manages the UTXO set, which is a reflection of the contents of m_chain.
static int64_t nTimeForks
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool MoneyRange(const CAmount &nValue)
int Height() const
Return the maximal height in the chain.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
std::unordered_map< uint256, CBlockIndex, BlockHasher > BlockMap
CTxOut out
unspent transaction output
bool DeploymentActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache &versionbitscache)
Determine if a deployment is active for the next block.
static MempoolAcceptResult Success(std::list< CTransactionRef > &&replaced_txns, int64_t vsize, CAmount fees)
bool AcceptBlockHeader(const CBlockHeader &block, BlockValidationState &state, CBlockIndex **ppindex, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
If a block header hasn't already been seen, call CheckBlockHeader on it, ensure that it doesn't desce...
cache implements a cache with properties similar to a cuckoo-set.
void InitCoinsDB(size_t cache_size_bytes, bool in_memory, bool should_wipe, fs::path leveldb_name="chainstate")
Initialize the CoinsViews UTXO set database management data structures.
stage after last reached validness failed
bool CheckFinalTxAtTip(const CBlockIndex &active_chain_tip, const CTransaction &tx)
static constexpr size_t MINIMUM_WITNESS_COMMITMENT
Minimum size of a witness commitment structure.
std::optional< std::string > EntriesAndTxidsDisjoint(const CTxMemPool::setEntries &ancestors, const std::set< uint256 > &direct_conflicts, const uint256 &txid)
Check the intersection between two sets of transactions (a set of mempool entries and a set of txids)...
unsigned int fCoinBase
whether containing transaction was a coinbase
The coins cache is in immediate need of a flush.
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule) ...
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
void ReallocateCache()
Force a reallocation of the cache map.
arith_uint256 nLastPreciousChainwork
chainwork for the last block that preciousblock has been applied to.
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.
static bool IsCurrentForFeeEstimation(Chainstate &active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void addTransaction(const CTransactionRef &tx)
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
PerBlockConnectTrace()=default
const CBlock & GenesisBlock() const
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...
CoinsViews(fs::path 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...
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...
bool LoadMempool(CTxMemPool &pool, const fs::path &load_path, Chainstate &active_chainstate, FopenFn mockable_fopen_function)
bool ConnectTip(BlockValidationState &state, CBlockIndex *pindexNew, const std::shared_ptr< const CBlock > &pblock, ConnectTrace &connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Connect a new block to m_chain.
violated mempool's fee/size/descendant/RBF/etc limits
the block header may be on a too-little-work chain
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
inputs (covered by txid) failed policy rules
undo data available in rev*.dat
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
void MaybeUpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Make mempool consistent after a reorg, by re-adding or recursively erasing disconnected block transac...
const ResultType m_result_type
Result type.
void CheckBlockIndex()
Make various assertions about the state of the block index.
void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
transaction spends a coinbase too early, or violates locktime/sequence locks
void SetLoadTried(bool load_tried)
Set whether or not we've made an attempt to load the mempool (regardless of whether the attempt was s...
static constexpr int NO_WITNESS_COMMITMENT
Index marker for when no witness commitment is present in a coinbase transaction. ...
static bool ContextualCheckBlock(const CBlock &block, BlockValidationState &state, const ChainstateManager &chainman, const CBlockIndex *pindexPrev)
NOTE: This function is not currently invoked by ConnectBlock(), so we should consider upgrade issues ...
bool CheckPackage(const Package &txns, PackageValidationState &state)
Context-free package policy checks:
bool SignalsOptInRBF(const CTransaction &tx)
Check whether the sequence numbers on this transaction are signaling opt-in to replace-by-fee, according to BIP 125.
CChain m_chain
The current chain of blockheaders we consult and build on.
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 DeploymentActiveAt(const CBlockIndex &index, const Consensus::Params ¶ms, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache &versionbitscache)
Determine if a deployment is active for this block.
Non-refcounted RAII wrapper for FILE*.
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
void SetTip(CBlockIndex &block)
Set/initialize a chain with a given tip.
static void LimitMempoolSize(CTxMemPool &pool, CCoinsViewCache &coins_cache) EXCLUSIVE_LOCKS_REQUIRED(
void ReceivedBlockTransactions(const CBlock &block, CBlockIndex *pindexNew, const FlatFilePos &pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
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
std::map< uint256, uint32_t > script_flag_exceptions
Hashes of blocks that.
bool IsWitnessStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check if the transaction is over standard P2WSH resources limit: 3600bytes witnessScript size...
void StartScriptCheckWorkerThreads(int threads_num)
Run instances of script checking worker threads.
void removeForReorg(CChain &chain, std::function< bool(txiter)> filter_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs
After reorg, filter the entries that would no longer be valid in the next block, and update the entri...
size_t GetSerializeSize(const T &t, int nVersion=0)
std::vector< CBlockIndex * > GetAllBlockIndices() EXCLUSIVE_LOCKS_REQUIRED(std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
void TransactionAddedToMempool(const CTransactionRef &, uint64_t mempool_sequence)
uint256 g_best_block
Used to notify getblocktemplate RPC of new tips.
arith_uint256 UintToArith256(const uint256 &a)
bool FlushStateToDisk(BlockValidationState &state, FlushStateMode mode, int nManualPruneHeight=0)
Update the on-disk chain state.
VersionBitsCache m_versionbitscache
Track versionbit status.
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)
int nSubsidyHalvingInterval
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &block, bool force_processing, bool min_pow_checked, bool *new_block) LOCKS_EXCLUDED(cs_main)
Process an incoming block.
std::optional< std::string > GetEntriesForConflicts(const CTransaction &tx, CTxMemPool &pool, const CTxMemPool::setEntries &iters_conflicting, CTxMemPool::setEntries &all_conflicts)
Get all descendants of iters_conflicting.
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)
void PruneAndFlush()
Prune blockfiles from the disk if necessary and then flush chainstate changes if we pruned...
MempoolAcceptResult AcceptToMemoryPool(Chainstate &active_chainstate, const CTransactionRef &tx, int64_t accept_time, bool bypass_limits, bool test_accept) EXCLUSIVE_LOCKS_REQUIRED(
Try to add a transaction to the mempool.
uint256 GetBlockHash() const
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check transaction inputs to mitigate two potential denial-of-service attacks:
static CuckooCache::cache< uint256, SignatureCacheHasher > g_scriptExecutionCache
static feebumper::Result CheckFeeRate(const CWallet &wallet, const CWalletTx &wtx, const CFeeRate &newFeerate, const int64_t maxTxSize, CAmount old_fee, std::vector< bilingual_str > &errors)
Check if the user provided a valid feeRate.
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
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
bool ActivateBestChain(BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr) LOCKS_EXCLUDED(bool AcceptBlock(const std::shared_ptr< const CBlock > &pblock, BlockValidationState &state, CBlockIndex **ppindex, bool fRequested, const FlatFilePos *dbp, bool *fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the best known block, and make it the tip of the block chain.
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
CBlockLocator GetLocator() const
Return a CBlockLocator that refers to the tip in of this chain.
static const uint32_t MEMPOOL_HEIGHT
Fake height value used in Coin to signify they are only in the memory pool (since 0...
std::function< FILE *(const fs::path &, const char *)> FopenFn
std::string ToString(const T &t)
Locale-independent version of std::to_string.
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePo SaveBlockToDisk)(const CBlock &block, int nHeight, CChain &active_chain, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
uint64_t PruneAfterHeight() const
void SetfLargeWorkInvalidChainFound(bool flag)
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
bool DisconnectTip(BlockValidationState &state, DisconnectedBlockTransactions *disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Disconnect m_chain's tip.
bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(bool LoadBlockIndexDB(const Consensus::Params &consensus_params) EXCLUSIVE_LOCKS_REQUIRED(CBlockIndex * AddToBlockIndex(const CBlockHeader &block, CBlockIndex *&best_header) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool HasValidProofOfWork(const std::vector< CBlockHeader > &headers, const Consensus::Params &consensusParams)
Check with the proof of work on each blockheader matches the value in nBits.
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
Initialize this PrecomputedTransactionData with transaction data.
static bool NotifyHeaderTip(Chainstate &chainstate) LOCKS_EXCLUDED(cs_main)
bool CheckInputScripts(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData &txdata, std::vector< CScriptCheck > *pvChecks=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Check whether all of this transaction's input scripts succeed.
void EmplaceCoinInternalDANGER(COutPoint &&outpoint, Coin &&coin)
Emplace a coin into cacheCoins without performing any checks, marking the emplaced coin as dirty...
bool IsSnapshotActive() const
Chainstate stores and provides an API to update our local knowledge of the current best chain...
const CChainParams & m_params
Chain parameters for this chainstate.
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
void swap(CScriptCheck &check) noexcept
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...
const CBlockIndex * FindForkInGlobalIndex(const CBlockLocator &locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the last common block of this chain and a locator.
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, uint32_t flags)
Compute total signature operation cost of a transaction.
static int64_t nTimeChainState
Abstract view on the open txout dataset.
static int64_t nTimeTotal
this block was cached as being invalid and we didn't store the reason why
bool reliesOnAssumedValid()
Return true if this chainstate relies on blocks that are assumed-valid.
void removeForBlock(const std::vector< CTransactionRef > &vtx)
Validation result for package mempool acceptance.
An input of a transaction.
DisconnectResult DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view) EXCLUSIVE_LOCKS_REQUIRED(boo ConnectBlock)(const CBlock &block, BlockValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool fJustCheck=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of this block (with given index) on the UTXO set represented by coins...
std::vector< unsigned char > GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev) const
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
static constexpr int PRUNE_LOCK_BUFFER
The number of blocks to keep below the deepest prune lock.
const uint256 & GetWitnessHash() const
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of a block on the utxo cache, ignoring that it may already have been applied...
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
const uint256 & GetHash() const
std::string ToString() const
bilingual_str _(const char *psz)
Translation function.
static CCheckQueue< CScriptCheck > scriptcheckqueue(128)
the block failed to meet one of our checkpoints
const std::function< NodeClock::time_point()> adjusted_time_callback
int32_t nBlockReverseSequenceId
Decreasing counter (used by subsequent preciousblock calls).
bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the block tree and coins database from disk, initializing state if we're running with -reindex...
int BIP34Height
Block height and hash at which BIP34 becomes active.
Chainstate(CTxMemPool *mempool, node::BlockManager &blockman, ChainstateManager &chainman, std::optional< uint256 > from_snapshot_blockhash=std::nullopt)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
uint256 uint256S(const char *str)
int64_t nPowTargetSpacing
bool VerifyDB(Chainstate &chainstate, const Consensus::Params &consensus_params, CCoinsView &coinsview, int nCheckLevel, int nCheckDepth) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::string ScriptErrorString(const ScriptError serror)
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
Abstract class that implements BIP9-style threshold logic, and caches results.
bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Whether the chain state needs to be redownloaded due to lack of witness data.
std::map< int, const AssumeutxoData > MapAssumeutxo
Holds various statistics on transactions within a chain.
static int64_t nTimeIndex
void Finalize(unsigned char hash[OUTPUT_SIZE])
const std::vector< CTxOut > vout
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
static const int DEFAULT_STOPATHEIGHT
Default for -stopatheight.
bool TestLockPointValidity(CChain &active_chain, const LockPoints &lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
const Consensus::Params & GetConsensus() const
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept)
Validate (and maybe submit) a package to the mempool.
std::shared_ptr< const CBlock > pblock
void LoadMempool(const fs::path &load_path, fsbridge::FopenFn mockable_fopen_function=fsbridge::fopen)
Load the persisted mempool from disk.
bool ActivateBestChainStep(BlockValidationState &state, CBlockIndex *pindexMostWork, const std::shared_ptr< const CBlock > &pblock, bool &fInvalidFound, ConnectTrace &connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Dictates whether we need to flush the cache to disk or not.
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main)
CMainSignals & GetMainSignals()
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
CCoinsViewDB & CoinsDB() EXCLUSIVE_LOCKS_REQUIRED(
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
bool InitScriptExecutionCache(size_t max_size_bytes)
Initializes the script-execution cache.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
const CMessageHeader::MessageStartChars & MessageStart() const
void ForceFlushStateToDisk()
Unconditionally flush all changes to disk.
An output of a transaction.
void ReplaceAll(std::string &in_out, const std::string &search, const std::string &substitute)
std::string ToString() const
bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Update the chain tip based on database information, i.e.
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
At least one tx is invalid.
void StopScriptCheckWorkerThreads()
Stop all of the script checking worker threads.
uint32_t nMinerConfirmationWindow
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...
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.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void AddTransactionsUpdated(unsigned int n)
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...
Chainstate &InitializeChainstate(CTxMemPool *mempool, const std::optional< uint256 > &snapshot_blockhash=std::nullopt) LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(std::vector< Chainstate * GetAll)()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
Validation result for a single transaction mempool acceptance.
static MempoolAcceptResult MempoolTx(int64_t vsize, CAmount fees)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define Assume(val)
Assume is the identity function.
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download...
256-bit unsigned big integer.
int64_t GetMedianTimePast() const
block data in blk*.dat was received with a witness-enforcing client
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool possible_overwrite)
Add a coin.
#define TRACE5(context, event, a, b, c, d, e)
static int64_t nTimeCheck
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
static int64_t nTimeConnect
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Determine what nVersion a new block should use.
int64_t m_total_coinstip_cache
The total number of bytes available for us to use across all in-memory coins caches.
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(
constexpr int64_t count_seconds(std::chrono::seconds t)
Closure representing one script verification Note that this stores references to the spending transac...
static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST
The maximum number of sigops we're willing to relay/mine in a single tx.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
static bool CheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW=true)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Transaction is missing a witness.
int64_t GetTimeMicros()
Returns the system time (not mockable)
bool fPruneMode
Pruning-related variables and constants.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
static void DoWarning(const bilingual_str &warning)
int32_t nVersion
block header
static bool ComputeUTXOStats(CCoinsView *view, CCoinsStats &stats, T hash_obj, const std::function< void()> &interruption_point)
Calculate statistics about the unspent transaction output set.
const CChainParams & GetParams() const
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
invalid by consensus rules (excluding any below reasons)
const CTransaction * ptxTo
bool g_parallel_script_checks
Whether there are dedicated script-checking threads running.
std::atomic< bool > m_cached_finished_ibd
Whether this chainstate is undergoing initial block download.
static const bool DEFAULT_CHECKPOINTS_ENABLED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
const ChainTxData & TxData() const
static bool ContextualCheckBlockHeader(const CBlockHeader &block, BlockValidationState &state, BlockManager &blockman, const ChainstateManager &chainman, const CBlockIndex *pindexPrev, NodeClock::time_point now) EXCLUSIVE_LOCKS_REQUIRED(
Context-dependent validity checks.
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 ...
#define LOCKS_EXCLUDED(...)
std::set< CBlockIndex * > m_dirty_blockindex
Dirty block index entries.
bool ActivateSnapshot(AutoFile &coins_file, const node::SnapshotMetadata &metadata, bool in_memory)
Construct and activate a Chainstate on the basis of UTXO snapshot data.
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
const CBlockIndex *GetFirstStoredBlock(const CBlockIndex &start_block LIFETIMEBOUND) EXCLUSIVE_LOCKS_REQUIRED(bool m_have_pruned
Find the first block that is not pruned.
The block chain is a tree shaped structure starting with the genesis block at the root...
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
Undo information for a CTransaction.
std::vector< PerBlockConnectTrace > blocksConnected
CCoinsView backed by the coin database (chainstate/)
static constexpr 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 ...
const ChainstateManager & m_chainman
void PruneBlockIndexCandidates()
Delete all entries in setBlockIndexCandidates that are worse than the current tip.
static const int PROTOCOL_VERSION
network protocol versioning
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
bool m_spent_outputs_ready
Whether m_spent_outputs is initialized.
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
A block this one builds on is invalid.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
std::string ToString() const
#define TRACE6(context, event, a, b, c, d, e, f)
const AssumeutxoData * ExpectedAssumeutxo(const int height, const CChainParams &chainparams)
Return the expected assumeutxo value for a given height, if one exists.
bool AbortNode(BlockValidationState &state, const std::string &strMessage, const bilingual_str &userMessage)
static void AppendWarning(bilingual_str &res, const bilingual_str &warn)
Private helper function that concatenates warning messages.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL
Time to wait between writing blocks/block index to disk.
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(
Raise the validity level of this block index entry.
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
static int64_t nTimeVerify
static int64_t nTimePostConnect
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
bool IsAssumedValid() const EXCLUSIVE_LOCKS_REQUIRED(
Holds configuration for use during UTXO snapshot load and validation.
#define AssertLockNotHeld(cs)
void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
arith_uint256 CalculateHeadersWork(const std::vector< CBlockHeader > &headers)
Return the sum of the work on a given set of headers.
void StartShutdown()
Request shutdown of the application.
int MinBIP9WarningHeight
Don't warn about unknown BIP 9 activations below this height.
this node does not have a mempool so can't validate the transaction
A mutable version of CTransaction.
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period...
block timestamp was > 2 hours in the future (or our clock is bad)
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
size_t m_coinstip_cache_size_bytes
The cache size of the in-memory coins view.
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...
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
Mutex m_chainstate_mutex
The ChainState Mutex A lock that must be held when modifying this ChainState - held in ActivateBestCh...
arith_uint256 GetBlockProof(const CBlockIndex &block)
static MempoolAcceptResult Failure(TxValidationState state)
static bool CheckInputsFromMempoolAndCache(const CTransaction &tx, TxValidationState &state, const CCoinsViewCache &view, const CTxMemPool &pool, unsigned int flags, PrecomputedTransactionData &txdata, CCoinsViewCache &coins_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main
Checks to avoid mempool polluting consensus critical paths since cached signature and script validity...
static constexpr int64_t MAX_FUTURE_BLOCK_TIME
Maximum amount of time that a block timestamp is allowed to exceed the current network-adjusted time ...
size_t DynamicMemoryUsage() const
The basic transaction that is broadcasted on the network and contained in blocks. ...
Different type to mark Mutex at global scope.
void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
int nHeight
height of the entry in the chain. The genesis block has height 0
bool TestBlockValidity(BlockValidationState &state, const CChainParams &chainparams, Chainstate &chainstate, const CBlock &block, CBlockIndex *pindexPrev, const std::function< NodeClock::time_point()> &adjusted_time_callback, bool fCheckPOW, bool fCheckMerkleRoot)
Check a block is completely valid from start to finish (only works on top of our current best block) ...
WarningBitsConditionChecker(const ChainstateManager &chainman, int bit)
std::optional< uint256 > SnapshotBlockhash() const
const Consensus::Params & GetConsensus() const
Chainstate & ActiveChainstate() const
The most-work chain.
static int64_t nTimeReadFromDiskTotal
int64_t m_total_coinsdb_cache
The total number of bytes available for us to use across all leveldb coins databases.
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.
std::string GetRejectReason() const
full block available in blk*.dat
#define LOG_TIME_MILLIS_WITH_CATEGORY(end_msg, log_category)
std::atomic_bool fImporting
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from...
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.
int64_t GetTime()
DEPRECATED, see GetTime.
const AssumeutxoHash hash_serialized
The expected hash of the deserialized UTXO set.
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
std::vector< CTxUndo > vtxundo
static SynchronizationState GetSynchronizationState(bool init)
static int64_t GetBlockWeight(const CBlock &block)
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.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
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
If set, this indicates that the block index entry is assumed-valid.
bool PreciousBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(voi ResetBlockFailureFlags)(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as precious and reorganize.
ScriptError GetScriptError() const
static int64_t nBlocksTotal
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
CCoinsView that brings transactions from a mempool into view.
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
void ReportHeadersPresync(const arith_uint256 &work, int64_t height, int64_t timestamp)
This is used by net_processing to report pre-synchronization progress of headers, as headers are not ...
bool error(const char *fmt, const Args &... args)
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 > &)
static int64_t nTimeFlush
void BlockChecked(const CBlock &, const BlockValidationState &)
CHash256 & Write(Span< const unsigned char > input)
otherwise didn't meet our local policy rules
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
#define LOG_TIME_MILLIS_WITH_CATEGORY_MSG_ONCE(end_msg, log_category)
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
unsigned int nTx
Number of transactions in this block.
static constexpr 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 ...
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex)
static GenTxid Txid(const uint256 &hash)
static MempoolAcceptResult MempoolTxDifferentWitness(const uint256 &other_wtxid)
CTxMemPool * GetMempool()
bool IsSnapshotValidated() const EXCLUSIVE_LOCKS_REQUIRED(
Is there a snapshot in use and has it been fully validated?
static constexpr std::chrono::hours DATABASE_FLUSH_INTERVAL
Time to wait between flushing chainstate to disk.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
#define Assert(val)
Identity function.
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
Return the time it would take to redo the work difference between from and to, assuming the current h...
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
GlobalMutex g_best_block_mutex
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &block, bool min_pow_checked, BlockValidationState &state, const CBlockIndex **ppindex=nullptr) LOCKS_EXCLUDED(cs_main)
Process incoming block headers.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
MempoolAcceptResult ProcessTransaction(const CTransactionRef &tx, bool test_accept=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Try to add a transaction to the memory pool.
static constexpr CAmount COIN
The amount of satoshis in one BTC.
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
PrecomputedTransactionData * txdata
Threshold condition checker that triggers when unknown versionbits are seen on the network...