94 "level 0 reads the blocks from disk",
95 "level 1 verifies block validity",
96 "level 2 verifies undo data",
97 "level 3 checks disconnection of tip blocks",
98 "level 4 tries to reconnect the blocks",
99 "each level includes the checks of the previous levels",
135 std::vector<CScriptCheck>* pvChecks =
nullptr)
148 const int nBlockHeight = active_chain_tip.nHeight + 1;
155 const int64_t nBlockTime{active_chain_tip.GetMedianTimePast()};
157 return IsFinalTx(tx, nBlockHeight, nBlockTime);
171 std::optional<std::vector<int>> CalculatePrevHeights(
176 std::vector<int> prev_heights;
177 prev_heights.resize(tx.
vin.size());
178 for (
size_t i = 0; i < tx.
vin.size(); ++i) {
187 prev_heights[i] = tip.
nHeight + 1;
189 prev_heights[i] = coin.
nHeight;
203 auto prev_heights{CalculatePrevHeights(*tip, coins_view, tx)};
204 if (!prev_heights.has_value())
return std::nullopt;
207 next_tip.
pprev = tip;
225 int max_input_height{0};
226 for (
const int height : prev_heights.value()) {
228 if (height != next_tip.
nHeight) {
229 max_input_height = std::max(max_input_height, height);
267 int expired = pool.Expire(GetTime<std::chrono::seconds>() - pool.m_expiry);
272 std::vector<COutPoint> vNoSpendsRemaining;
273 pool.TrimToSize(pool.m_max_size_bytes, &vNoSpendsRemaining);
274 for (
const COutPoint& removed : vNoSpendsRemaining)
275 coins_cache.Uncache(removed);
281 if (active_chainstate.IsInitialBlockDownload())
285 if (active_chainstate.m_chain.Height() < active_chainstate.m_chainman.m_best_header->nHeight - 1) {
299 std::vector<uint256> vHashUpdate;
309 if (!fAddToMempool || (*it)->IsCoinBase() ||
311 true,
false).m_result_type !=
317 vHashUpdate.push_back((*it)->GetHash());
362 if (it->GetSpendsCoinbase()) {
370 if (coin.IsCoinBase() && mempool_spend_height - coin.nHeight <
COINBASE_MATURITY) {
405 if (coin.
IsSpent())
return false;
435 m_viewmempool(&active_chainstate.CoinsTip(), m_pool),
436 m_active_chainstate(active_chainstate),
437 m_limits{m_pool.m_limits}
445 const int64_t m_accept_time;
446 const bool m_bypass_limits;
454 std::vector<COutPoint>& m_coins_to_uncache;
455 const bool m_test_accept;
459 const bool m_allow_replacement;
464 const bool m_package_submission;
468 const bool m_package_feerates;
471 static ATMPArgs SingleAccept(
const CChainParams& chainparams, int64_t accept_time,
472 bool bypass_limits, std::vector<COutPoint>& coins_to_uncache,
474 return ATMPArgs{ chainparams,
486 static ATMPArgs PackageTestAccept(
const CChainParams& chainparams, int64_t accept_time,
487 std::vector<COutPoint>& coins_to_uncache) {
488 return ATMPArgs{ chainparams,
500 static ATMPArgs PackageChildWithParents(
const CChainParams& chainparams, int64_t accept_time,
501 std::vector<COutPoint>& coins_to_uncache) {
502 return ATMPArgs{ chainparams,
514 static ATMPArgs SingleInPackageAccept(
const ATMPArgs& package_args) {
515 return ATMPArgs{ package_args.m_chainparams,
516 package_args.m_accept_time,
518 package_args.m_coins_to_uncache,
519 package_args.m_test_accept,
532 std::vector<COutPoint>& coins_to_uncache,
534 bool allow_replacement,
535 bool package_submission,
536 bool package_feerates)
537 : m_chainparams{chainparams},
538 m_accept_time{accept_time},
539 m_bypass_limits{bypass_limits},
540 m_coins_to_uncache{coins_to_uncache},
541 m_test_accept{test_accept},
542 m_allow_replacement{allow_replacement},
543 m_package_submission{package_submission},
544 m_package_feerates{package_feerates}
569 explicit Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
571 std::set<uint256> m_conflicts;
581 std::unique_ptr<CTxMemPoolEntry> m_entry;
585 std::list<CTransactionRef> m_replaced_transactions;
597 size_t m_conflicting_size{0};
624 bool PackageMempoolChecks(
const std::vector<CTransactionRef>& txns,
647 std::map<const uint256, const MempoolAcceptResult>& results)
655 CAmount mempoolRejectFee = m_pool.GetMinFee().GetFee(package_size);
656 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
660 if (package_fee < m_pool.m_min_relay_feerate.GetFee(package_size)) {
662 strprintf(
"%d < %d", package_fee, m_pool.m_min_relay_feerate.GetFee(package_size)));
681 bool MemPoolAccept::PreChecks(ATMPArgs&
args, Workspace& ws)
687 const uint256& hash = ws.m_hash;
690 const int64_t nAcceptTime =
args.m_accept_time;
691 const bool bypass_limits =
args.m_bypass_limits;
692 std::vector<COutPoint>& coins_to_uncache =
args.m_coins_to_uncache;
696 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
708 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)) {
736 if (ptxConflicting) {
737 if (!
args.m_allow_replacement) {
741 if (!ws.m_conflicts.count(ptxConflicting->
GetHash()))
757 ws.m_conflicts.insert(ptxConflicting->
GetHash());
762 m_view.SetBackend(m_viewmempool);
768 coins_to_uncache.push_back(txin.
prevout);
774 if (!m_view.HaveCoin(txin.
prevout)) {
776 for (
size_t out = 0; out < tx.
vout.size(); out++) {
789 m_view.GetBestBlock();
794 m_view.SetBackend(m_dummy);
796 assert(m_active_chainstate.m_blockman.LookupBlockIndex(m_view.GetBestBlock()) == m_active_chainstate.m_chain.Tip());
803 const std::optional<LockPoints> lock_points{
CalculateLockPointsAtTip(m_active_chainstate.m_chain.Tip(), m_view, tx)};
825 ws.m_modified_fees = ws.m_base_fees;
826 m_pool.ApplyDelta(hash, ws.m_modified_fees);
830 bool fSpendsCoinbase =
false;
832 const Coin &coin = m_view.AccessCoin(txin.
prevout);
834 fSpendsCoinbase =
true;
839 entry.reset(
new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
840 fSpendsCoinbase, nSigOpsCost, lock_points.value()));
841 ws.m_vsize = entry->GetTxSize();
850 if (!bypass_limits && !
args.m_package_feerates && !
CheckFeeRate(ws.m_vsize, ws.m_modified_fees, state))
return false;
852 ws.m_iters_conflicting = m_pool.GetIterSet(ws.m_conflicts);
854 if (ws.m_conflicts.size() == 1) {
882 assert(ws.m_iters_conflicting.size() == 1);
885 m_limits.descendant_count += 1;
886 m_limits.descendant_size_vbytes += conflict->GetSizeWithDescendants();
889 auto ancestors{m_pool.CalculateMemPoolAncestors(*entry, m_limits)};
905 .ancestor_size_vbytes = m_limits.ancestor_size_vbytes,
906 .descendant_count = m_limits.descendant_count + 1,
913 ancestors = m_pool.CalculateMemPoolAncestors(*entry, cpfp_carve_out_limits);
917 ws.m_ancestors = *ancestors;
929 m_rbf = !ws.m_conflicts.empty();
933 bool MemPoolAccept::ReplacementChecks(Workspace& ws)
939 const uint256& hash = ws.m_hash;
942 CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize);
957 if (
const auto err_string{
GetEntriesForConflicts(tx, m_pool, ws.m_iters_conflicting, ws.m_all_conflicting)}) {
959 "too many potential replacements", *err_string);
964 "replacement-adds-unconfirmed", *err_string);
969 ws.m_conflicting_fees += it->GetModifiedFee();
970 ws.m_conflicting_size += it->GetTxSize();
972 if (
const auto err_string{
PaysForRBF(ws.m_conflicting_fees, ws.m_modified_fees, ws.m_vsize,
973 m_pool.m_incremental_relay_feerate, hash)}) {
979 bool MemPoolAccept::PackageMempoolChecks(
const std::vector<CTransactionRef>& txns,
986 assert(std::all_of(txns.cbegin(), txns.cend(), [
this](
const auto& tx)
987 { return !m_pool.exists(GenTxid::Txid(tx->GetHash()));}));
989 std::string err_string;
990 if (!m_pool.CheckPackageLimits(txns, m_limits, err_string)) {
997 bool MemPoolAccept::PolicyScriptChecks(
const ATMPArgs&
args, Workspace& ws)
1008 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, ws.m_precomputed_txdata)) {
1025 bool MemPoolAccept::ConsensusScriptChecks(
const ATMPArgs&
args, Workspace& ws)
1030 const uint256& hash = ws.m_hash;
1048 unsigned int currentBlockScriptVerifyFlags{
GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
1050 ws.m_precomputed_txdata, m_active_chainstate.CoinsTip())) {
1051 LogPrintf(
"BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.
ToString(), state.
ToString());
1058 bool MemPoolAccept::Finalize(
const ATMPArgs&
args, Workspace& ws)
1063 const uint256& hash = ws.m_hash;
1065 const bool bypass_limits =
args.m_bypass_limits;
1067 std::unique_ptr<CTxMemPoolEntry>& entry = ws.m_entry;
1073 it->GetTx().GetHash().ToString(),
1075 FormatMoney(ws.m_modified_fees - ws.m_conflicting_fees),
1076 (
int)entry->GetTxSize() - (
int)ws.m_conflicting_size);
1077 TRACE7(mempool, replaced,
1078 it->GetTx().GetHash().data(),
1081 std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(it->GetTime()).count(),
1086 ws.m_replaced_transactions.push_back(it->GetSharedTx());
1096 bool validForFeeEstimation = !bypass_limits && !
args.m_package_submission &&
IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
1099 m_pool.addUnchecked(*entry, ws.m_ancestors, validForFeeEstimation);
1105 if (!
args.m_package_submission && !bypass_limits) {
1113 bool MemPoolAccept::SubmitPackage(
const ATMPArgs&
args, std::vector<Workspace>& workspaces,
1115 std::map<const uint256, const MempoolAcceptResult>& results)
1121 assert(std::all_of(workspaces.cbegin(), workspaces.cend(), [
this](
const auto& ws){
1122 return !m_pool.exists(GenTxid::Txid(ws.m_ptx->GetHash())); }));
1124 bool all_submitted =
true;
1129 for (Workspace& ws : workspaces) {
1130 if (!ConsensusScriptChecks(
args, ws)) {
1134 all_submitted =
false;
1136 strprintf(
"BUG! PolicyScriptChecks succeeded but ConsensusScriptChecks failed: %s",
1137 ws.m_ptx->GetHash().ToString()));
1143 auto ancestors{m_pool.CalculateMemPoolAncestors(*ws.m_entry, m_limits)};
1148 all_submitted =
false;
1150 strprintf(
"BUG! Mempool ancestors or descendants were underestimated: %s",
1151 ws.m_ptx->GetHash().ToString()));
1153 ws.m_ancestors = std::move(ancestors).value_or(ws.m_ancestors);
1160 if (!Finalize(
args, ws)) {
1164 all_submitted =
false;
1166 strprintf(
"BUG! Adding to mempool failed: %s", ws.m_ptx->GetHash().ToString()));
1174 std::vector<uint256> all_package_wtxids;
1175 all_package_wtxids.reserve(workspaces.size());
1176 std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids),
1177 [](
const auto& ws) { return ws.m_ptx->GetWitnessHash(); });
1180 for (Workspace& ws : workspaces) {
1181 const auto effective_feerate =
args.m_package_feerates ? ws.m_package_feerate :
1182 CFeeRate{ws.m_modified_fees,
static_cast<uint32_t
>(ws.m_vsize)};
1183 const auto effective_feerate_wtxids =
args.m_package_feerates ? all_package_wtxids :
1184 std::vector<uint256>({ws.m_ptx->GetWitnessHash()});
1186 results.emplace(ws.m_ptx->GetWitnessHash(),
1188 ws.m_base_fees, effective_feerate, effective_feerate_wtxids));
1191 all_submitted =
false;
1196 return all_submitted;
1216 const CFeeRate effective_feerate{ws.m_modified_fees,
static_cast<uint32_t
>(ws.m_vsize)};
1217 const std::vector<uint256> single_wtxid{ws.m_ptx->GetWitnessHash()};
1219 if (
args.m_test_accept) {
1221 ws.m_base_fees, effective_feerate, single_wtxid);
1229 effective_feerate, single_wtxid);
1240 std::vector<Workspace> workspaces{};
1241 workspaces.reserve(txns.size());
1242 std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
1243 [](
const auto& tx) { return Workspace(tx); });
1244 std::map<const uint256, const MempoolAcceptResult> results;
1249 for (Workspace& ws : workspaces) {
1250 if (!PreChecks(
args, ws)) {
1261 m_viewmempool.PackageAddTransaction(ws.m_ptx);
1267 const auto m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
1268 [](int64_t
sum,
auto& ws) { return sum + ws.m_vsize; });
1269 const auto m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(),
CAmount{0},
1270 [](
CAmount sum,
auto& ws) { return sum + ws.m_modified_fees; });
1271 const CFeeRate package_feerate(m_total_modified_fees, m_total_vsize);
1273 if (
args.m_package_feerates &&
1274 !
CheckFeeRate(m_total_vsize, m_total_modified_fees, placeholder_state)) {
1282 std::string err_string;
1283 if (txns.size() > 1 && !PackageMempoolChecks(txns, package_state)) {
1287 std::vector<uint256> all_package_wtxids;
1288 all_package_wtxids.reserve(workspaces.size());
1289 std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids),
1290 [](
const auto& ws) { return ws.m_ptx->GetWitnessHash(); });
1291 for (Workspace& ws : workspaces) {
1292 ws.m_package_feerate = package_feerate;
1293 if (!PolicyScriptChecks(
args, ws)) {
1299 if (
args.m_test_accept) {
1300 const auto effective_feerate =
args.m_package_feerates ? ws.m_package_feerate :
1301 CFeeRate{ws.m_modified_fees,
static_cast<uint32_t
>(ws.m_vsize)};
1302 const auto effective_feerate_wtxids =
args.m_package_feerates ? all_package_wtxids :
1303 std::vector<uint256>{ws.m_ptx->GetWitnessHash()};
1304 results.emplace(ws.m_ptx->GetWitnessHash(),
1306 ws.m_vsize, ws.m_base_fees, effective_feerate,
1307 effective_feerate_wtxids));
1313 if (!SubmitPackage(
args, workspaces, package_state, results)) {
1341 assert(package.size() > 1);
1344 const auto& child = package.back();
1345 std::unordered_set<uint256, SaltedTxidHasher> unconfirmed_parent_txids;
1346 std::transform(package.cbegin(), package.cend() - 1,
1347 std::inserter(unconfirmed_parent_txids, unconfirmed_parent_txids.end()),
1348 [](
const auto& tx) { return tx->GetHash(); });
1355 const CCoinsViewCache& coins_tip_cache = m_active_chainstate.CoinsTip();
1356 for (
const auto& input : child->vin) {
1358 args.m_coins_to_uncache.push_back(input.prevout);
1364 m_view.SetBackend(m_active_chainstate.CoinsTip());
1365 const auto package_or_confirmed = [
this, &unconfirmed_parent_txids](
const auto& input) {
1366 return unconfirmed_parent_txids.count(input.prevout.hash) > 0 || m_view.HaveCoin(input.prevout);
1368 if (!std::all_of(child->vin.cbegin(), child->vin.cend(), package_or_confirmed)) {
1374 m_view.SetBackend(m_dummy);
1378 std::map<const uint256, const MempoolAcceptResult> results_final;
1387 ATMPArgs single_args = ATMPArgs::SingleInPackageAccept(
args);
1392 std::map<uint256, MempoolAcceptResult> individual_results_nonfinal;
1393 bool quit_early{
false};
1394 std::vector<CTransactionRef> txns_package_eval;
1395 for (
const auto& tx : package) {
1397 const auto& txid = tx->
GetHash();
1403 auto iter = m_pool.GetIter(txid);
1404 assert(iter != std::nullopt);
1414 auto iter = m_pool.GetIter(txid);
1415 assert(iter != std::nullopt);
1421 const auto single_res = AcceptSingleTransaction(tx, single_args);
1426 results_final.emplace(wtxid, single_res);
1440 individual_results_nonfinal.emplace(wtxid, single_res);
1442 individual_results_nonfinal.emplace(wtxid, single_res);
1443 txns_package_eval.push_back(tx);
1450 if (quit_early || txns_package_eval.empty()) {
1451 for (
const auto& [wtxid, mempoolaccept_res] : individual_results_nonfinal) {
1452 Assume(results_final.emplace(wtxid, mempoolaccept_res).second);
1459 auto submission_result = AcceptMultipleTransactions(txns_package_eval,
args);
1461 for (
const auto& [wtxid, mempoolaccept_res] : results_final) {
1462 Assume(submission_result.m_tx_results.emplace(wtxid, mempoolaccept_res).second);
1469 submission_result.m_tx_results.insert(individual_results_nonfinal.cbegin(),
1470 individual_results_nonfinal.cend());
1471 Assume(submission_result.m_tx_results.size() == package.size());
1473 return submission_result;
1479 int64_t accept_time,
bool bypass_limits,
bool test_accept)
1483 const CChainParams& chainparams{active_chainstate.m_chainman.GetParams()};
1484 assert(active_chainstate.GetMempool() !=
nullptr);
1485 CTxMemPool& pool{*active_chainstate.GetMempool()};
1487 std::vector<COutPoint> coins_to_uncache;
1488 auto args = MemPoolAccept::ATMPArgs::SingleAccept(chainparams, accept_time, bypass_limits, coins_to_uncache, test_accept);
1496 for (
const COutPoint& hashTx : coins_to_uncache)
1497 active_chainstate.CoinsTip().Uncache(hashTx);
1498 TRACE2(mempool, rejected,
1510 const Package& package,
bool test_accept)
1513 assert(!package.empty());
1514 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){return tx != nullptr;}));
1516 std::vector<COutPoint> coins_to_uncache;
1521 auto args = MemPoolAccept::ATMPArgs::PackageTestAccept(chainparams,
GetTime(), coins_to_uncache);
1522 return MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package,
args);
1524 auto args = MemPoolAccept::ATMPArgs::PackageChildWithParents(chainparams,
GetTime(), coins_to_uncache);
1525 return MemPoolAccept(pool, active_chainstate).AcceptPackage(package,
args);
1530 if (test_accept || result.m_state.IsInvalid()) {
1531 for (
const COutPoint& hashTx : coins_to_uncache) {
1550 nSubsidy >>= halvings;
1555 : m_dbview{
std::move(db_params),
std::move(options)},
1556 m_catcherview(&m_dbview) {}
1558 void CoinsViews::InitCache()
1561 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
1568 std::optional<uint256> from_snapshot_blockhash)
1569 : m_mempool(mempool),
1570 m_blockman(blockman),
1571 m_chainman(chainman),
1572 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1575 size_t cache_size_bytes,
1587 .cache_bytes = cache_size_bytes,
1588 .memory_only = in_memory,
1589 .wipe_data = should_wipe,
1595 void Chainstate::InitCoinsCache(
size_t cache_size_bytes)
1608 bool Chainstate::IsInitialBlockDownload()
const
1628 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1637 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1638 if (strCmd.empty())
return;
1643 std::string singleQuote(
"'");
1645 safeStatus = singleQuote+safeStatus+singleQuote;
1648 std::thread
t(runCommand, strCmd);
1659 if (IsInitialBlockDownload()) {
1664 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1682 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
1687 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
1742 if (!setup_results)
return false;
1744 const auto [num_elems, approx_size_bytes] = *setup_results;
1745 LogPrintf(
"Using %zu MiB out of %zu MiB requested for script execution cache, able to store %zu elements\n",
1746 approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
1772 std::vector<CScriptCheck>* pvChecks)
1777 pvChecks->reserve(tx.
vin.size());
1794 std::vector<CTxOut> spent_outputs;
1795 spent_outputs.reserve(tx.
vin.size());
1797 for (
const auto& txin : tx.
vin) {
1801 spent_outputs.emplace_back(coin.
out);
1803 txdata.
Init(tx, std::move(spent_outputs));
1807 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1818 pvChecks->emplace_back(std::move(check));
1819 }
else if (!check()) {
1847 if (cacheFullScriptStore && !pvChecks) {
1859 return state.
Error(strMessage);
1873 if (view.
HaveCoin(out)) fClean =
false;
1875 if (undo.nHeight == 0) {
1881 undo.nHeight = alternate.
nHeight;
1892 view.
AddCoin(out, std::move(undo), !fClean);
1906 error(
"DisconnectBlock(): failure reading undo data");
1910 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1911 error(
"DisconnectBlock(): block and undo data inconsistent");
1921 bool fEnforceBIP30 = !((pindex->
nHeight==91722 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e")) ||
1922 (pindex->
nHeight==91812 && pindex->
GetBlockHash() ==
uint256S(
"0x00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f")));
1925 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1929 bool is_bip30_exception = (is_coinbase && !fEnforceBIP30);
1933 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1934 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1937 bool is_spent = view.
SpendCoin(out, &coin);
1939 if (!is_bip30_exception) {
1950 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1953 for (
unsigned int j = tx.
vin.size(); j > 0;) {
2074 const auto time_start{SteadyClock::now()};
2090 if (!
CheckBlock(block, state, params.GetConsensus(), !fJustCheck, !fJustCheck)) {
2095 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
2097 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
2108 if (block_hash == params.GetConsensus().hashGenesisBlock) {
2114 bool fScriptChecks =
true;
2123 if (it->second.GetAncestor(pindex->
nHeight) == pindex &&
2145 const auto time_1{SteadyClock::now()};
2148 Ticks<MillisecondsDouble>(time_1 - time_start),
2190 static constexpr
int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
2222 fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->
GetBlockHash() == params.GetConsensus().BIP34Hash));
2227 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
2228 for (
const auto& tx : block.
vtx) {
2229 for (
size_t o = 0; o < tx->
vout.size(); o++) {
2231 LogPrintf(
"ERROR: ConnectBlock(): tried to overwrite transaction\n");
2239 int nLockTimeFlags = 0;
2247 const auto time_2{SteadyClock::now()};
2250 Ticks<MillisecondsDouble>(time_2 - time_1),
2262 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
2264 std::vector<int> prevheights;
2267 int64_t nSigOpsCost = 0;
2268 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
2269 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2273 nInputs += tx.
vin.size();
2287 LogPrintf(
"ERROR: %s: accumulated fee in the block out of range.\n", __func__);
2294 prevheights.resize(tx.
vin.size());
2295 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2299 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
2300 LogPrintf(
"ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
2311 LogPrintf(
"ERROR: ConnectBlock(): too many sigops\n");
2317 std::vector<CScriptCheck> vChecks;
2318 bool fCacheResults = fJustCheck;
2320 if (fScriptChecks && !
CheckInputScripts(tx, tx_state, view,
flags, fCacheResults, fCacheResults, txsdata[i], parallel_script_checks ? &vChecks :
nullptr)) {
2324 return error(
"ConnectBlock(): CheckInputScripts on %s failed with %s",
2327 control.
Add(std::move(vChecks));
2336 const auto time_3{SteadyClock::now()};
2338 LogPrint(
BCLog::BENCH,
" - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (
unsigned)block.
vtx.size(),
2339 Ticks<MillisecondsDouble>(time_3 - time_2), Ticks<MillisecondsDouble>(time_3 - time_2) / block.
vtx.size(),
2340 nInputs <= 1 ? 0 : Ticks<MillisecondsDouble>(time_3 - time_2) / (nInputs - 1),
2345 if (block.
vtx[0]->GetValueOut() > blockReward) {
2346 LogPrintf(
"ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.
vtx[0]->GetValueOut(), blockReward);
2350 if (!control.
Wait()) {
2351 LogPrintf(
"ERROR: %s: CheckQueue failed\n", __func__);
2354 const auto time_4{SteadyClock::now()};
2356 LogPrint(
BCLog::BENCH,
" - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1,
2357 Ticks<MillisecondsDouble>(time_4 - time_2),
2358 nInputs <= 1 ? 0 : Ticks<MillisecondsDouble>(time_4 - time_2) / (nInputs - 1),
2365 if (!
m_blockman.WriteUndoDataForBlock(blockundo, state, pindex, params)) {
2369 const auto time_5{SteadyClock::now()};
2372 Ticks<MillisecondsDouble>(time_5 - time_4),
2384 const auto time_6{SteadyClock::now()};
2387 Ticks<MillisecondsDouble>(time_6 - time_5),
2391 TRACE6(validation, block_connected,
2406 return this->GetCoinsCacheSizeState(
2412 size_t max_coins_cache_size_bytes,
2413 size_t max_mempool_size_bytes)
2418 int64_t nTotalSpace =
2419 max_coins_cache_size_bytes + std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
2422 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
2423 int64_t large_threshold =
2424 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2426 if (cacheSize > nTotalSpace) {
2427 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
2429 }
else if (cacheSize > large_threshold) {
2438 int nManualPruneHeight)
2441 assert(this->CanFlushToDisk());
2442 std::set<int> setFilesToPrune;
2443 bool full_flush_completed =
false;
2450 bool fFlushForPrune =
false;
2451 bool fDoFullFlush =
false;
2459 std::optional<std::string> limiting_lock;
2461 for (
const auto& prune_lock :
m_blockman.m_prune_locks) {
2462 if (prune_lock.second.height_first == std::numeric_limits<int>::max())
continue;
2465 last_prune = std::max(1, std::min(last_prune, lock_height));
2466 if (last_prune == lock_height) {
2467 limiting_lock = prune_lock.first;
2471 if (limiting_lock) {
2472 LogPrint(
BCLog::PRUNE,
"%s limited pruning to height %d\n", limiting_lock.value(), last_prune);
2475 if (nManualPruneHeight > 0) {
2485 if (!setFilesToPrune.empty()) {
2486 fFlushForPrune =
true;
2488 m_blockman.m_block_tree_db->WriteFlag(
"prunedblockfiles",
true);
2493 const auto nNow{SteadyClock::now()};
2510 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2512 if (fDoFullFlush || fPeriodicWrite) {
2515 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2529 return AbortNode(state,
"Failed to write to block index database");
2533 if (fFlushForPrune) {
2541 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2551 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
2555 return AbortNode(state,
"Failed to write to coin database");
2557 full_flush_completed =
true;
2559 int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - nNow)},
2561 (uint64_t)coins_count,
2562 (uint64_t)coins_mem_usage,
2563 (
bool)fFlushForPrune);
2566 if (full_flush_completed) {
2570 }
catch (
const std::runtime_error& e) {
2571 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2595 static bool fWarned =
false;
2614 const std::string& func_name,
2615 const std::string&
prefix,
2620 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",
2628 !warning_messages.empty() ?
strprintf(
" warning='%s'", warning_messages) :
"");
2631 void Chainstate::UpdateTip(
const CBlockIndex* pindexNew)
2634 const auto& coins_tip = this->
CoinsTip();
2640 if (
this != &
m_chainman.ActiveChainstate()) {
2642 constexpr
int BACKGROUND_LOG_INTERVAL = 2000;
2643 if (pindexNew->
nHeight % BACKGROUND_LOG_INTERVAL == 0) {
2644 UpdateTipLog(coins_tip, pindexNew, params, __func__,
"[background validation] ",
"");
2661 if (!this->IsInitialBlockDownload()) {
2665 ThresholdState state = checker.GetStateFor(pindex, params.GetConsensus(), warningcache.at(bit));
2698 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2701 return error(
"DisconnectTip(): Failed to read block");
2704 const auto time_start{SteadyClock::now()};
2708 if (DisconnectBlock(block, pindexDelete, view) !=
DISCONNECT_OK)
2710 bool flushed = view.
Flush();
2714 Ticks<MillisecondsDouble>(SteadyClock::now() - time_start));
2718 const int max_height_first{pindexDelete->
nHeight - 1};
2719 for (
auto& prune_lock :
m_blockman.m_prune_locks) {
2720 if (prune_lock.second.height_first <= max_height_first)
continue;
2722 prune_lock.second.height_first = max_height_first;
2723 LogPrint(
BCLog::PRUNE,
"%s prune lock moved back to %d\n", prune_lock.first, max_height_first);
2734 for (
auto it = block.
vtx.rbegin(); it != block.
vtx.rend(); ++it) {
2747 UpdateTip(pindexDelete->
pprev);
2813 const auto time_1{SteadyClock::now()};
2814 std::shared_ptr<const CBlock> pthisBlock;
2816 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2818 return AbortNode(state,
"Failed to read block");
2820 pthisBlock = pblockNew;
2823 pthisBlock = pblock;
2825 const CBlock& blockConnecting = *pthisBlock;
2827 const auto time_2{SteadyClock::now()};
2829 SteadyClock::time_point time_3;
2831 Ticks<MillisecondsDouble>(time_2 - time_1),
2836 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view);
2843 time_3 = SteadyClock::now();
2847 Ticks<MillisecondsDouble>(time_3 - time_2),
2850 bool flushed = view.
Flush();
2853 const auto time_4{SteadyClock::now()};
2856 Ticks<MillisecondsDouble>(time_4 - time_3),
2863 const auto time_5{SteadyClock::now()};
2866 Ticks<MillisecondsDouble>(time_5 - time_4),
2876 UpdateTip(pindexNew);
2878 const auto time_6{SteadyClock::now()};
2882 Ticks<MillisecondsDouble>(time_6 - time_5),
2886 Ticks<MillisecondsDouble>(time_6 - time_1),
2892 if (
this != &
m_chainman.ActiveChainstate()) {
2895 m_chainman.MaybeCompleteSnapshotValidation();
2923 bool fInvalidAncestor =
false;
2933 if (fFailedChain || fMissingData) {
2940 while (pindexTest != pindexFailed) {
2943 }
else if (fMissingData) {
2948 std::make_pair(pindexFailed->
pprev, pindexFailed));
2951 pindexFailed = pindexFailed->
pprev;
2954 fInvalidAncestor =
true;
2957 pindexTest = pindexTest->
pprev;
2959 if (!fInvalidAncestor)
2991 bool fBlocksDisconnected =
false;
3002 AbortNode(state,
"Failed to disconnect block; see debug.log for details");
3005 fBlocksDisconnected =
true;
3009 std::vector<CBlockIndex*> vpindexToConnect;
3010 bool fContinue =
true;
3015 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
3016 vpindexToConnect.clear();
3017 vpindexToConnect.reserve(nTargetHeight -
nHeight);
3020 vpindexToConnect.push_back(pindexIter);
3021 pindexIter = pindexIter->
pprev;
3027 if (!
ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
3034 fInvalidFound =
true;
3055 if (fBlocksDisconnected) {
3075 bool fNotify =
false;
3076 bool fInitialBlockDownload =
false;
3081 pindexHeader = chainstate.m_chainman.m_best_header;
3083 if (pindexHeader != pindexHeaderOld) {
3085 fInitialBlockDownload = chainstate.IsInitialBlockDownload();
3086 pindexHeaderOld = pindexHeader;
3104 bool Chainstate::ActivateBestChain(
BlockValidationState& state, std::shared_ptr<const CBlock> pblock)
3123 LogPrintf(
"m_disabled is set - this chainstate should not be in operation. "
3143 LOCK(MempoolMutex());
3145 bool blocks_connected =
false;
3151 if (pindexMostWork ==
nullptr) {
3156 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
3160 bool fInvalidFound =
false;
3161 std::shared_ptr<const CBlock> nullBlockPtr;
3162 if (!
ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
3166 blocks_connected =
true;
3168 if (fInvalidFound) {
3170 pindexMostWork =
nullptr;
3175 assert(trace.pblock && trace.pindex);
3188 if (!blocks_connected)
return true;
3191 bool fInitialDownload = IsInitialBlockDownload();
3195 if (pindexFork != pindexNewTip) {
3217 }
while (pindexNewTip != pindexMostWork);
3256 return ActivateBestChain(state, std::shared_ptr<const CBlock>());
3266 if (pindex->
nHeight == 0)
return false;
3269 bool pindex_was_in_chain =
false;
3270 int disconnected = 0;
3284 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
3288 for (
auto& entry :
m_blockman.m_block_index) {
3299 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
3314 LOCK(MempoolMutex());
3316 pindex_was_in_chain =
true;
3329 if (!
ret)
return false;
3349 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
3350 while (candidate_it != candidate_blocks_by_work.end()) {
3353 candidate_it = candidate_blocks_by_work.erase(candidate_it);
3361 to_mark_failed = invalid_walk_tip;
3386 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3396 if (pindex_was_in_chain) {
3408 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3409 if (!block_index.IsValid() && block_index.GetAncestor(
nHeight) == pindex) {
3415 if (&block_index ==
m_chainman.m_best_invalid) {
3424 while (pindex !=
nullptr) {
3430 pindex = pindex->
pprev;
3438 pindexNew->
nTx = block.
vtx.size();
3440 pindexNew->nFile = pos.
nFile;
3441 pindexNew->nDataPos = pos.
nPos;
3442 pindexNew->nUndoPos = 0;
3452 std::deque<CBlockIndex*> queue;
3453 queue.push_back(pindexNew);
3456 while (!queue.empty()) {
3464 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
3465 while (range.first != range.second) {
3466 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3467 queue.push_back(it->second);
3506 if (fCheckMerkleRoot) {
3530 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3532 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3533 if (block.
vtx[i]->IsCoinBase())
3538 for (
const auto& tx : block.
vtx) {
3548 unsigned int nSigOps = 0;
3549 for (
const auto& tx : block.
vtx)
3556 if (fCheckPOW && fCheckMerkleRoot)
3562 void ChainstateManager::UpdateUncommittedBlockStructures(
CBlock& block,
const CBlockIndex* pindexPrev)
const
3565 static const std::vector<unsigned char>
nonce(32, 0x00);
3568 tx.
vin[0].scriptWitness.stack.resize(1);
3569 tx.
vin[0].scriptWitness.stack[0] =
nonce;
3576 std::vector<unsigned char> commitment;
3578 std::vector<unsigned char>
ret(32, 0x00);
3594 tx.
vout.push_back(out);
3597 UpdateUncommittedBlockStructures(block, pindexPrev);
3603 return std::all_of(headers.cbegin(), headers.cend(),
3604 [&](
const auto& header) { return CheckProofOfWork(header.GetHash(), header.nBits, consensusParams);});
3629 assert(pindexPrev !=
nullptr);
3638 if (chainman.m_options.checkpoints_enabled) {
3642 const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
3643 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
3644 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
3654 if (block.
Time() > now + std::chrono::seconds{MAX_FUTURE_BLOCK_TIME}) {
3677 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3680 bool enforce_locktime_median_time_past{
false};
3682 assert(pindexPrev !=
nullptr);
3683 enforce_locktime_median_time_past =
true;
3686 const int64_t nLockTimeCutoff{enforce_locktime_median_time_past ?
3691 for (
const auto& tx : block.
vtx) {
3701 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3702 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3715 bool fHaveWitness =
false;
3719 bool malleated =
false;
3724 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3728 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3731 fHaveWitness =
true;
3736 if (!fHaveWitness) {
3737 for (
const auto& tx : block.
vtx) {
3763 BlockMap::iterator miSelf{
m_blockman.m_block_index.find(hash)};
3765 if (miSelf !=
m_blockman.m_block_index.end()) {
3789 pindexPrev = &((*mi).second);
3824 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
3827 while (invalid_walk != failedit) {
3830 invalid_walk = invalid_walk->
pprev;
3838 if (!min_pow_checked) {
3856 "Saw new header hash=%s height=%d", hash.
ToString(), pindex->
nHeight);
3858 if (ActiveChainstate().IsInitialBlockDownload()) {
3876 ActiveChainstate().CheckBlockIndex();
3887 if (ActiveChainstate().IsInitialBlockDownload() && ppindex && *ppindex) {
3890 const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
3891 LogPrintf(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
3900 const auto& chainstate = ActiveChainstate();
3909 auto now = std::chrono::steady_clock::now();
3910 if (now < m_last_presync_update + std::chrono::milliseconds{250})
return;
3911 m_last_presync_update = now;
3913 bool initial_download = chainstate.IsInitialBlockDownload();
3915 if (initial_download) {
3917 const double progress{100.0 * height / (height + blocks_left)};
3918 LogPrintf(
"Pre-synchronizing blockheaders, height: %d (~%.2f%%)\n", height, progress);
3925 const CBlock& block = *pblock;
3927 if (fNewBlock) *fNewBlock =
false;
3931 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3936 if (!accepted_header)
3959 if (fAlreadyHave)
return true;
3961 if (pindex->
nTx != 0)
return true;
3962 if (!fHasMoreOrSameWork)
return true;
3963 if (fTooFarAhead)
return true;
3974 if (!
CheckBlock(block, state, params.GetConsensus()) ||
3989 if (fNewBlock) *fNewBlock =
true;
3992 if (blockPos.IsNull()) {
3993 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3997 }
catch (
const std::runtime_error& e) {
3998 return AbortNode(state, std::string(
"System error: ") + e.what());
4014 if (new_block) *new_block =
false;
4029 ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing,
nullptr, new_block, min_pow_checked);
4033 return error(
"%s: AcceptBlock FAILED (%s)", __func__, state.
ToString());
4040 if (!ActiveChainstate().ActivateBestChain(state, block)) {
4041 return error(
"%s: ActivateBestChain failed (%s)", __func__, state.
ToString());
4050 Chainstate& active_chainstate = ActiveChainstate();
4068 bool fCheckMerkleRoot)
4075 indexDummy.
pprev = pindexPrev;
4081 return error(
"%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.
ToString());
4083 return error(
"%s: Consensus::CheckBlock: %s", __func__, state.
ToString());
4085 return error(
"%s: Consensus::ContextualCheckBlock: %s", __func__, state.
ToString());
4086 if (!chainstate.
ConnectBlock(block, state, &indexDummy, viewNew,
true)) {
4131 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4141 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, 0,
false);
4153 int nCheckLevel,
int nCheckDepth)
4162 if (nCheckDepth <= 0 || nCheckDepth > chainstate.
m_chain.
Height()) {
4165 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4166 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4170 int nGoodTransactions = 0;
4173 bool skipped_no_block_data{
false};
4174 bool skipped_l3_checks{
false};
4175 LogPrintf(
"Verification progress: 0%%\n");
4180 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
4181 if (reportDone < percentageDone / 10) {
4183 LogPrintf(
"Verification progress: %d%%\n", percentageDone);
4184 reportDone = percentageDone / 10;
4186 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
4193 LogPrintf(
"VerifyDB(): block verification stopping at height %d (no data). This could be due to pruning or use of an assumeutxo snapshot.\n", pindex->
nHeight);
4194 skipped_no_block_data =
true;
4204 if (nCheckLevel >= 1 && !
CheckBlock(block, state, consensus_params)) {
4205 LogPrintf(
"Verification error: found bad block at %d, hash=%s (%s)\n",
4210 if (nCheckLevel >= 2 && pindex) {
4222 if (nCheckLevel >= 3) {
4231 nGoodTransactions = 0;
4232 pindexFailure = pindex;
4234 nGoodTransactions += block.
vtx.size();
4237 skipped_l3_checks =
true;
4242 if (pindexFailure) {
4243 LogPrintf(
"Verification error: coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.
m_chain.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
4246 if (skipped_l3_checks) {
4247 LogPrintf(
"Skipped verification of level >=3 (insufficient database cache size). Consider increasing -dbcache.\n");
4254 if (nCheckLevel >= 4 && !skipped_l3_checks) {
4256 const int percentageDone = std::max(1, std::min(99, 100 - (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * 50)));
4257 if (reportDone < percentageDone / 10) {
4259 LogPrintf(
"Verification progress: %d%%\n", percentageDone);
4260 reportDone = percentageDone / 10;
4262 uiInterface.ShowProgress(
_(
"Verifying blocks…").translated, percentageDone,
false);
4269 if (!chainstate.
ConnectBlock(block, state, pindex, coins)) {
4277 LogPrintf(
"Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
4279 if (skipped_l3_checks) {
4282 if (skipped_no_block_data) {
4299 if (!tx->IsCoinBase()) {
4300 for (
const CTxIn &txin : tx->vin) {
4318 if (hashHeads.empty())
return true;
4319 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4321 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, 0,
false);
4328 if (
m_blockman.m_block_index.count(hashHeads[0]) == 0) {
4329 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4331 pindexNew = &(
m_blockman.m_block_index[hashHeads[0]]);
4333 if (!hashHeads[1].IsNull()) {
4334 if (
m_blockman.m_block_index.count(hashHeads[1]) == 0) {
4335 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4337 pindexOld = &(
m_blockman.m_block_index[hashHeads[1]]);
4339 assert(pindexFork !=
nullptr);
4343 while (pindexOld != pindexFork) {
4359 pindexOld = pindexOld->
pprev;
4363 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4368 uiInterface.ShowProgress(
_(
"Replaying blocks…").translated, (
int) ((
nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
4390 block = block->pprev;
4396 void Chainstate::UnloadBlockIndex()
4399 nBlockSequenceId = 1;
4410 if (!
ret)
return false;
4412 m_blockman.ScanAndUnlinkAlreadyPrunedFiles();
4414 std::vector<CBlockIndex*> vSortedByHeight{
m_blockman.GetAllBlockIndices()};
4415 std::sort(vSortedByHeight.begin(), vSortedByHeight.end(),
4419 int first_assumed_valid_height = std::numeric_limits<int>::max();
4421 for (
const CBlockIndex* block : vSortedByHeight) {
4422 if (block->IsAssumedValid()) {
4423 auto chainstates =
GetAll();
4429 auto any_chain = [&](
auto fnc) {
return std::any_of(chainstates.cbegin(), chainstates.cend(), fnc); };
4433 first_assumed_valid_height = block->nHeight;
4434 LogPrintf(
"Saw first assumedvalid block at height %d (%s)\n",
4435 first_assumed_valid_height, block->
ToString());
4471 pindex->
nHeight < first_assumed_valid_height) {
4477 m_best_invalid = pindex;
4483 needs_init =
m_blockman.m_block_index.empty();
4493 LogPrintf(
"Initializing databases...\n");
4508 if (
m_blockman.m_block_index.count(params.GenesisBlock().GetHash()))
4512 const CBlock& block = params.GenesisBlock();
4514 if (blockPos.IsNull()) {
4515 return error(
"%s: writing genesis block to disk failed", __func__);
4519 }
catch (
const std::runtime_error& e) {
4520 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4529 std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent)
4534 assert(!dbp == !blocks_with_unknown_parent);
4536 const auto start{SteadyClock::now()};
4545 uint64_t nRewind = blkdat.GetPos();
4546 while (!blkdat.eof()) {
4549 blkdat.SetPos(nRewind);
4552 unsigned int nSize = 0;
4556 blkdat.FindByte(params.MessageStart()[0]);
4557 nRewind = blkdat.GetPos() + 1;
4566 }
catch (
const std::exception&) {
4573 const uint64_t nBlockPos{blkdat.GetPos()};
4575 dbp->
nPos = nBlockPos;
4576 blkdat.SetLimit(nBlockPos + nSize);
4582 nRewind = nBlockPos + nSize;
4583 blkdat.SkipTo(nRewind);
4590 if (dbp && blocks_with_unknown_parent) {
4591 blocks_with_unknown_parent->emplace(header.
hashPrevBlock, *dbp);
4600 blkdat.SetPos(nBlockPos);
4601 std::shared_ptr<CBlock> pblock{std::make_shared<CBlock>()};
4603 nRewind = blkdat.GetPos();
4606 if (
AcceptBlock(pblock, state,
nullptr,
true, dbp,
nullptr,
true)) {
4612 }
else if (hash != params.GetConsensus().hashGenesisBlock && pindex->
nHeight % 1000 == 0) {
4618 if (hash == params.GetConsensus().hashGenesisBlock) {
4620 if (!ActivateBestChain(state,
nullptr)) {
4627 if (!blocks_with_unknown_parent)
continue;
4630 std::deque<uint256> queue;
4631 queue.push_back(hash);
4632 while (!queue.empty()) {
4635 auto range = blocks_with_unknown_parent->equal_range(head);
4636 while (range.first != range.second) {
4637 std::multimap<uint256, FlatFilePos>::iterator it = range.first;
4638 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4640 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4644 if (
AcceptBlock(pblockrecursive, dummy,
nullptr,
true, &it->second,
nullptr,
true)) {
4646 queue.push_back(pblockrecursive->GetHash());
4650 blocks_with_unknown_parent->erase(it);
4654 }
catch (
const std::exception& e) {
4666 LogPrint(
BCLog::REINDEX,
"%s: unexpected data at file offset 0x%x - %s. continuing\n", __func__, (nRewind - 1), e.what());
4669 }
catch (
const std::runtime_error& e) {
4670 AbortNode(std::string(
"System error: ") + e.what());
4672 LogPrintf(
"Loaded %i blocks from external file in %dms\n", nLoaded, Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
4692 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4693 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
4694 forward.emplace(block_index.pprev, &block_index);
4699 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4701 rangeGenesis.first++;
4702 assert(rangeGenesis.first == rangeGenesis.second);
4713 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4715 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4716 while (pindex !=
nullptr) {
4718 if (pindexFirstInvalid ==
nullptr && pindex->nStatus &
BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
4722 pindexFirstMissing = pindex;
4724 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4731 if (pindexFirstNotTransactionsValid ==
nullptr &&
4733 pindexFirstNotTransactionsValid = pindex;
4736 if (pindexFirstNotChainValid ==
nullptr &&
4738 pindexFirstNotChainValid = pindex;
4741 if (pindexFirstNotScriptsValid ==
nullptr &&
4743 pindexFirstNotScriptsValid = pindex;
4748 if (pindex->
pprev ==
nullptr) {
4761 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4783 assert(pindexFirstNotTreeValid ==
nullptr);
4787 if (pindexFirstInvalid ==
nullptr) {
4792 if (pindexFirstInvalid ==
nullptr) {
4793 const bool is_active =
this == &
m_chainman.ActiveChainstate();
4803 if (is_active && (pindexFirstMissing ==
nullptr || pindex ==
m_chain.
Tip())) {
4814 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
m_blockman.
m_blocks_unlinked.equal_range(pindex->
pprev);
4815 bool foundInUnlinked =
false;
4816 while (rangeUnlinked.first != rangeUnlinked.second) {
4817 assert(rangeUnlinked.first->first == pindex->
pprev);
4818 if (rangeUnlinked.first->second == pindex) {
4819 foundInUnlinked =
true;
4822 rangeUnlinked.first++;
4824 if (pindex->
pprev && (pindex->nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4829 if (pindexFirstMissing ==
nullptr)
assert(!foundInUnlinked);
4830 if (pindex->
pprev && (pindex->nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4842 if (pindexFirstInvalid ==
nullptr) {
4851 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4852 if (range.first != range.second) {
4854 pindex = range.first->second;
4863 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4864 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4865 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4866 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4867 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4868 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4869 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4873 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4874 while (rangePar.first->second != pindex) {
4875 assert(rangePar.first != rangePar.second);
4880 if (rangePar.first != rangePar.second) {
4882 pindex = rangePar.first->second;
4894 assert(nNodes == forward.size());
4901 return strprintf(
"Chainstate [%s] @ height %d (%s)",
4906 bool Chainstate::ResizeCoinsCaches(
size_t coinstip_size,
size_t coinsdb_size)
4919 LogPrintf(
"[%s] resized coinsdb cache to %.1f MiB\n",
4920 this->
ToString(), coinsdb_size * (1.0 / 1024 / 1024));
4921 LogPrintf(
"[%s] resized coinstip cache to %.1f MiB\n",
4922 this->
ToString(), coinstip_size * (1.0 / 1024 / 1024));
4927 if (coinstip_size > old_coinstip_size) {
4941 if (pindex ==
nullptr)
4944 int64_t nNow = time(
nullptr);
4954 return std::min<double>(pindex->
nChainTx / fTxTotal, 1.0);
4960 if (m_active_chainstate && m_active_chainstate->m_from_snapshot_blockhash) {
4962 return m_active_chainstate->m_from_snapshot_blockhash;
4964 return std::nullopt;
4970 std::vector<Chainstate*> out;
4972 for (
Chainstate*
cs : {m_ibd_chainstate.get(), m_snapshot_chainstate.get()}) {
4973 if (this->IsUsable(
cs)) out.push_back(
cs);
4982 assert(!m_ibd_chainstate);
4983 assert(!m_active_chainstate);
4985 m_ibd_chainstate = std::make_unique<Chainstate>(mempool,
m_blockman, *
this);
4986 m_active_chainstate = m_ibd_chainstate.get();
4987 return *m_active_chainstate;
4994 const auto assumeutxo_found = valid_assumeutxos_map.find(height);
4996 if (assumeutxo_found != valid_assumeutxos_map.end()) {
4997 return &assumeutxo_found->second;
5011 bool removed = fs::remove(base_blockhash_path);
5013 LogPrintf(
"[snapshot] failed to remove file %s\n",
5017 LogPrintf(
"[snapshot] snapshot chainstate dir being removed lacks %s file\n",
5023 LogPrintf(
"Removing leveldb dir at %s\n", path_str);
5027 const bool destroyed = dbwrapper::DestroyDB(path_str, {}).ok();
5030 LogPrintf(
"error: leveldb DestroyDB call failed on %s\n", path_str);
5050 LogPrintf(
"[snapshot] can't activate a snapshot-based chainstate more than once\n");
5054 int64_t current_coinsdb_cache_size{0};
5055 int64_t current_coinstip_cache_size{0};
5063 static constexpr
double IBD_CACHE_PERC = 0.01;
5064 static constexpr
double SNAPSHOT_CACHE_PERC = 0.99;
5076 current_coinsdb_cache_size = this->ActiveChainstate().m_coinsdb_cache_size_bytes;
5077 current_coinstip_cache_size = this->ActiveChainstate().m_coinstip_cache_size_bytes;
5081 this->ActiveChainstate().ResizeCoinsCaches(
5082 static_cast<size_t>(current_coinstip_cache_size * IBD_CACHE_PERC),
5083 static_cast<size_t>(current_coinsdb_cache_size * IBD_CACHE_PERC));
5087 return std::make_unique<Chainstate>(
5088 nullptr,
m_blockman, *
this, base_blockhash));
5092 snapshot_chainstate->InitCoinsDB(
5093 static_cast<size_t>(current_coinsdb_cache_size * SNAPSHOT_CACHE_PERC),
5094 in_memory,
false,
"chainstate");
5095 snapshot_chainstate->InitCoinsCache(
5096 static_cast<size_t>(current_coinstip_cache_size * SNAPSHOT_CACHE_PERC));