6#include <bitcoin-build-config.h>
100 "level 0 reads the blocks from disk",
101 "level 1 verifies block validity",
102 "level 2 verifies undo data",
103 "level 3 checks disconnection of tip blocks",
104 "level 4 tries to reconnect the blocks",
105 "each level includes the checks of the previous levels",
143 std::vector<CScriptCheck>* pvChecks =
nullptr)
156 const int nBlockHeight = active_chain_tip.nHeight + 1;
163 const int64_t nBlockTime{active_chain_tip.GetMedianTimePast()};
165 return IsFinalTx(tx, nBlockHeight, nBlockTime);
179std::optional<std::vector<int>> CalculatePrevHeights(
184 std::vector<int> prev_heights;
185 prev_heights.resize(tx.
vin.size());
186 for (
size_t i = 0; i < tx.
vin.size(); ++i) {
187 if (
auto coin{coins.
GetCoin(tx.
vin[i].prevout)}) {
207 auto prev_heights{CalculatePrevHeights(*tip, coins_view, tx)};
208 if (!prev_heights.has_value())
return std::nullopt;
211 next_tip.
pprev = tip;
229 int max_input_height{0};
230 for (
const int height : prev_heights.value()) {
232 if (height != next_tip.
nHeight) {
233 max_input_height = std::max(max_input_height, height);
271 int expired = pool.Expire(GetTime<std::chrono::seconds>() - pool.m_opts.expiry);
276 std::vector<COutPoint> vNoSpendsRemaining;
277 pool.TrimToSize(pool.m_opts.max_size_bytes, &vNoSpendsRemaining);
278 for (
const COutPoint& removed : vNoSpendsRemaining)
279 coins_cache.Uncache(removed);
285 if (active_chainstate.m_chainman.IsInitialBlockDownload()) {
290 if (active_chainstate.m_chain.Height() < active_chainstate.m_chainman.m_best_header->nHeight - 1) {
304 std::vector<uint256> vHashUpdate;
311 const auto queuedTx = disconnectpool.
take();
312 auto it = queuedTx.rbegin();
313 while (it != queuedTx.rend()) {
315 if (!fAddToMempool || (*it)->IsCoinBase() ||
317 true,
false).m_result_type !=
323 vHashUpdate.push_back((*it)->GetHash());
364 it->UpdateLockPoints(*new_lock_points);
371 if (it->GetSpendsCoinbase()) {
377 if (coin.IsCoinBase() && mempool_spend_height - coin.nHeight <
COINBASE_MATURITY) {
413 if (coin.
IsSpent())
return false;
443 m_viewmempool(&active_chainstate.CoinsTip(), m_pool),
444 m_active_chainstate(active_chainstate)
452 const int64_t m_accept_time;
453 const bool m_bypass_limits;
461 std::vector<COutPoint>& m_coins_to_uncache;
463 const bool m_test_accept;
467 const bool m_allow_replacement;
469 const bool m_allow_sibling_eviction;
474 const bool m_package_submission;
478 const bool m_package_feerates;
483 const std::optional<CFeeRate> m_client_maxfeerate;
486 const bool m_allow_carveouts;
489 static ATMPArgs SingleAccept(
const CChainParams& chainparams, int64_t accept_time,
490 bool bypass_limits, std::vector<COutPoint>& coins_to_uncache,
492 return ATMPArgs{ chainparams,
507 static ATMPArgs PackageTestAccept(
const CChainParams& chainparams, int64_t accept_time,
508 std::vector<COutPoint>& coins_to_uncache) {
509 return ATMPArgs{ chainparams,
524 static ATMPArgs PackageChildWithParents(
const CChainParams& chainparams, int64_t accept_time,
525 std::vector<COutPoint>& coins_to_uncache,
const std::optional<CFeeRate>& client_maxfeerate) {
526 return ATMPArgs{ chainparams,
541 static ATMPArgs SingleInPackageAccept(
const ATMPArgs& package_args) {
542 return ATMPArgs{ package_args.m_chainparams,
543 package_args.m_accept_time,
545 package_args.m_coins_to_uncache,
546 package_args.m_test_accept,
551 package_args.m_client_maxfeerate,
562 std::vector<COutPoint>& coins_to_uncache,
564 bool allow_replacement,
565 bool allow_sibling_eviction,
566 bool package_submission,
567 bool package_feerates,
568 std::optional<CFeeRate> client_maxfeerate,
569 bool allow_carveouts)
570 : m_chainparams{chainparams},
571 m_accept_time{accept_time},
572 m_bypass_limits{bypass_limits},
573 m_coins_to_uncache{coins_to_uncache},
574 m_test_accept{test_accept},
575 m_allow_replacement{allow_replacement},
576 m_allow_sibling_eviction{allow_sibling_eviction},
577 m_package_submission{package_submission},
578 m_package_feerates{package_feerates},
579 m_client_maxfeerate{client_maxfeerate},
580 m_allow_carveouts{allow_carveouts}
584 if (m_package_feerates) {
585 Assume(m_package_submission);
586 Assume(!m_allow_carveouts);
587 Assume(!m_allow_sibling_eviction);
589 if (m_allow_sibling_eviction)
Assume(m_allow_replacement);
629 explicit Workspace(
const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
632 std::set<Txid> m_conflicts;
642 bool m_sibling_eviction{
false};
677 bool PackageMempoolChecks(
const std::vector<CTransactionRef>& txns,
678 std::vector<Workspace>& workspaces,
699 std::map<uint256, MempoolAcceptResult>& results)
707 CAmount mempoolRejectFee = m_pool.GetMinFee().GetFee(package_size);
708 if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
712 if (package_fee < m_pool.m_opts.min_relay_feerate.GetFee(package_size)) {
714 strprintf(
"%d < %d", package_fee, m_pool.m_opts.min_relay_feerate.GetFee(package_size)));
721 return m_active_chainstate.m_chainman.m_validation_cache;
734 struct SubPackageState {
736 CAmount m_total_modified_fees{0};
738 int64_t m_total_vsize{0};
745 std::list<CTransactionRef> m_replaced_transactions;
747 std::unique_ptr<CTxMemPool::ChangeSet> m_changeset;
752 size_t m_conflicting_size{0};
755 struct SubPackageState m_subpackage;
760 m_subpackage = SubPackageState{};
763 CleanupTemporaryCoins();
767bool MemPoolAccept::PreChecks(ATMPArgs&
args, Workspace& ws)
773 const Txid& hash = ws.m_hash;
776 const int64_t nAcceptTime =
args.m_accept_time;
777 const bool bypass_limits =
args.m_bypass_limits;
778 std::vector<COutPoint>& coins_to_uncache =
args.m_coins_to_uncache;
793 if (m_pool.m_opts.require_standard && !
IsStandardTx(tx, m_pool.m_opts.max_datacarrier_bytes, m_pool.m_opts.permit_bare_multisig, m_pool.m_opts.dust_relay_feerate, reason)) {
821 if (ptxConflicting) {
822 if (!
args.m_allow_replacement) {
826 ws.m_conflicts.insert(ptxConflicting->
GetHash());
830 m_view.SetBackend(m_viewmempool);
836 coins_to_uncache.push_back(txin.
prevout);
842 if (!m_view.HaveCoin(txin.
prevout)) {
857 m_view.GetBestBlock();
862 m_view.SetBackend(m_dummy);
864 assert(m_active_chainstate.m_blockman.LookupBlockIndex(m_view.GetBestBlock()) == m_active_chainstate.m_chain.Tip());
871 const std::optional<LockPoints> lock_points{
CalculateLockPointsAtTip(m_active_chainstate.m_chain.Tip(), m_view, tx)};
894 bool fSpendsCoinbase =
false;
896 const Coin &coin = m_view.AccessCoin(txin.
prevout);
898 fSpendsCoinbase =
true;
905 const uint64_t entry_sequence = bypass_limits ? 0 : m_pool.GetSequence();
906 if (!m_subpackage.m_changeset) {
907 m_subpackage.m_changeset = m_pool.GetChangeSet();
909 ws.m_tx_handle = m_subpackage.m_changeset->StageAddition(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(), entry_sequence, fSpendsCoinbase, nSigOpsCost, lock_points.value());
912 ws.m_modified_fees = ws.m_tx_handle->GetModifiedFee();
914 ws.m_vsize = ws.m_tx_handle->GetTxSize();
917 if (m_pool.m_opts.require_standard) {
918 if (!
PreCheckEphemeralTx(*ptx, m_pool.m_opts.dust_relay_feerate, ws.m_base_fees, ws.m_modified_fees, state)) {
933 if (!bypass_limits && ws.m_ptx->version !=
TRUC_VERSION && ws.m_modified_fees < m_pool.m_opts.min_relay_feerate.GetFee(ws.m_vsize)) {
937 strprintf(
"%d < %d", ws.m_modified_fees, m_pool.m_opts.min_relay_feerate.GetFee(ws.m_vsize)));
942 if (!bypass_limits && !
args.m_package_feerates && !
CheckFeeRate(ws.m_vsize, ws.m_modified_fees, state))
return false;
944 ws.m_iters_conflicting = m_pool.GetIterSet(ws.m_conflicts);
951 if (ws.m_conflicts.size() == 1 &&
args.m_allow_carveouts) {
979 assert(ws.m_iters_conflicting.size() == 1);
986 if (
auto ancestors{m_subpackage.m_changeset->CalculateMemPoolAncestors(ws.m_tx_handle, maybe_rbf_limits)}) {
987 ws.m_ancestors = std::move(*ancestors);
993 if (!
args.m_allow_carveouts) {
1018 if (
auto ancestors_retry{m_subpackage.m_changeset->CalculateMemPoolAncestors(ws.m_tx_handle, cpfp_carve_out_limits)}) {
1019 ws.m_ancestors = std::move(*ancestors_retry);
1028 if (
const auto err{
SingleTRUCChecks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
1030 if (
args.m_allow_sibling_eviction && err->second !=
nullptr) {
1036 ws.m_conflicts.insert(err->second->GetHash());
1040 ws.m_iters_conflicting.insert(m_pool.GetIter(err->second->GetHash()).value());
1041 ws.m_sibling_eviction =
true;
1062 m_subpackage.m_rbf |= !ws.m_conflicts.empty();
1066bool MemPoolAccept::ReplacementChecks(Workspace& ws)
1072 const uint256& hash = ws.m_hash;
1075 CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize);
1089 strprintf(
"insufficient fee%s", ws.m_sibling_eviction ?
" (including sibling eviction)" :
""), *err_string);
1097 strprintf(
"too many potential replacements%s", ws.m_sibling_eviction ?
" (including sibling eviction)" :
""), *err_string);
1102 Assume(!ws.m_sibling_eviction);
1104 strprintf(
"replacement-adds-unconfirmed%s", ws.m_sibling_eviction ?
" (including sibling eviction)" :
""), *err_string);
1110 m_subpackage.m_conflicting_fees += it->GetModifiedFee();
1111 m_subpackage.m_conflicting_size += it->GetTxSize();
1113 if (
const auto err_string{
PaysForRBF(m_subpackage.m_conflicting_fees, ws.m_modified_fees, ws.m_vsize,
1114 m_pool.m_opts.incremental_relay_feerate, hash)}) {
1117 strprintf(
"insufficient fee%s", ws.m_sibling_eviction ?
" (including sibling eviction)" :
""), *err_string);
1121 for (
auto it : all_conflicts) {
1122 m_subpackage.m_changeset->StageRemoval(it);
1127bool MemPoolAccept::PackageMempoolChecks(
const std::vector<CTransactionRef>& txns,
1128 std::vector<Workspace>& workspaces,
1129 const int64_t total_vsize,
1136 assert(std::all_of(txns.cbegin(), txns.cend(), [
this](
const auto& tx)
1137 { return !m_pool.exists(GenTxid::Txid(tx->GetHash()));}));
1139 assert(txns.size() == workspaces.size());
1141 auto result = m_pool.CheckPackageLimits(txns, total_vsize);
1148 if (!m_subpackage.m_rbf)
return true;
1159 for (
const auto& ws : workspaces) {
1160 if (!ws.m_ancestors.empty()) {
1167 for (Workspace& ws : workspaces) {
1169 direct_conflict_iters.merge(ws.m_iters_conflicting);
1172 const auto& parent_ws = workspaces[0];
1173 const auto& child_ws = workspaces[1];
1181 "package RBF failed: too many potential replacements", *err_string);
1186 m_subpackage.m_changeset->StageRemoval(it);
1187 m_subpackage.m_conflicting_fees += it->GetModifiedFee();
1188 m_subpackage.m_conflicting_size += it->GetTxSize();
1192 const Txid& child_hash = child_ws.m_ptx->GetHash();
1193 if (
const auto err_string{
PaysForRBF(m_subpackage.m_conflicting_fees,
1194 m_subpackage.m_total_modified_fees,
1195 m_subpackage.m_total_vsize,
1196 m_pool.m_opts.incremental_relay_feerate, child_hash)}) {
1198 "package RBF failed: insufficient anti-DoS fees", *err_string);
1203 const CFeeRate parent_feerate(parent_ws.m_modified_fees, parent_ws.m_vsize);
1204 const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize);
1205 if (package_feerate <= parent_feerate) {
1207 "package RBF failed: package feerate is less than or equal to parent feerate",
1208 strprintf(
"package feerate %s <= parent feerate is %s", package_feerate.ToString(), parent_feerate.ToString()));
1215 "package RBF failed: " + err_tup.value().second,
"");
1218 LogDebug(
BCLog::TXPACKAGES,
"package RBF checks passed: parent %s (wtxid=%s), child %s (wtxid=%s), package hash (%s)\n",
1219 txns.front()->GetHash().ToString(), txns.front()->GetWitnessHash().ToString(),
1220 txns.back()->GetHash().ToString(), txns.back()->GetWitnessHash().ToString(),
1227bool MemPoolAccept::PolicyScriptChecks(
const ATMPArgs&
args, Workspace& ws)
1238 if (!
CheckInputScripts(tx, state, m_view, scriptVerifyFlags,
true,
false, ws.m_precomputed_txdata, GetValidationCache())) {
1255bool MemPoolAccept::ConsensusScriptChecks(
const ATMPArgs&
args, Workspace& ws)
1260 const uint256& hash = ws.m_hash;
1278 unsigned int currentBlockScriptVerifyFlags{
GetBlockScriptFlags(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman)};
1280 ws.m_precomputed_txdata, m_active_chainstate.CoinsTip(), GetValidationCache())) {
1281 LogPrintf(
"BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s\n", hash.
ToString(), state.
ToString());
1288void MemPoolAccept::FinalizeSubpackage(
const ATMPArgs&
args)
1293 if (!m_subpackage.m_changeset->GetRemovals().empty())
Assume(
args.m_allow_replacement);
1297 std::string log_string =
strprintf(
"replacing mempool tx %s (wtxid=%s, fees=%s, vsize=%s). ",
1298 it->GetTx().GetHash().ToString(),
1299 it->GetTx().GetWitnessHash().ToString(),
1302 FeeFrac feerate{m_subpackage.m_total_modified_fees, int32_t(m_subpackage.m_total_vsize)};
1304 const bool replaced_with_tx{m_subpackage.m_changeset->GetTxCount() == 1};
1305 if (replaced_with_tx) {
1306 const CTransaction& tx = m_subpackage.m_changeset->GetAddedTxn(0);
1307 tx_or_package_hash = tx.
GetHash();
1308 log_string +=
strprintf(
"New tx %s (wtxid=%s, fees=%s, vsize=%s)",
1314 tx_or_package_hash =
GetPackageHash(m_subpackage.m_changeset->GetAddedTxns());
1315 log_string +=
strprintf(
"New package %s with %lu txs, fees=%s, vsize=%s",
1316 tx_or_package_hash.ToString(),
1317 m_subpackage.m_changeset->GetTxCount(),
1324 it->GetTx().GetHash().data(),
1327 std::chrono::duration_cast<std::chrono::duration<std::uint64_t>>(it->GetTime()).count(),
1328 tx_or_package_hash.data(),
1333 m_subpackage.m_replaced_transactions.push_back(it->GetSharedTx());
1335 m_subpackage.m_changeset->Apply();
1336 m_subpackage.m_changeset.reset();
1339bool MemPoolAccept::SubmitPackage(
const ATMPArgs&
args, std::vector<Workspace>& workspaces,
1341 std::map<uint256, MempoolAcceptResult>& results)
1347 assert(std::all_of(workspaces.cbegin(), workspaces.cend(), [
this](
const auto& ws){
1348 return !m_pool.exists(GenTxid::Txid(ws.m_ptx->GetHash())); }));
1350 bool all_submitted =
true;
1351 FinalizeSubpackage(
args);
1356 for (Workspace& ws : workspaces) {
1357 if (!ConsensusScriptChecks(
args, ws)) {
1361 all_submitted =
false;
1363 strprintf(
"BUG! PolicyScriptChecks succeeded but ConsensusScriptChecks failed: %s",
1364 ws.m_ptx->GetHash().ToString()));
1366 if (!m_subpackage.m_changeset) m_subpackage.m_changeset = m_pool.GetChangeSet();
1367 m_subpackage.m_changeset->StageRemoval(m_pool.GetIter(ws.m_ptx->GetHash()).value());
1370 if (!all_submitted) {
1371 Assume(m_subpackage.m_changeset);
1375 m_subpackage.m_changeset->Apply();
1376 m_subpackage.m_changeset.reset();
1380 std::vector<Wtxid> all_package_wtxids;
1381 all_package_wtxids.reserve(workspaces.size());
1382 std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids),
1383 [](
const auto& ws) { return ws.m_ptx->GetWitnessHash(); });
1385 if (!m_subpackage.m_replaced_transactions.empty()) {
1386 LogDebug(
BCLog::MEMPOOL,
"replaced %u mempool transactions with %u new one(s) for %s additional fees, %d delta bytes\n",
1387 m_subpackage.m_replaced_transactions.size(), workspaces.size(),
1388 m_subpackage.m_total_modified_fees - m_subpackage.m_conflicting_fees,
1389 m_subpackage.m_total_vsize -
static_cast<int>(m_subpackage.m_conflicting_size));
1393 for (Workspace& ws : workspaces) {
1394 auto iter = m_pool.GetIter(ws.m_ptx->GetHash());
1395 Assume(iter.has_value());
1396 const auto effective_feerate =
args.m_package_feerates ? ws.m_package_feerate :
1397 CFeeRate{ws.m_modified_fees,
static_cast<uint32_t
>(ws.m_vsize)};
1398 const auto effective_feerate_wtxids =
args.m_package_feerates ? all_package_wtxids :
1399 std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()};
1400 results.emplace(ws.m_ptx->GetWitnessHash(),
1402 ws.m_base_fees, effective_feerate, effective_feerate_wtxids));
1403 if (!m_pool.m_opts.signals)
continue;
1406 ws.m_vsize, (*iter)->GetHeight(),
1407 args.m_bypass_limits,
args.m_package_submission,
1409 m_pool.HasNoInputsOf(tx));
1410 m_pool.m_opts.signals->TransactionAddedToMempool(tx_info, m_pool.GetAndIncrementSequence());
1412 return all_submitted;
1421 const std::vector<Wtxid> single_wtxid{ws.m_ptx->GetWitnessHash()};
1423 if (!PreChecks(
args, ws)) {
1431 m_subpackage.m_total_vsize = ws.m_vsize;
1432 m_subpackage.m_total_modified_fees = ws.m_modified_fees;
1435 if (
args.m_client_maxfeerate &&
CFeeRate(ws.m_modified_fees, ws.m_vsize) >
args.m_client_maxfeerate.value()) {
1440 if (m_pool.m_opts.require_standard) {
1442 if (!
CheckEphemeralSpends({ptx}, m_pool.m_opts.dust_relay_feerate, m_pool, ws.m_state, dummy_txid)) {
1447 if (m_subpackage.m_rbf && !ReplacementChecks(ws)) {
1461 const CFeeRate effective_feerate{ws.m_modified_fees,
static_cast<uint32_t
>(ws.m_vsize)};
1463 if (
args.m_test_accept) {
1465 ws.m_base_fees, effective_feerate, single_wtxid);
1468 FinalizeSubpackage(
args);
1471 if (!
args.m_package_submission && !
args.m_bypass_limits) {
1480 if (m_pool.m_opts.signals) {
1482 auto iter = m_pool.GetIter(tx.
GetHash());
1483 Assume(iter.has_value());
1485 ws.m_vsize, (*iter)->GetHeight(),
1486 args.m_bypass_limits,
args.m_package_submission,
1488 m_pool.HasNoInputsOf(tx));
1489 m_pool.m_opts.signals->TransactionAddedToMempool(tx_info, m_pool.GetAndIncrementSequence());
1492 if (!m_subpackage.m_replaced_transactions.empty()) {
1493 LogDebug(
BCLog::MEMPOOL,
"replaced %u mempool transactions with 1 new transaction for %s additional fees, %d delta bytes\n",
1494 m_subpackage.m_replaced_transactions.size(),
1495 ws.m_modified_fees - m_subpackage.m_conflicting_fees,
1496 ws.m_vsize -
static_cast<int>(m_subpackage.m_conflicting_size));
1500 effective_feerate, single_wtxid);
1511 std::vector<Workspace> workspaces{};
1512 workspaces.reserve(txns.size());
1513 std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces),
1514 [](
const auto& tx) { return Workspace(tx); });
1515 std::map<uint256, MempoolAcceptResult> results;
1520 for (Workspace& ws : workspaces) {
1521 if (!PreChecks(
args, ws)) {
1530 if (
args.m_client_maxfeerate &&
CFeeRate(ws.m_modified_fees, ws.m_vsize) >
args.m_client_maxfeerate.value()) {
1548 m_viewmempool.PackageAddTransaction(ws.m_ptx);
1553 for (Workspace& ws : workspaces) {
1569 m_subpackage.m_total_vsize = std::accumulate(workspaces.cbegin(), workspaces.cend(), int64_t{0},
1570 [](int64_t
sum,
auto& ws) { return sum + ws.m_vsize; });
1571 m_subpackage.m_total_modified_fees = std::accumulate(workspaces.cbegin(), workspaces.cend(),
CAmount{0},
1572 [](
CAmount sum,
auto& ws) { return sum + ws.m_modified_fees; });
1573 const CFeeRate package_feerate(m_subpackage.m_total_modified_fees, m_subpackage.m_total_vsize);
1574 std::vector<Wtxid> all_package_wtxids;
1575 all_package_wtxids.reserve(workspaces.size());
1576 std::transform(workspaces.cbegin(), workspaces.cend(), std::back_inserter(all_package_wtxids),
1577 [](
const auto& ws) { return ws.m_ptx->GetWitnessHash(); });
1579 if (
args.m_package_feerates &&
1580 !
CheckFeeRate(m_subpackage.m_total_vsize, m_subpackage.m_total_modified_fees, placeholder_state)) {
1588 if (txns.size() > 1 && !PackageMempoolChecks(txns, workspaces, m_subpackage.m_total_vsize, package_state)) {
1593 if (m_pool.m_opts.require_standard) {
1596 if (!
CheckEphemeralSpends(txns, m_pool.m_opts.dust_relay_feerate, m_pool, child_state, child_txid)) {
1603 for (Workspace& ws : workspaces) {
1604 ws.m_package_feerate = package_feerate;
1605 if (!PolicyScriptChecks(
args, ws)) {
1611 if (
args.m_test_accept) {
1612 const auto effective_feerate =
args.m_package_feerates ? ws.m_package_feerate :
1613 CFeeRate{ws.m_modified_fees,
static_cast<uint32_t
>(ws.m_vsize)};
1614 const auto effective_feerate_wtxids =
args.m_package_feerates ? all_package_wtxids :
1615 std::vector<Wtxid>{ws.m_ptx->GetWitnessHash()};
1616 results.emplace(ws.m_ptx->GetWitnessHash(),
1618 ws.m_vsize, ws.m_base_fees, effective_feerate,
1619 effective_feerate_wtxids));
1625 if (!SubmitPackage(
args, workspaces, package_state, results)) {
1633void MemPoolAccept::CleanupTemporaryCoins()
1653 for (
const auto& outpoint : m_viewmempool.GetNonBaseCoins()) {
1656 m_view.Uncache(outpoint);
1659 m_viewmempool.Reset();
1667 if (subpackage.size() > 1) {
1668 return AcceptMultipleTransactions(subpackage,
args);
1670 const auto& tx = subpackage.front();
1671 ATMPArgs single_args = ATMPArgs::SingleInPackageAccept(
args);
1672 const auto single_res = AcceptSingleTransaction(tx, single_args);
1683 ClearSubPackageState();
1690 Assert(!package.empty());
1706 if (package.size() > 1) {
1715 assert(package.size() > 1);
1718 const auto& child = package.back();
1719 std::unordered_set<uint256, SaltedTxidHasher> unconfirmed_parent_txids;
1720 std::transform(package.cbegin(), package.cend() - 1,
1721 std::inserter(unconfirmed_parent_txids, unconfirmed_parent_txids.end()),
1722 [](
const auto& tx) { return tx->GetHash(); });
1729 const CCoinsViewCache& coins_tip_cache = m_active_chainstate.CoinsTip();
1730 for (
const auto& input : child->vin) {
1732 args.m_coins_to_uncache.push_back(input.prevout);
1738 m_view.SetBackend(m_active_chainstate.CoinsTip());
1739 const auto package_or_confirmed = [
this, &unconfirmed_parent_txids](
const auto& input) {
1740 return unconfirmed_parent_txids.count(input.prevout.hash) > 0 || m_view.HaveCoin(input.prevout);
1742 if (!std::all_of(child->vin.cbegin(), child->vin.cend(), package_or_confirmed)) {
1748 m_view.SetBackend(m_dummy);
1754 std::map<uint256, MempoolAcceptResult> results_final;
1758 std::map<uint256, MempoolAcceptResult> individual_results_nonfinal;
1760 bool quit_early{
false};
1761 std::vector<CTransactionRef> txns_package_eval;
1762 for (
const auto& tx : package) {
1764 const auto& txid = tx->
GetHash();
1778 const auto& entry{*
Assert(m_pool.GetEntry(txid))};
1788 const auto& entry{*
Assert(m_pool.GetEntry(txid))};
1794 const auto single_package_res = AcceptSubPackage({tx},
args);
1795 const auto& single_res = single_package_res.m_tx_results.at(wtxid);
1800 results_final.emplace(wtxid, single_res);
1801 }
else if (package.size() == 1 ||
1815 individual_results_nonfinal.emplace(wtxid, single_res);
1817 individual_results_nonfinal.emplace(wtxid, single_res);
1818 txns_package_eval.push_back(tx);
1823 auto multi_submission_result = quit_early || txns_package_eval.empty() ?
PackageMempoolAcceptResult(package_state_quit_early, {}) :
1824 AcceptSubPackage(txns_package_eval,
args);
1830 ClearSubPackageState();
1836 for (
const auto& tx : package) {
1838 if (multi_submission_result.m_tx_results.count(wtxid) > 0) {
1840 Assume(results_final.count(wtxid) == 0);
1843 const auto& txresult = multi_submission_result.m_tx_results.at(wtxid);
1850 results_final.emplace(wtxid, txresult);
1852 }
else if (
const auto it{results_final.find(wtxid)}; it != results_final.end()) {
1856 Assume(individual_results_nonfinal.count(wtxid) == 0);
1863 results_final.erase(wtxid);
1866 }
else if (
const auto it{individual_results_nonfinal.find(wtxid)}; it != individual_results_nonfinal.end()) {
1869 results_final.emplace(wtxid, it->second);
1872 Assume(results_final.size() == package.size());
1879 int64_t accept_time,
bool bypass_limits,
bool test_accept)
1886 std::vector<COutPoint> coins_to_uncache;
1887 auto args = MemPoolAccept::ATMPArgs::SingleAccept(chainparams, accept_time, bypass_limits, coins_to_uncache, test_accept);
1895 for (
const COutPoint& hashTx : coins_to_uncache)
1898 tx->GetHash().data(),
1909 const Package& package,
bool test_accept,
const std::optional<CFeeRate>& client_maxfeerate)
1912 assert(!package.empty());
1913 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){return tx != nullptr;}));
1915 std::vector<COutPoint> coins_to_uncache;
1920 auto args = MemPoolAccept::ATMPArgs::PackageTestAccept(chainparams,
GetTime(), coins_to_uncache);
1921 return MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package,
args);
1923 auto args = MemPoolAccept::ATMPArgs::PackageChildWithParents(chainparams,
GetTime(), coins_to_uncache, client_maxfeerate);
1924 return MemPoolAccept(pool, active_chainstate).AcceptPackage(package,
args);
1929 if (test_accept || result.m_state.IsInvalid()) {
1930 for (
const COutPoint& hashTx : coins_to_uncache) {
1949 nSubsidy >>= halvings;
1954 : m_dbview{
std::move(db_params),
std::move(options)},
1955 m_catcherview(&m_dbview) {}
1957void CoinsViews::InitCache()
1960 m_cacheview = std::make_unique<CCoinsViewCache>(&m_catcherview);
1967 std::optional<uint256> from_snapshot_blockhash)
1968 : m_mempool(mempool),
1969 m_blockman(blockman),
1970 m_chainman(chainman),
1971 m_from_snapshot_blockhash(from_snapshot_blockhash) {}
1977 return m_cached_snapshot_base;
1981 size_t cache_size_bytes,
1993 .cache_bytes = cache_size_bytes,
1994 .memory_only = in_memory,
1995 .wipe_data = should_wipe,
2003void Chainstate::InitCoinsCache(
size_t cache_size_bytes)
2029 if (chain.Tip() ==
nullptr) {
2038 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
2055 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
2058 _(
"Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."));
2071 SetBlockFailureFlags(pindexNew);
2076 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%f date=%s\n", __func__,
2081 LogPrintf(
"%s: current best=%s height=%d log2_work=%f date=%s\n", __func__,
2120 if (
VerifyScript(scriptSig,
m_tx_out.
scriptPubKey, witness,
nFlags,
CachingTransactionSignatureChecker(
ptxTo,
nIn,
m_tx_out.
nValue,
cacheStore, *
m_signature_cache, *
txdata), &error)) {
2121 return std::nullopt;
2124 return std::make_pair(error, std::move(debug_str));
2129 : m_signature_cache{signature_cache_bytes}
2140 LogPrintf(
"Using %zu MiB out of %zu MiB requested for script execution cache, able to store %zu elements\n",
2141 approx_size_bytes >> 20, script_execution_cache_bytes >> 20, num_elems);
2167 std::vector<CScriptCheck>* pvChecks)
2172 pvChecks->reserve(tx.
vin.size());
2189 std::vector<CTxOut> spent_outputs;
2190 spent_outputs.reserve(tx.
vin.size());
2192 for (
const auto& txin : tx.
vin) {
2196 spent_outputs.emplace_back(coin.
out);
2198 txdata.
Init(tx, std::move(spent_outputs));
2202 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
2213 pvChecks->emplace_back(std::move(check));
2214 }
else if (
auto result = check(); result.has_value()) {
2226 auto mandatory_result = check2();
2227 if (!mandatory_result.has_value()) {
2236 result = mandatory_result;
2246 if (cacheFullScriptStore && !pvChecks) {
2274 if (undo.nHeight == 0) {
2280 undo.nHeight = alternate.
nHeight;
2305 LogError(
"DisconnectBlock(): failure reading undo data\n");
2309 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
2310 LogError(
"DisconnectBlock(): block and undo data inconsistent\n");
2320 bool fEnforceBIP30 = !((pindex->
nHeight==91722 && pindex->
GetBlockHash() ==
uint256{
"00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e"}) ||
2321 (pindex->
nHeight==91812 && pindex->
GetBlockHash() ==
uint256{
"00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f"}));
2324 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
2328 bool is_bip30_exception = (is_coinbase && !fEnforceBIP30);
2332 for (
size_t o = 0; o < tx.
vout.size(); o++) {
2333 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
2338 if (!is_bip30_exception) {
2349 LogError(
"DisconnectBlock(): transaction and undo data inconsistent\n");
2352 for (
unsigned int j = tx.
vin.size(); j > 0;) {
2450 const auto time_start{SteadyClock::now()};
2466 if (!
CheckBlock(block, state, params.GetConsensus(), !fJustCheck, !fJustCheck)) {
2478 uint256 hashPrevBlock = pindex->
pprev ==
nullptr ?
uint256() : pindex->pprev->GetBlockHash();
2485 if (block_hash == params.GetConsensus().hashGenesisBlock) {
2491 bool fScriptChecks =
true;
2500 if (it->second.GetAncestor(pindex->
nHeight) == pindex &&
2522 const auto time_1{SteadyClock::now()};
2523 m_chainman.time_check += time_1 - time_start;
2525 Ticks<MillisecondsDouble>(time_1 - time_start),
2567 static constexpr int BIP34_IMPLIES_BIP30_LIMIT = 1983702;
2599 fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->
GetBlockHash() == params.GetConsensus().BIP34Hash));
2604 if (fEnforceBIP30 || pindex->
nHeight >= BIP34_IMPLIES_BIP30_LIMIT) {
2605 for (
const auto& tx : block.
vtx) {
2606 for (
size_t o = 0; o < tx->
vout.size(); o++) {
2609 "tried to overwrite transaction");
2616 int nLockTimeFlags = 0;
2624 const auto time_2{SteadyClock::now()};
2627 Ticks<MillisecondsDouble>(time_2 - time_1),
2639 std::vector<PrecomputedTransactionData> txsdata(block.
vtx.size());
2641 std::vector<int> prevheights;
2644 int64_t nSigOpsCost = 0;
2645 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
2646 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2651 nInputs += tx.
vin.size();
2667 "accumulated fee in the block out of range");
2674 prevheights.resize(tx.
vin.size());
2675 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2679 if (!
SequenceLocks(tx, nLockTimeFlags, prevheights, *pindex)) {
2698 std::vector<CScriptCheck> vChecks;
2699 bool fCacheResults = fJustCheck;
2707 control.Add(std::move(vChecks));
2712 blockundo.
vtxundo.emplace_back();
2716 const auto time_3{SteadyClock::now()};
2718 LogDebug(
BCLog::BENCH,
" - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (
unsigned)block.
vtx.size(),
2719 Ticks<MillisecondsDouble>(time_3 - time_2), Ticks<MillisecondsDouble>(time_3 - time_2) / block.
vtx.size(),
2720 nInputs <= 1 ? 0 : Ticks<MillisecondsDouble>(time_3 - time_2) / (nInputs - 1),
2721 Ticks<SecondsDouble>(
m_chainman.time_connect),
2725 if (block.
vtx[0]->GetValueOut() > blockReward && state.
IsValid()) {
2727 strprintf(
"coinbase pays too much (actual=%d vs limit=%d)", block.
vtx[0]->GetValueOut(), blockReward));
2730 auto parallel_result = control.Complete();
2731 if (parallel_result.has_value() && state.
IsValid()) {
2738 const auto time_4{SteadyClock::now()};
2740 LogDebug(
BCLog::BENCH,
" - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1,
2741 Ticks<MillisecondsDouble>(time_4 - time_2),
2742 nInputs <= 1 ? 0 : Ticks<MillisecondsDouble>(time_4 - time_2) / (nInputs - 1),
2743 Ticks<SecondsDouble>(
m_chainman.time_verify),
2750 if (!
m_blockman.WriteBlockUndo(blockundo, state, *pindex)) {
2754 const auto time_5{SteadyClock::now()};
2757 Ticks<MillisecondsDouble>(time_5 - time_4),
2769 const auto time_6{SteadyClock::now()};
2772 Ticks<MillisecondsDouble>(time_6 - time_5),
2782 Ticks<std::chrono::nanoseconds>(time_5 - time_start)
2791 return this->GetCoinsCacheSizeState(
2797 size_t max_coins_cache_size_bytes,
2798 size_t max_mempool_size_bytes)
2803 int64_t nTotalSpace =
2804 max_coins_cache_size_bytes + std::max<int64_t>(int64_t(max_mempool_size_bytes) - nMempoolUsage, 0);
2807 static constexpr int64_t MAX_BLOCK_COINSDB_USAGE_BYTES = 10 * 1024 * 1024;
2808 int64_t large_threshold =
2809 std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE_BYTES);
2811 if (cacheSize > nTotalSpace) {
2812 LogPrintf(
"Cache size (%s) exceeds total space (%s)\n", cacheSize, nTotalSpace);
2814 }
else if (cacheSize > large_threshold) {
2823 int nManualPruneHeight)
2827 std::set<int> setFilesToPrune;
2828 bool full_flush_completed =
false;
2835 bool fFlushForPrune =
false;
2836 bool fDoFullFlush =
false;
2844 std::optional<std::string> limiting_lock;
2846 for (
const auto& prune_lock :
m_blockman.m_prune_locks) {
2847 if (prune_lock.second.height_first == std::numeric_limits<int>::max())
continue;
2850 last_prune = std::max(1, std::min(last_prune, lock_height));
2851 if (last_prune == lock_height) {
2852 limiting_lock = prune_lock.first;
2856 if (limiting_lock) {
2857 LogDebug(
BCLog::PRUNE,
"%s limited pruning to height %d\n", limiting_lock.value(), last_prune);
2860 if (nManualPruneHeight > 0) {
2865 std::min(last_prune, nManualPruneHeight),
2873 if (!setFilesToPrune.empty()) {
2874 fFlushForPrune =
true;
2876 m_blockman.m_block_tree_db->WriteFlag(
"prunedblockfiles",
true);
2881 const auto nNow{SteadyClock::now()};
2898 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2900 if (fDoFullFlush || fPeriodicWrite) {
2925 if (fFlushForPrune) {
2933 if (fDoFullFlush && !
CoinsTip().GetBestBlock().IsNull()) {
2934 if (coins_mem_usage >=
WARN_FLUSH_COINS_SIZE)
LogWarning(
"Flushing large (%d GiB) UTXO set to disk, it may take several minutes", coins_mem_usage >> 30);
2952 full_flush_completed =
true;
2954 int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - nNow)},
2956 (uint64_t)coins_count,
2957 (uint64_t)coins_mem_usage,
2958 (
bool)fFlushForPrune);
2965 }
catch (
const std::runtime_error& e) {
2992 const std::string& func_name,
2993 const std::string&
prefix,
2998 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",
3003 chainman.GuessVerificationProgress(tip),
3006 !warning_messages.empty() ?
strprintf(
" warning='%s'", warning_messages) :
"");
3009void Chainstate::UpdateTip(
const CBlockIndex* pindexNew)
3012 const auto& coins_tip = this->
CoinsTip();
3018 constexpr int BACKGROUND_LOG_INTERVAL = 2000;
3019 if (pindexNew->
nHeight % BACKGROUND_LOG_INTERVAL == 0) {
3030 std::vector<bilingual_str> warning_messages;
3041 warning_messages.push_back(warning);
3069 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3072 LogError(
"DisconnectTip(): Failed to read block\n");
3076 const auto time_start{SteadyClock::now()};
3080 if (DisconnectBlock(block, pindexDelete, view) !=
DISCONNECT_OK) {
3084 bool flushed = view.
Flush();
3088 Ticks<MillisecondsDouble>(SteadyClock::now() - time_start));
3092 const int max_height_first{pindexDelete->
nHeight - 1};
3093 for (
auto& prune_lock :
m_blockman.m_prune_locks) {
3094 if (prune_lock.second.height_first <= max_height_first)
continue;
3096 prune_lock.second.height_first = max_height_first;
3097 LogDebug(
BCLog::PRUNE,
"%s prune lock moved back to %d\n", prune_lock.first, max_height_first);
3116 UpdateTip(pindexDelete->
pprev);
3178 const auto time_1{SteadyClock::now()};
3179 std::shared_ptr<const CBlock> pthisBlock;
3181 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
3185 pthisBlock = pblockNew;
3188 pthisBlock = pblock;
3190 const CBlock& blockConnecting = *pthisBlock;
3192 const auto time_2{SteadyClock::now()};
3193 SteadyClock::time_point time_3;
3197 Ticks<MillisecondsDouble>(time_2 - time_1));
3200 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view);
3210 time_3 = SteadyClock::now();
3211 m_chainman.time_connect_total += time_3 - time_2;
3214 Ticks<MillisecondsDouble>(time_3 - time_2),
3215 Ticks<SecondsDouble>(
m_chainman.time_connect_total),
3217 bool flushed = view.
Flush();
3220 const auto time_4{SteadyClock::now()};
3223 Ticks<MillisecondsDouble>(time_4 - time_3),
3230 const auto time_5{SteadyClock::now()};
3231 m_chainman.time_chainstate += time_5 - time_4;
3233 Ticks<MillisecondsDouble>(time_5 - time_4),
3234 Ticks<SecondsDouble>(
m_chainman.time_chainstate),
3243 UpdateTip(pindexNew);
3245 const auto time_6{SteadyClock::now()};
3246 m_chainman.time_post_connect += time_6 - time_5;
3249 Ticks<MillisecondsDouble>(time_6 - time_5),
3250 Ticks<SecondsDouble>(
m_chainman.time_post_connect),
3253 Ticks<MillisecondsDouble>(time_6 - time_1),
3262 m_chainman.MaybeCompleteSnapshotValidation();
3290 bool fInvalidAncestor =
false;
3300 if (fFailedChain || fMissingData) {
3307 while (pindexTest != pindexFailed) {
3311 }
else if (fMissingData) {
3316 std::make_pair(pindexFailed->
pprev, pindexFailed));
3319 pindexFailed = pindexFailed->
pprev;
3322 fInvalidAncestor =
true;
3325 pindexTest = pindexTest->
pprev;
3327 if (!fInvalidAncestor)
3359 bool fBlocksDisconnected =
false;
3373 fBlocksDisconnected =
true;
3377 std::vector<CBlockIndex*> vpindexToConnect;
3378 bool fContinue =
true;
3383 int nTargetHeight = std::min(
nHeight + 32, pindexMostWork->
nHeight);
3384 vpindexToConnect.clear();
3385 vpindexToConnect.reserve(nTargetHeight -
nHeight);
3388 vpindexToConnect.push_back(pindexIter);
3389 pindexIter = pindexIter->
pprev;
3394 for (
CBlockIndex* pindexConnect : vpindexToConnect | std::views::reverse) {
3395 if (!
ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
3402 fInvalidFound =
true;
3423 if (fBlocksDisconnected) {
3444 bool fNotify =
false;
3445 bool fInitialBlockDownload =
false;
3449 pindexHeader = m_best_header;
3451 if (pindexHeader != m_last_notified_header) {
3454 m_last_notified_header = pindexHeader;
3467 if (signals.CallbacksPending() > 10) {
3468 signals.SyncWithValidationInterfaceQueue();
3472bool Chainstate::ActivateBestChain(
BlockValidationState& state, std::shared_ptr<const CBlock> pblock)
3491 LogPrintf(
"m_disabled is set - this chainstate should not be in operation. "
3492 "Please report this as a bug. %s\n", CLIENT_BUGREPORT);
3498 bool exited_ibd{
false};
3515 bool blocks_connected =
false;
3521 if (pindexMostWork ==
nullptr) {
3526 if (pindexMostWork ==
nullptr || pindexMostWork ==
m_chain.
Tip()) {
3530 bool fInvalidFound =
false;
3531 std::shared_ptr<const CBlock> nullBlockPtr;
3536 if (!
ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
3540 blocks_connected =
true;
3542 if (fInvalidFound) {
3544 pindexMostWork =
nullptr;
3549 assert(trace.pblock && trace.pindex);
3564 if (!blocks_connected)
return true;
3569 if (was_in_ibd && !still_in_ibd) {
3625 }
while (pindexNewTip != pindexMostWork);
3665 return ActivateBestChain(state, std::shared_ptr<const CBlock>());
3675 if (pindex->
nHeight == 0)
return false;
3678 bool pindex_was_in_chain =
false;
3679 int disconnected = 0;
3693 std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
3697 for (
auto& entry :
m_blockman.m_block_index) {
3708 candidate_blocks_by_work.insert(std::make_pair(candidate->
nChainWork, candidate));
3725 pindex_was_in_chain =
true;
3738 if (!
ret)
return false;
3758 auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->
pprev->
nChainWork);
3759 while (candidate_it != candidate_blocks_by_work.end()) {
3762 candidate_it = candidate_blocks_by_work.erase(candidate_it);
3770 to_mark_failed = invalid_walk_tip;
3795 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3805 if (pindex_was_in_chain) {
3824void Chainstate::SetBlockFailureFlags(
CBlockIndex* invalid_block)
3828 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3829 if (block_index.GetAncestor(invalid_block->
nHeight) == invalid_block && !(block_index.nStatus &
BLOCK_FAILED_MASK)) {
3841 for (
auto& [
_, block_index] :
m_blockman.m_block_index) {
3842 if (!block_index.IsValid() && block_index.GetAncestor(
nHeight) == pindex) {
3843 block_index.nStatus &= ~BLOCK_FAILED_MASK;
3848 if (&block_index ==
m_chainman.m_best_invalid) {
3857 while (pindex !=
nullptr) {
3859 pindex->nStatus &= ~BLOCK_FAILED_MASK;
3863 pindex = pindex->
pprev;
3877 if (is_active_chainstate) {
3881 }
else if (!m_disabled) {
3886 if (snapshot_base->GetAncestor(pindex->
nHeight) == pindex) {
3896 pindexNew->
nTx = block.
vtx.size();
3902 auto prev_tx_sum = [](
CBlockIndex& block) {
return block.nTx + (block.pprev ? block.pprev->m_chain_tx_count : 0); };
3904 pindexNew == GetSnapshotBaseBlock())) {
3905 LogWarning(
"Internal bug detected: block %d has unexpected m_chain_tx_count %i that should be %i (%s %s). Please report this issue here: %s\n",
3909 pindexNew->nFile = pos.
nFile;
3910 pindexNew->nDataPos = pos.
nPos;
3911 pindexNew->nUndoPos = 0;
3921 std::deque<CBlockIndex*> queue;
3922 queue.push_back(pindexNew);
3925 while (!queue.empty()) {
3933 LogWarning(
"Internal bug detected: block %d has unexpected m_chain_tx_count %i that should be %i (%s %s). Please report this issue here: %s\n",
3939 c->TryAddBlockIndexCandidate(pindex);
3941 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
m_blockman.
m_blocks_unlinked.equal_range(pindex);
3942 while (range.first != range.second) {
3943 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3944 queue.push_back(it->second);
3975 "hashMerkleRoot mismatch");
3984 "bad-txns-duplicate",
3985 "duplicate transaction");
4000 if (expect_witness_commitment) {
4005 assert(!block.
vtx.empty() && !block.
vtx[0]->vin.empty());
4006 const auto& witness_stack{block.
vtx[0]->vin[0].scriptWitness.stack};
4008 if (witness_stack.size() != 1 || witness_stack[0].size() != 32) {
4011 "bad-witness-nonce-size",
4012 strprintf(
"%s : invalid witness reserved value size", __func__));
4021 if (memcmp(hash_witness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
4024 "bad-witness-merkle-match",
4025 strprintf(
"%s : witness merkle commitment mismatch", __func__));
4034 for (
const auto& tx : block.
vtx) {
4038 "unexpected-witness",
4039 strprintf(
"%s : unexpected witness data found", __func__));
4079 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
4081 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
4082 if (block.
vtx[i]->IsCoinBase())
4087 for (
const auto& tx : block.
vtx) {
4097 unsigned int nSigOps = 0;
4098 for (
const auto& tx : block.
vtx)
4105 if (fCheckPOW && fCheckMerkleRoot)
4114 static const std::vector<unsigned char>
nonce(32, 0x00);
4117 tx.
vin[0].scriptWitness.stack.resize(1);
4118 tx.
vin[0].scriptWitness.stack[0] =
nonce;
4125 std::vector<unsigned char> commitment;
4127 std::vector<unsigned char>
ret(32, 0x00);
4135 out.scriptPubKey[1] = 0x24;
4136 out.scriptPubKey[2] = 0xaa;
4137 out.scriptPubKey[3] = 0x21;
4138 out.scriptPubKey[4] = 0xa9;
4139 out.scriptPubKey[5] = 0xed;
4140 memcpy(&
out.scriptPubKey[6], witnessroot.
begin(), 32);
4141 commitment = std::vector<unsigned char>(
out.scriptPubKey.begin(),
out.scriptPubKey.end());
4152 return std::all_of(headers.cbegin(), headers.cend(),
4153 [&](
const auto& header) { return CheckProofOfWork(header.GetHash(), header.nBits, consensusParams);});
4164 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase()) {
4171 return std::any_of(block.
vtx.begin(), block.
vtx.end(),
4172 [](
auto& tx) { return GetSerializeSize(TX_NO_WITNESS(tx)) == 64; });
4209 assert(pindexPrev !=
nullptr);
4210 const int nHeight = pindexPrev->nHeight + 1;
4218 if (chainman.m_options.checkpoints_enabled) {
4222 const CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(chainman.GetParams().Checkpoints());
4223 if (pcheckpoint && nHeight < pcheckpoint->
nHeight) {
4224 LogPrintf(
"ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__,
nHeight);
4230 if (block.
GetBlockTime() <= pindexPrev->GetMedianTimePast())
4269 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
4272 bool enforce_locktime_median_time_past{
false};
4274 assert(pindexPrev !=
nullptr);
4275 enforce_locktime_median_time_past =
true;
4278 const int64_t nLockTimeCutoff{enforce_locktime_median_time_past ?
4283 for (
const auto& tx : block.
vtx) {
4293 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
4294 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
4330 BlockMap::iterator miSelf{
m_blockman.m_block_index.find(hash)};
4332 if (miSelf !=
m_blockman.m_block_index.end()) {
4356 pindexPrev = &((*mi).second);
4391 if (pindexPrev->
GetAncestor(failedit->nHeight) == failedit) {
4394 while (invalid_walk != failedit) {
4397 invalid_walk = invalid_walk->
pprev;
4405 if (!min_pow_checked) {
4423 "Saw new header hash=%s height=%d", hash.
ToString(), pindex->
nHeight);
4457 blocks_left = std::max<int64_t>(0, blocks_left);
4458 const double progress{100.0 * last_accepted.nHeight / (last_accepted.nHeight + blocks_left)};
4459 LogInfo(
"Synchronizing blockheaders, height: %d (~%.2f%%)\n", last_accepted.nHeight, progress);
4476 auto now = std::chrono::steady_clock::now();
4477 if (now < m_last_presync_update + std::chrono::milliseconds{250})
return;
4478 m_last_presync_update = now;
4482 if (initial_download) {
4484 blocks_left = std::max<int64_t>(0, blocks_left);
4485 const double progress{100.0 * height / (height + blocks_left)};
4486 LogInfo(
"Pre-synchronizing blockheaders, height: %d (~%.2f%%)\n", height, progress);
4493 const CBlock& block = *pblock;
4495 if (fNewBlock) *fNewBlock =
false;
4499 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
4501 bool accepted_header{
AcceptBlockHeader(block, state, &pindex, min_pow_checked)};
4504 if (!accepted_header)
4528 if (fAlreadyHave)
return true;
4530 if (pindex->
nTx != 0)
return true;
4531 if (!fHasMoreOrSameWork)
return true;
4532 if (fTooFarAhead)
return true;
4543 if (!
CheckBlock(block, state, params.GetConsensus()) ||
4560 if (fNewBlock) *fNewBlock =
true;
4568 if (blockPos.IsNull()) {
4569 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
4574 }
catch (
const std::runtime_error& e) {
4598 if (new_block) *new_block =
false;
4613 ret =
AcceptBlock(block, state, &pindex, force_processing,
nullptr, new_block, min_pow_checked);
4628 LogError(
"%s: ActivateBestChain failed (%s)\n", __func__, state.
ToString());
4634 if (bg_chain && !bg_chain->ActivateBestChain(bg_state, block)) {
4635 LogError(
"%s: [background] ActivateBestChain failed (%s)\n", __func__, bg_state.
ToString());
4662 bool fCheckMerkleRoot)
4669 indexDummy.
pprev = pindexPrev;
4675 LogError(
"%s: Consensus::ContextualCheckBlockHeader: %s\n", __func__, state.
ToString());
4683 LogError(
"%s: Consensus::ContextualCheckBlock: %s\n", __func__, state.
ToString());
4686 if (!chainstate.
ConnectBlock(block, state, &indexDummy, viewNew,
true)) {
4724 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4754 int nCheckLevel,
int nCheckDepth)
4763 if (nCheckDepth <= 0 || nCheckDepth > chainstate.
m_chain.
Height()) {
4766 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4767 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4771 int nGoodTransactions = 0;
4774 bool skipped_no_block_data{
false};
4775 bool skipped_l3_checks{
false};
4776 LogPrintf(
"Verification progress: 0%%\n");
4781 const int percentageDone = std::max(1, std::min(99, (
int)(((
double)(chainstate.
m_chain.
Height() - pindex->
nHeight)) / (
double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
4782 if (reportDone < percentageDone / 10) {
4784 LogPrintf(
"Verification progress: %d%%\n", percentageDone);
4785 reportDone = percentageDone / 10;
4794 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);
4795 skipped_no_block_data =
true;