48 #include <boost/algorithm/string/replace.hpp> 49 #include <boost/thread.hpp> 52 # error "BSHA3 cannot be compiled without assertions." 55 #define MICRO 0.000001 62 struct CBlockIndexWorkComparator
75 if (pa < pb)
return false;
76 if (pa > pb)
return true;
263 std::vector<CBlockFileInfo> vinfoBlockFile;
264 int nLastBlockFile = 0;
269 bool fCheckForPruning =
false;
272 std::set<CBlockIndex*> setDirtyBlockIndex;
275 std::set<int> setDirtyFileInfo;
310 static void FindFilesToPruneManual(std::set<int>& setFilesToPrune,
int nManualPruneHeight);
311 static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
313 static FILE* OpenUndoFile(
const CDiskBlockPos &pos,
bool fReadOnly =
false);
340 const int64_t nBlockTime = (
flags & LOCKTIME_MEDIAN_TIME_PAST)
344 return IsFinalTx(tx, nBlockHeight, nBlockTime);
371 assert(tip !=
nullptr);
383 std::pair<int, int64_t> lockPair;
384 if (useExistingLockPoints) {
386 lockPair.first = lp->
height;
387 lockPair.second = lp->
time;
392 std::vector<int> prevheights;
393 prevheights.resize(tx.
vin.size());
394 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
395 const CTxIn& txin = tx.
vin[txinIndex];
397 if (!viewMemPool.GetCoin(txin.
prevout, coin)) {
398 return error(
"%s: Missing input", __func__);
400 if (coin.
nHeight == MEMPOOL_HEIGHT) {
402 prevheights[txinIndex] = tip->
nHeight + 1;
404 prevheights[txinIndex] = coin.
nHeight;
409 lp->
height = lockPair.first;
410 lp->
time = lockPair.second;
424 int maxInputHeight = 0;
425 for (
const int height : prevheights) {
427 if (height != tip->
nHeight+1) {
428 maxInputHeight = std::max(maxInputHeight, height);
440 static void LimitMempoolSize(
CTxMemPool& pool,
size_t limit,
unsigned long age) {
443 LogPrint(
BCLog::MEMPOOL,
"Expired %i transactions from the memory pool\n", expired);
446 std::vector<COutPoint> vNoSpendsRemaining;
448 for (
const COutPoint& removed : vNoSpendsRemaining)
489 std::vector<uint256> vHashUpdate;
500 if (!fAddToMempool || (*it)->IsCoinBase() ||
502 nullptr ,
true , 0 )) {
507 vHashUpdate.push_back((*it)->GetHash());
511 disconnectpool.queuedTx.clear();
522 LimitMempoolSize(
mempool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
536 assert(!tx.IsCoinBase());
537 for (
const CTxIn& txin : tx.vin) {
544 if (coin.
IsSpent())
return false;
549 assert(txFrom->vout.size() > txin.
prevout.
n);
553 assert(!coinFromDisk.
IsSpent());
554 assert(coinFromDisk.
out == coin.
out);
558 return CheckInputs(tx, state, view,
true,
flags, cacheSigStore,
true, txdata);
562 bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
569 if (pfMissingInputs) {
570 *pfMissingInputs =
false;
578 return state.DoS(100,
false, REJECT_INVALID,
"coinbase");
583 return state.DoS(0,
false, REJECT_NONSTANDARD, reason);
588 if (::
GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) < MIN_STANDARD_TX_NONWITNESS_SIZE)
589 return state.DoS(0,
false, REJECT_NONSTANDARD,
"tx-size-small");
595 return state.DoS(0,
false, REJECT_NONSTANDARD,
"non-final");
599 return state.Invalid(
false, REJECT_DUPLICATE,
"txn-already-in-mempool");
603 std::set<uint256> setConflicts;
607 if (ptxConflicting) {
608 if (!setConflicts.count(ptxConflicting->
GetHash()))
622 bool fReplacementOptOut =
true;
625 for (
const CTxIn &_txin : ptxConflicting->
vin)
627 if (_txin.
nSequence <= MAX_BIP125_RBF_SEQUENCE)
629 fReplacementOptOut =
false;
634 if (fReplacementOptOut) {
635 return state.Invalid(
false, REJECT_DUPLICATE,
"txn-mempool-conflict");
638 setConflicts.insert(ptxConflicting->
GetHash());
654 coins_to_uncache.push_back(txin.
prevout);
656 if (!view.HaveCoin(txin.
prevout)) {
658 for (
size_t out = 0; out < tx.
vout.size(); out++) {
661 return state.Invalid(
false, REJECT_DUPLICATE,
"txn-already-known");
665 if (pfMissingInputs) {
666 *pfMissingInputs =
true;
676 view.SetBackend(dummy);
684 return state.DoS(0,
false, REJECT_NONSTANDARD,
"non-BIP68-final");
693 return state.Invalid(
false, REJECT_NONSTANDARD,
"bad-txns-nonstandard-inputs");
697 return state.DoS(0,
false, REJECT_NONSTANDARD,
"bad-witness-nonstandard",
true);
707 bool fSpendsCoinbase =
false;
711 fSpendsCoinbase =
true;
717 fSpendsCoinbase, nSigOpsCost, lp);
725 if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
726 return state.DoS(0,
false, REJECT_NONSTANDARD,
"bad-txns-too-many-sigops",
false,
730 if (!bypass_limits && mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
731 return state.DoS(0,
false, REJECT_INSUFFICIENTFEE,
"mempool min fee not met",
false,
strprintf(
"%d < %d", nModifiedFees, mempoolRejectFee));
736 return state.DoS(0,
false, REJECT_INSUFFICIENTFEE,
"min relay fee not met",
false,
strprintf(
"%d < %d", nModifiedFees, ::
minRelayTxFee.
GetFee(nSize)));
739 if (nAbsurdFee && nFees > nAbsurdFee)
740 return state.Invalid(
false,
741 REJECT_HIGHFEE,
"absurdly-high-fee",
742 strprintf(
"%d > %d", nFees, nAbsurdFee));
746 size_t nLimitAncestors =
gArgs.
GetArg(
"-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
747 size_t nLimitAncestorSize =
gArgs.
GetArg(
"-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
748 size_t nLimitDescendants =
gArgs.
GetArg(
"-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
749 size_t nLimitDescendantSize =
gArgs.
GetArg(
"-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
750 std::string errString;
751 if (!pool.
CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
752 return state.DoS(0,
false, REJECT_NONSTANDARD,
"too-long-mempool-chain",
false, errString);
761 const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
762 if (setConflicts.count(hashAncestor))
764 return state.DoS(10,
false,
765 REJECT_INVALID,
"bad-txns-spends-conflicting-tx",
false,
766 strprintf(
"%s spends conflicting transaction %s",
775 size_t nConflictingSize = 0;
776 uint64_t nConflictingCount = 0;
782 const bool fReplacementTransaction = setConflicts.
size();
783 if (fReplacementTransaction)
785 CFeeRate newFeeRate(nModifiedFees, nSize);
786 std::set<uint256> setConflictsParents;
787 const int maxDescendantsToVisit = 100;
789 for (
const auto& mi : setIterConflicting) {
804 CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
805 if (newFeeRate <= oldFeeRate)
807 return state.DoS(0,
false,
808 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
809 strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
811 newFeeRate.ToString(),
812 oldFeeRate.ToString()));
815 for (
const CTxIn &txin : mi->GetTx().vin)
820 nConflictingCount += mi->GetCountWithDescendants();
825 if (nConflictingCount <= maxDescendantsToVisit) {
832 nConflictingFees += it->GetModifiedFee();
833 nConflictingSize += it->GetTxSize();
836 return state.DoS(0,
false,
837 REJECT_NONSTANDARD,
"too many potential replacements",
false,
838 strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
841 maxDescendantsToVisit));
844 for (
unsigned int j = 0; j < tx.
vin.size(); j++)
850 if (!setConflictsParents.count(tx.
vin[j].prevout.hash))
855 if (pool.
exists(tx.
vin[j].prevout.hash)) {
856 return state.DoS(0,
false,
857 REJECT_NONSTANDARD,
"replacement-adds-unconfirmed",
false,
858 strprintf(
"replacement %s adds unconfirmed input, idx %d",
867 if (nModifiedFees < nConflictingFees)
869 return state.DoS(0,
false,
870 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
871 strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
877 CAmount nDeltaFees = nModifiedFees - nConflictingFees;
880 return state.DoS(0,
false,
881 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
882 strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
889 constexpr
unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
894 if (!
CheckInputs(tx, state, view,
true, scriptVerifyFlags,
true,
false, txdata)) {
922 unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(
chainActive.
Tip(), chainparams.GetConsensus());
923 if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, currentBlockScriptVerifyFlags,
true, txdata)) {
924 return error(
"%s: BUG! PLEASE REPORT THIS! CheckInputs failed against latest-block but not STANDARD flags %s, %s",
936 LogPrint(
BCLog::MEMPOOL,
"replacing tx %s with %s for %s BSHA3 additional fees, %d delta bytes\n",
937 it->GetTx().GetHash().ToString(),
940 (int)nSize - (
int)nConflictingSize);
942 plTxnReplaced->push_back(it->GetSharedTx());
951 bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation() && pool.
HasNoInputsOf(tx);
954 pool.
addUnchecked(entry, setAncestors, validForFeeEstimation);
957 if (!bypass_limits) {
958 LimitMempoolSize(pool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
960 return state.DoS(0,
false, REJECT_INSUFFICIENTFEE,
"mempool full");
971 bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
974 std::vector<COutPoint> coins_to_uncache;
975 bool res = AcceptToMemoryPoolWorker(chainparams, pool, state, tx, pfMissingInputs, nAcceptTime, plTxnReplaced, bypass_limits, nAbsurdFee, coins_to_uncache, test_accept);
977 for (
const COutPoint& hashTx : coins_to_uncache)
987 bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced,
988 bool bypass_limits,
const CAmount nAbsurdFee,
bool test_accept)
991 return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, pfMissingInputs,
GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee, test_accept);
1012 return g_txindex->FindTx(hash, hashBlock, txOut);
1024 for (
const auto& tx : block.
vtx) {
1051 if (fileout.IsNull())
1052 return error(
"WriteBlockToDisk: OpenBlockFile failed");
1056 fileout << messageStart << nSize;
1059 long fileOutPos = ftell(fileout.Get());
1061 return error(
"WriteBlockToDisk: ftell failed");
1062 pos.
nPos = (
unsigned int)fileOutPos;
1075 return error(
"ReadBlockFromDisk: OpenBlockFile failed for %s", pos.
ToString());
1081 catch (
const std::exception& e) {
1082 return error(
"%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.
ToString());
1087 return error(
"ReadBlockFromDisk: Errors in block header at %s", pos.
ToString());
1103 return error(
"ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
1114 return error(
"%s: OpenBlockFile failed for %s", __func__, pos.
ToString());
1119 unsigned int blk_size;
1121 filein >> blk_start >> blk_size;
1124 return error(
"%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.
ToString(),
1129 if (blk_size > MAX_SIZE) {
1130 return error(
"%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.
ToString(),
1131 blk_size, MAX_SIZE);
1134 block.resize(blk_size);
1135 filein.
read((
char*)block.data(), blk_size);
1136 }
catch(
const std::exception& e) {
1137 return error(
"%s: Read from block file failed: %s for %s", __func__, e.what(), pos.
ToString());
1163 nSubsidy >>= halvings;
1170 static std::atomic<bool> latchToFalse{
false};
1172 if (latchToFalse.load(std::memory_order_relaxed))
1176 if (latchToFalse.load(std::memory_order_relaxed))
1186 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1187 latchToFalse.store(
true, std::memory_order_relaxed);
1193 static void AlertNotify(
const std::string& strMessage)
1196 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1197 if (strCmd.empty())
return;
1202 std::string singleQuote(
"'");
1204 safeStatus = singleQuote+safeStatus+singleQuote;
1205 boost::replace_all(strCmd,
"%s", safeStatus);
1228 std::string warning = std::string(
"'Warning: Large-work fork detected, forking after block ") +
1230 AlertNotify(warning);
1234 LogPrintf(
"%s: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", __func__,
1241 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1258 while (pfork && pfork != plonger)
1261 plonger = plonger->
pprev;
1262 if (pfork == plonger)
1264 pfork = pfork->
pprev;
1282 CheckForkWarningConditions();
1290 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
1291 pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
1295 LogPrintf(
"%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
1298 CheckForkWarningConditions();
1305 setDirtyBlockIndex.insert(pindex);
1307 InvalidChainFound(pindex);
1333 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1342 return pindexPrev->
nHeight + 1;
1352 size_t nMaxCacheSize = std::min(std::max((int64_t)0,
gArgs.
GetArg(
"-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
1353 size_t nElems = scriptExecutionCache.setup_bytes(nMaxCacheSize);
1354 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1355 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1377 pvChecks->reserve(tx.
vin.size());
1388 if (fScriptChecks) {
1397 static_assert(55 -
sizeof(
flags) - 32 >= 128/8,
"Want at least 128 bits of nonce for script execution cache");
1400 if (scriptExecutionCache.contains(hashCacheEntry, !cacheFullScriptStore)) {
1404 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1406 const Coin& coin = inputs.AccessCoin(prevout);
1419 check.swap(pvChecks->back());
1420 }
else if (!check()) {
1421 if (
flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
1429 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
1431 return state.Invalid(
false, REJECT_NONSTANDARD,
strprintf(
"non-mandatory-script-verify-flag (%s)",
ScriptErrorString(check.GetScriptError())));
1440 return state.DoS(100,
false, REJECT_INVALID,
strprintf(
"mandatory-script-verify-flag-failed (%s)",
ScriptErrorString(check.GetScriptError())));
1444 if (cacheFullScriptStore && !pvChecks) {
1447 scriptExecutionCache.insert(hashCacheEntry);
1461 if (fileout.IsNull())
1462 return error(
"%s: OpenUndoFile failed", __func__);
1466 fileout << messageStart << nSize;
1469 long fileOutPos = ftell(fileout.Get());
1471 return error(
"%s: ftell failed", __func__);
1472 pos.
nPos = (
unsigned int)fileOutPos;
1473 fileout << blockundo;
1477 hasher << hashBlock;
1478 hasher << blockundo;
1479 fileout << hasher.GetHash();
1488 return error(
"%s: no undo data available", __func__);
1493 if (filein.IsNull())
1494 return error(
"%s: OpenUndoFile failed", __func__);
1501 verifier >> blockundo;
1502 filein >> hashChecksum;
1504 catch (
const std::exception& e) {
1505 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1509 if (hashChecksum != verifier.GetHash())
1510 return error(
"%s: Checksum mismatch", __func__);
1516 static bool AbortNode(
const std::string& strMessage,
const std::string& userMessage=
"")
1519 LogPrintf(
"*** %s\n", strMessage);
1521 userMessage.empty() ?
_(
"Error: A fatal internal error occurred, see debug.log for details") : userMessage,
1527 static bool AbortNode(
CValidationState& state,
const std::string& strMessage,
const std::string& userMessage=
"")
1529 AbortNode(strMessage, userMessage);
1530 return state.
Error(strMessage);
1546 if (view.
HaveCoin(out)) fClean =
false;
1548 if (undo.nHeight == 0) {
1554 undo.nHeight = alternate.
nHeight;
1564 view.
AddCoin(out, std::move(undo), !fClean);
1576 if (!UndoReadFromDisk(blockUndo, pindex)) {
1577 error(
"DisconnectBlock(): failure reading undo data");
1581 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1582 error(
"DisconnectBlock(): block and undo data inconsistent");
1587 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1594 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1595 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1598 bool is_spent = view.
SpendCoin(out, &coin);
1609 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1612 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1628 void static FlushBlockFile(
bool fFinalize =
false)
1630 LOCK(cs_LastBlockFile);
1638 status &=
TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
1643 fileOld = OpenUndoFile(posOld);
1646 status &=
TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
1652 AbortNode(
"Flushing block file to disk failed. This is likely the result of an I/O error.");
1664 return error(
"ConnectBlock(): FindUndoPos failed");
1666 return AbortNode(state,
"Failed to write undo data");
1671 setDirtyBlockIndex.insert(pindex);
1681 scriptcheckqueue.Thread();
1690 int32_t nVersion = VERSIONBITS_TOP_BITS;
1695 nVersion |=
VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
1720 return ((pindex->
nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
1721 ((pindex->
nVersion >> bit) & 1) != 0 &&
1755 if (consensusparams.nBIP66Enabled) {
1760 if (consensusparams.nBIP65Enabled) {
1765 if (consensusparams.nCSVEnabled) {
1778 static int64_t nTimeCheck = 0;
1779 static int64_t nTimeForks = 0;
1780 static int64_t nTimeVerify = 0;
1781 static int64_t nTimeConnect = 0;
1782 static int64_t nTimeIndex = 0;
1783 static int64_t nTimeCallbacks = 0;
1784 static int64_t nTimeTotal = 0;
1785 static int64_t nBlocksTotal = 0;
1816 return AbortNode(state,
"Corrupt block found indicating potential hardware failure; shutting down");
1835 bool fScriptChecks =
true;
1844 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
1861 int64_t nTime1 =
GetTimeMicros(); nTimeCheck += nTime1 - nTimeStart;
1862 LogPrint(
BCLog::BENCH,
" - Sanity checks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime1 - nTimeStart), nTimeCheck *
MICRO, nTimeCheck *
MILLI / nBlocksTotal);
1879 int nLockTimeFlags = 0;
1881 nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
1887 int64_t nTime2 =
GetTimeMicros(); nTimeForks += nTime2 - nTime1;
1888 LogPrint(
BCLog::BENCH,
" - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime2 - nTime1), nTimeForks *
MICRO, nTimeForks *
MILLI / nBlocksTotal);
1894 std::vector<int> prevheights;
1897 int64_t nSigOpsCost = 0;
1898 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
1899 std::vector<PrecomputedTransactionData> txdata;
1900 txdata.reserve(block.
vtx.size());
1901 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
1905 nInputs += tx.
vin.size();
1915 return state.
DoS(100,
error(
"%s: accumulated fee in the block out of range.", __func__),
1916 REJECT_INVALID,
"bad-txns-accumulated-fee-outofrange");
1922 prevheights.resize(tx.
vin.size());
1923 for (
size_t j = 0; j < tx.
vin.size(); j++) {
1927 if (!
SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
1928 return state.
DoS(100,
error(
"%s: contains a non-BIP68-final transaction", __func__),
1929 REJECT_INVALID,
"bad-txns-nonfinal");
1938 if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST)
1939 return state.
DoS(100,
error(
"ConnectBlock(): too many sigops"),
1940 REJECT_INVALID,
"bad-blk-sigops");
1942 txdata.emplace_back(tx);
1945 std::vector<CScriptCheck> vChecks;
1946 bool fCacheResults = fJustCheck;
1948 return error(
"ConnectBlock(): CheckInputs on %s failed with %s",
1950 control.
Add(vChecks);
1959 int64_t nTime3 =
GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
1960 LogPrint(
BCLog::BENCH,
" - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (
unsigned)block.
vtx.size(),
MILLI * (nTime3 - nTime2),
MILLI * (nTime3 - nTime2) / block.
vtx.size(), nInputs <= 1 ? 0 :
MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect *
MICRO, nTimeConnect *
MILLI / nBlocksTotal);
1963 if (block.
vtx[0]->GetValueOut() > blockReward)
1964 return state.
DoS(100,
1965 error(
"ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
1966 block.
vtx[0]->GetValueOut(), blockReward),
1967 REJECT_INVALID,
"bad-cb-amount");
1969 if (!control.
Wait())
1970 return state.
DoS(100,
error(
"%s: CheckQueue failed", __func__), REJECT_INVALID,
"block-validation-failed");
1971 int64_t nTime4 =
GetTimeMicros(); nTimeVerify += nTime4 - nTime2;
1972 LogPrint(
BCLog::BENCH,
" - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1,
MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 :
MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify *
MICRO, nTimeVerify *
MILLI / nBlocksTotal);
1977 if (!WriteUndoDataForBlock(blockundo, state, pindex, chainparams))
1982 setDirtyBlockIndex.insert(pindex);
1989 int64_t nTime5 =
GetTimeMicros(); nTimeIndex += nTime5 - nTime4;
1990 LogPrint(
BCLog::BENCH,
" - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime5 - nTime4), nTimeIndex *
MICRO, nTimeIndex *
MILLI / nBlocksTotal);
1992 int64_t nTime6 =
GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
1993 LogPrint(
BCLog::BENCH,
" - Callbacks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime6 - nTime5), nTimeCallbacks *
MICRO, nTimeCallbacks *
MILLI / nBlocksTotal);
2010 static int64_t nLastWrite = 0;
2011 static int64_t nLastFlush = 0;
2012 std::set<int> setFilesToPrune;
2013 bool full_flush_completed =
false;
2016 bool fFlushForPrune =
false;
2017 bool fDoFullFlush =
false;
2018 LOCK(cs_LastBlockFile);
2020 if (nManualPruneHeight > 0) {
2021 FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight);
2024 fCheckForPruning =
false;
2026 if (!setFilesToPrune.empty()) {
2027 fFlushForPrune =
true;
2029 pblocktree->WriteFlag(
"prunedblockfiles",
true);
2036 if (nLastWrite == 0) {
2039 if (nLastFlush == 0) {
2042 int64_t nMempoolSizeMax =
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
2043 int64_t cacheSize =
pcoinsTip->DynamicMemoryUsage();
2044 int64_t nTotalSpace =
nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
2046 bool fCacheLarge = mode ==
FlushStateMode::PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
2050 bool fPeriodicWrite = mode ==
FlushStateMode::PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
2052 bool fPeriodicFlush = mode ==
FlushStateMode::PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
2054 fDoFullFlush = (mode ==
FlushStateMode::ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2056 if (fDoFullFlush || fPeriodicWrite) {
2059 return state.
Error(
"out of disk space");
2064 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2065 vFiles.reserve(setDirtyFileInfo.size());
2066 for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
2067 vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it]));
2068 setDirtyFileInfo.erase(it++);
2070 std::vector<const CBlockIndex*> vBlocks;
2071 vBlocks.reserve(setDirtyBlockIndex.size());
2072 for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
2073 vBlocks.push_back(*it);
2074 setDirtyBlockIndex.erase(it++);
2076 if (!
pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
2077 return AbortNode(state,
"Failed to write to block index database");
2086 if (fDoFullFlush && !
pcoinsTip->GetBestBlock().IsNull()) {
2093 return state.
Error(
"out of disk space");
2096 return AbortNode(state,
"Failed to write to coin database");
2098 full_flush_completed =
true;
2101 if (full_flush_completed) {
2105 }
catch (
const std::runtime_error& e) {
2106 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2121 fCheckForPruning =
true;
2128 static void DoWarning(
const std::string& strWarning)
2130 static bool fWarned =
false;
2133 AlertNotify(strWarning);
2139 static void AppendWarning(std::string& res,
const std::string& warn)
2141 if (!res.empty()) res +=
", ";
2156 std::string warningMessages;
2161 for (
int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
2165 const std::string strWarning =
strprintf(
_(
"Warning: unknown new rules activated (versionbit %i)"), bit);
2167 DoWarning(strWarning);
2169 AppendWarning(warningMessages, strWarning);
2174 for (
int i = 0; i < 100 && pindex !=
nullptr; i++)
2177 if (pindex->
nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->
nVersion & ~nExpectedVersion) != 0)
2179 pindex = pindex->
pprev;
2182 AppendWarning(warningMessages,
strprintf(
_(
"%d of last 100 blocks have unexpected version"), nUpgraded));
2183 if (nUpgraded > 100/2)
2185 std::string strWarning =
_(
"Warning: Unknown block versions being mined! It's possible unknown rules are in effect");
2187 DoWarning(strWarning);
2190 LogPrintf(
"%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)", __func__,
2195 if (!warningMessages.empty())
2196 LogPrintf(
" warning='%s'", warningMessages);
2214 assert(pindexDelete);
2216 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2219 return AbortNode(state,
"Failed to read block");
2224 assert(view.GetBestBlock() == pindexDelete->
GetBlockHash());
2227 bool flushed = view.Flush();
2235 if (disconnectpool) {
2237 for (
auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
2240 while (disconnectpool->
DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) {
2250 UpdateTip(pindexDelete->
pprev, chainparams);
2257 static int64_t nTimeReadFromDisk = 0;
2258 static int64_t nTimeConnectTotal = 0;
2259 static int64_t nTimeFlush = 0;
2260 static int64_t nTimeChainState = 0;
2261 static int64_t nTimePostConnect = 0;
2300 assert(!blocksConnected.back().pindex);
2303 blocksConnected.back().pindex = pindex;
2304 blocksConnected.back().pblock = std::move(pblock);
2305 blocksConnected.emplace_back();
2314 assert(!blocksConnected.back().pindex);
2315 assert(blocksConnected.back().conflictedTxs->empty());
2316 blocksConnected.pop_back();
2317 return blocksConnected;
2321 assert(!blocksConnected.back().pindex);
2323 blocksConnected.back().conflictedTxs->emplace_back(std::move(txRemoved));
2339 std::shared_ptr<const CBlock> pthisBlock;
2341 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2343 return AbortNode(state,
"Failed to read block");
2344 pthisBlock = pblockNew;
2346 pthisBlock = pblock;
2348 const CBlock& blockConnecting = *pthisBlock;
2350 int64_t nTime2 =
GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
2352 LogPrint(
BCLog::BENCH,
" - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) *
MILLI, nTimeReadFromDisk *
MICRO);
2355 bool rv =
ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
2362 nTime3 =
GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
2363 LogPrint(
BCLog::BENCH,
" - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) *
MILLI, nTimeConnectTotal *
MICRO, nTimeConnectTotal *
MILLI / nBlocksTotal);
2364 bool flushed = view.Flush();
2367 int64_t nTime4 =
GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
2368 LogPrint(
BCLog::BENCH,
" - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) *
MILLI, nTimeFlush *
MICRO, nTimeFlush *
MILLI / nBlocksTotal);
2372 int64_t nTime5 =
GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
2373 LogPrint(
BCLog::BENCH,
" - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) *
MILLI, nTimeChainState *
MICRO, nTimeChainState *
MILLI / nBlocksTotal);
2379 UpdateTip(pindexNew, chainparams);
2381 int64_t nTime6 =
GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
2382 LogPrint(
BCLog::BENCH,
" - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) *
MILLI, nTimePostConnect *
MICRO, nTimePostConnect *
MILLI / nBlocksTotal);
2383 LogPrint(
BCLog::BENCH,
"- Connect block: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime1) *
MILLI, nTimeTotal *
MICRO, nTimeTotal *
MILLI / nBlocksTotal);
2408 bool fInvalidAncestor =
false;
2418 if (fFailedChain || fMissingData) {
2424 while (pindexTest != pindexFailed) {
2427 }
else if (fMissingData) {
2434 pindexFailed = pindexFailed->
pprev;
2437 fInvalidAncestor =
true;
2440 pindexTest = pindexTest->
pprev;
2442 if (!fInvalidAncestor)
2471 bool fBlocksDisconnected =
false;
2477 UpdateMempoolForReorg(disconnectpool,
false);
2480 fBlocksDisconnected =
true;
2484 std::vector<CBlockIndex*> vpindexToConnect;
2485 bool fContinue =
true;
2486 int nHeight = pindexFork ? pindexFork->
nHeight : -1;
2487 while (fContinue && nHeight != pindexMostWork->
nHeight) {
2490 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->
nHeight);
2491 vpindexToConnect.clear();
2492 vpindexToConnect.reserve(nTargetHeight - nHeight);
2494 while (pindexIter && pindexIter->
nHeight != nHeight) {
2495 vpindexToConnect.push_back(pindexIter);
2496 pindexIter = pindexIter->
pprev;
2498 nHeight = nTargetHeight;
2502 if (!
ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
2506 InvalidChainFound(vpindexToConnect.front());
2509 fInvalidFound =
true;
2516 UpdateMempoolForReorg(disconnectpool,
false);
2530 if (fBlocksDisconnected) {
2533 UpdateMempoolForReorg(disconnectpool,
true);
2539 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
2541 CheckForkWarningConditions();
2547 bool fNotify =
false;
2548 bool fInitialBlockDownload =
false;
2555 if (pindexHeader != pindexHeaderOld) {
2558 pindexHeaderOld = pindexHeader;
2563 uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader);
2591 int nStopAtHeight =
gArgs.
GetArg(
"-stopatheight", DEFAULT_STOPATHEIGHT);
2593 boost::this_thread::interruption_point();
2608 bool blocks_connected =
false;
2614 if (pindexMostWork ==
nullptr) {
2619 if (pindexMostWork ==
nullptr || pindexMostWork ==
chainActive.
Tip()) {
2623 bool fInvalidFound =
false;
2624 std::shared_ptr<const CBlock> nullBlockPtr;
2625 if (!
ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
2627 blocks_connected =
true;
2629 if (fInvalidFound) {
2631 pindexMostWork =
nullptr;
2636 assert(trace.pblock && trace.pindex);
2640 if (!blocks_connected)
return true;
2647 if (pindexFork != pindexNewTip) {
2652 uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
2665 }
while (pindexNewTip != pindexMostWork);
2722 bool pindex_was_in_chain =
false;
2727 pindex_was_in_chain =
true;
2733 UpdateMempoolForReorg(disconnectpool,
false);
2740 while (pindex_was_in_chain && invalid_walk_tip != pindex) {
2742 setDirtyBlockIndex.insert(invalid_walk_tip);
2744 invalid_walk_tip = invalid_walk_tip->
pprev;
2749 setDirtyBlockIndex.insert(pindex);
2755 UpdateMempoolForReorg(disconnectpool,
true);
2767 InvalidChainFound(pindex);
2770 if (pindex_was_in_chain) {
2783 int nHeight = pindex->
nHeight;
2788 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
2790 setDirtyBlockIndex.insert(it->second);
2804 while (pindex !=
nullptr) {
2807 setDirtyBlockIndex.insert(pindex);
2810 pindex = pindex->
pprev;
2834 BlockMap::iterator mi =
mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
2839 pindexNew->
pprev = (*miPrev).second;
2849 setDirtyBlockIndex.insert(pindexNew);
2857 pindexNew->
nTx = block.
vtx.size();
2867 setDirtyBlockIndex.insert(pindexNew);
2871 std::deque<CBlockIndex*> queue;
2872 queue.push_back(pindexNew);
2875 while (!queue.empty()) {
2886 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range =
mapBlocksUnlinked.equal_range(pindex);
2887 while (range.first != range.second) {
2888 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
2889 queue.push_back(it->second);
2901 static bool FindBlockPos(
CDiskBlockPos &pos,
unsigned int nAddSize,
unsigned int nHeight, uint64_t nTime,
bool fKnown =
false)
2903 LOCK(cs_LastBlockFile);
2905 unsigned int nFile = fKnown ? pos.
nFile : nLastBlockFile;
2906 if (vinfoBlockFile.size() <= nFile) {
2907 vinfoBlockFile.resize(nFile + 1);
2911 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
2913 if (vinfoBlockFile.size() <= nFile) {
2914 vinfoBlockFile.resize(nFile + 1);
2918 pos.
nPos = vinfoBlockFile[nFile].nSize;
2921 if ((
int)nFile != nLastBlockFile) {
2923 LogPrintf(
"Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
2925 FlushBlockFile(!fKnown);
2926 nLastBlockFile = nFile;
2929 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
2931 vinfoBlockFile[nFile].nSize = std::max(pos.
nPos + nAddSize, vinfoBlockFile[nFile].nSize);
2933 vinfoBlockFile[nFile].nSize += nAddSize;
2936 unsigned int nOldChunks = (pos.
nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2937 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2938 if (nNewChunks > nOldChunks) {
2940 fCheckForPruning =
true;
2944 LogPrintf(
"Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.
nFile);
2950 return error(
"out of disk space");
2954 setDirtyFileInfo.insert(nFile);
2962 LOCK(cs_LastBlockFile);
2964 unsigned int nNewSize;
2965 pos.
nPos = vinfoBlockFile[nFile].nUndoSize;
2966 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
2967 setDirtyFileInfo.insert(nFile);
2969 unsigned int nOldChunks = (pos.
nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
2970 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
2971 if (nNewChunks > nOldChunks) {
2973 fCheckForPruning =
true;
2975 FILE *file = OpenUndoFile(pos);
2977 LogPrintf(
"Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.
nFile);
2983 return state.
Error(
"out of disk space");
2993 return state.
DoS(50,
false, REJECT_INVALID,
"high-hash",
false,
"proof of work failed");
3007 if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW))
3011 if (fCheckMerkleRoot) {
3015 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txnmrklroot",
true,
"hashMerkleRoot mismatch");
3021 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-duplicate",
true,
"duplicate transaction");
3031 if (block.
vtx.empty() || block.
vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT ||
::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
3032 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-length",
false,
"size limits failed");
3035 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3036 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-missing",
false,
"first tx is not coinbase");
3037 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3038 if (block.
vtx[i]->IsCoinBase())
3039 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-multiple",
false,
"more than one coinbase");
3042 for (
const auto& tx : block.
vtx)
3047 unsigned int nSigOps = 0;
3048 for (
const auto& tx : block.
vtx)
3052 if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST)
3053 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-sigops",
false,
"out-of-bounds SigOpCount");
3055 if (fCheckPOW && fCheckMerkleRoot)
3079 static int GetWitnessCommitmentIndex(
const CBlock& block)
3082 if (!block.
vtx.empty()) {
3083 for (
size_t o = 0; o < block.
vtx[0]->vout.size(); o++) {
3084 if (block.
vtx[0]->vout[o].scriptPubKey.size() >= 38 && block.
vtx[0]->vout[o].scriptPubKey[0] ==
OP_RETURN && block.
vtx[0]->vout[o].scriptPubKey[1] == 0x24 && block.
vtx[0]->vout[o].scriptPubKey[2] == 0x0f && block.
vtx[0]->vout[o].scriptPubKey[3] == 0x0f && block.
vtx[0]->vout[o].scriptPubKey[4] == 0x0f && block.
vtx[0]->vout[o].scriptPubKey[5] == 0x0f) {
3094 int commitpos = GetWitnessCommitmentIndex(block);
3095 static const std::vector<unsigned char> nonce(32, 0x00);
3096 if (commitpos != -1 &&
IsWitnessEnabled(pindexPrev, consensusParams) && !block.
vtx[0]->HasWitness()) {
3098 tx.
vin[0].scriptWitness.stack.resize(1);
3099 tx.
vin[0].scriptWitness.stack[0] = nonce;
3100 block.
vtx[0] = MakeTransactionRef(std::move(tx));
3106 std::vector<unsigned char> commitment;
3107 int commitpos = GetWitnessCommitmentIndex(block);
3108 std::vector<unsigned char>
ret(32, 0x00);
3110 if (commitpos == -1) {
3125 tx.vout.push_back(out);
3126 block.
vtx[0] = MakeTransactionRef(std::move(tx));
3144 assert(pindexPrev !=
nullptr);
3145 const int nHeight = pindexPrev->
nHeight + 1;
3150 return state.
DoS(100,
false, REJECT_INVALID,
"bad-diffbits",
false,
"incorrect proof of work");
3158 if (pcheckpoint && nHeight < pcheckpoint->nHeight)
3159 return state.
DoS(100,
error(
"%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT,
"bad-fork-prior-to-checkpoint");
3164 return state.
Invalid(
false, REJECT_INVALID,
"time-too-old",
"block's timestamp is too early");
3167 if (block.
GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
3168 return state.
Invalid(
false, REJECT_INVALID,
"time-too-new",
"block timestamp too far in the future");
3191 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3194 int nLockTimeFlags = 0;
3196 nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
3199 int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST)
3204 for (
const auto& tx : block.
vtx) {
3205 if (!
IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
3206 return state.
DoS(10,
false, REJECT_INVALID,
"bad-txns-nonfinal",
false,
"non-final transaction");
3214 if (block.
vtx[0]->vin[0].scriptSig.size() <
expect.size() ||
3215 !std::equal(
expect.begin(),
expect.end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3216 std::cout << block.
vtx[0]->vin[0].ToString();
3217 std::cout << std::endl;
3220 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-height",
false,
"block height mismatch in coinbase");
3232 bool fHaveWitness =
false;
3234 int commitpos = GetWitnessCommitmentIndex(block);
3235 if (commitpos != -1) {
3236 bool malleated =
false;
3241 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3242 return state.
DoS(100,
false, REJECT_INVALID,
"bad-witness-nonce-size",
true,
strprintf(
"%s : invalid witness reserved value size", __func__));
3245 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3246 return state.
DoS(100,
false, REJECT_INVALID,
"bad-witness-merkle-match",
true,
strprintf(
"%s : witness merkle commitment mismatch", __func__));
3248 fHaveWitness =
true;
3253 if (!fHaveWitness) {
3254 for (
const auto& tx : block.
vtx) {
3256 return state.
DoS(100,
false, REJECT_INVALID,
"unexpected-witness",
true,
strprintf(
"%s : unexpected witness data found", __func__));
3267 if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) {
3268 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-weight",
false,
strprintf(
"%s : weight limit failed", __func__));
3284 pindex = miSelf->second;
3288 return state.
Invalid(
error(
"%s: block %s is marked invalid", __func__, hash.
ToString()), 0,
"duplicate");
3292 if (!CheckBlockHeader(block, state, chainparams.
GetConsensus()))
3299 return state.
DoS(10,
error(
"%s: prev block not found", __func__), 0,
"prev-blk-not-found");
3300 pindexPrev = (*mi).second;
3302 return state.
DoS(100,
error(
"%s: prev block invalid", __func__), REJECT_INVALID,
"bad-prevblk");
3303 if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev,
GetAdjustedTime()))
3311 if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) {
3314 while (invalid_walk != failedit) {
3316 setDirtyBlockIndex.insert(invalid_walk);
3317 invalid_walk = invalid_walk->
pprev;
3319 return state.
DoS(100,
error(
"%s: prev block invalid", __func__), REJECT_INVALID,
"bad-prevblk");
3324 if (pindex ==
nullptr)
3338 if (first_invalid !=
nullptr) first_invalid->
SetNull();
3344 if (first_invalid) *first_invalid = header;
3362 if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, block.
GetBlockTime(), dbp !=
nullptr)) {
3363 error(
"%s: FindBlockPos failed", __func__);
3366 if (dbp ==
nullptr) {
3367 if (!WriteBlockToDisk(block, blockPos, chainparams.
MessageStart())) {
3368 AbortNode(
"Failed to write block");
3378 const CBlock& block = *pblock;
3380 if (fNewBlock) *fNewBlock =
false;
3384 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
3408 if (fAlreadyHave)
return true;
3410 if (pindex->
nTx != 0)
return true;
3411 if (!fHasMoreOrSameWork)
return true;
3412 if (fTooFarAhead)
return true;
3422 !ContextualCheckBlock(block, state, chainparams.
GetConsensus(), pindex->
pprev)) {
3425 setDirtyBlockIndex.insert(pindex);
3436 if (fNewBlock) *fNewBlock =
true;
3440 state.
Error(
strprintf(
"%s: Failed to find position to write new block to disk", __func__));
3444 }
catch (
const std::runtime_error& e) {
3445 return AbortNode(state, std::string(
"System error: ") + e.what());
3461 if (fNewBlock) *fNewBlock =
false;
3495 indexDummy.pprev = pindexPrev;
3497 indexDummy.phashBlock = &block_hash;
3500 if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev,
GetAdjustedTime()))
3504 if (!ContextualCheckBlock(block, state, chainparams.
GetConsensus(), pindexPrev))
3520 LOCK(cs_LastBlockFile);
3522 uint64_t retval = 0;
3524 retval += file.nSize + file.nUndoSize;
3532 LOCK(cs_LastBlockFile);
3536 if (pindex->
nFile == fileNumber) {
3542 setDirtyBlockIndex.insert(pindex);
3548 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->
pprev);
3549 while (range.first != range.second) {
3550 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
3552 if (_it->second == pindex) {
3553 mapBlocksUnlinked.erase(_it);
3559 vinfoBlockFile[fileNumber].SetNull();
3560 setDirtyFileInfo.insert(fileNumber);
3566 for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
3570 LogPrintf(
"Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
3575 static void FindFilesToPruneManual(std::set<int>& setFilesToPrune,
int nManualPruneHeight)
3577 assert(
fPruneMode && nManualPruneHeight > 0);
3584 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight,
chainActive.
Tip()->
nHeight - MIN_BLOCKS_TO_KEEP);
3586 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
3587 if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
3590 setFilesToPrune.insert(fileNumber);
3593 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune, count);
3621 static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight)
3636 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
3637 uint64_t nBytesToPrune;
3650 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
3651 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
3653 if (vinfoBlockFile[fileNumber].nSize == 0)
3660 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
3665 setFilesToPrune.insert(fileNumber);
3666 nCurrentUsage -= nBytesToPrune;
3671 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
3673 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
3674 nLastBlockWeCanPrune, count);
3682 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
3683 return AbortNode(
"Disk space is low!",
_(
"Error: Disk space is low!"));
3693 fs::create_directories(path.parent_path());
3695 if (!file && !fReadOnly)
3698 LogPrintf(
"Unable to open file %s\n", path.string());
3702 if (fseek(file, pos.
nPos, SEEK_SET)) {
3703 LogPrintf(
"Unable to seek to position %u of %s\n", pos.
nPos, path.string());
3712 return OpenDiskFile(pos,
"blk", fReadOnly);
3716 static FILE* OpenUndoFile(
const CDiskBlockPos &pos,
bool fReadOnly) {
3717 return OpenDiskFile(pos,
"rev", fReadOnly);
3735 return (*mi).second;
3739 mi =
mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
3750 boost::this_thread::interruption_point();
3753 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
3755 for (
const std::pair<const uint256, CBlockIndex*>& item :
mapBlockIndex)
3758 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
3760 sort(vSortedByHeight.begin(), vSortedByHeight.end());
3761 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
3768 if (pindex->
nTx > 0) {
3769 if (pindex->
pprev) {
3782 setDirtyBlockIndex.insert(pindex);
3803 pblocktree->ReadLastBlockFile(nLastBlockFile);
3804 vinfoBlockFile.resize(nLastBlockFile + 1);
3805 LogPrintf(
"%s: last block file = %i\n", __func__, nLastBlockFile);
3806 for (
int nFile = 0; nFile <= nLastBlockFile; nFile++) {
3807 pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
3809 LogPrintf(
"%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
3810 for (
int nFile = nLastBlockFile + 1;
true; nFile++) {
3812 if (
pblocktree->ReadBlockFileInfo(nFile, info)) {
3813 vinfoBlockFile.push_back(info);
3820 LogPrintf(
"Checking all blk files are present...\n");
3821 std::set<int> setBlkDataFiles;
3822 for (
const std::pair<const uint256, CBlockIndex*>& item :
mapBlockIndex)
3826 setBlkDataFiles.insert(pindex->
nFile);
3829 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
3840 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
3843 bool fReindexing =
false;
3859 LogPrintf(
"%s: Connecting genesis block...\n", __func__);
3862 LogPrintf(
"%s: failed to activate chain (%s)\n", __func__,
FormatStateMessage(state));
3876 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
3885 uiInterface.ShowProgress(
_(
"Verifying blocks..."), 0,
false);
3902 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3903 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
3907 int nGoodTransactions = 0;
3910 LogPrintf(
"[0%%]...");
3912 boost::this_thread::interruption_point();
3913 int percentageDone = std::max(1, std::min(99, (
int)(((
double)(
chainActive.
Height() - pindex->
nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
3914 if (reportDone < percentageDone/10) {
3916 LogPrintf(
"[%d%%]...", percentageDone);
3917 reportDone = percentageDone/10;
3919 uiInterface.ShowProgress(
_(
"Verifying blocks..."), percentageDone,
false);
3924 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
3933 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
3936 if (nCheckLevel >= 2 && pindex) {
3939 if (!UndoReadFromDisk(undo, pindex)) {
3952 nGoodTransactions = 0;
3953 pindexFailure = pindex;
3955 nGoodTransactions += block.
vtx.size();
3962 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n",
chainActive.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
3968 if (nCheckLevel >= 4) {
3970 boost::this_thread::interruption_point();
3971 uiInterface.ShowProgress(
_(
"Verifying blocks..."), std::max(1, std::min(99, 100 - (
int)(((
double)(
chainActive.
Height() - pindex->
nHeight)) / (double)nCheckDepth * 50))),
false);
3981 LogPrintf(
"[DONE].\n");
3982 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
3997 if (!tx->IsCoinBase()) {
3998 for (
const CTxIn &txin : tx->vin) {
4015 if (hashHeads.empty())
return true;
4016 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4018 uiInterface.ShowProgress(
_(
"Replaying blocks..."), 0,
false);
4019 LogPrintf(
"Replaying blocks\n");
4026 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4030 if (!hashHeads[1].IsNull()) {
4032 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4036 assert(pindexFork !=
nullptr);
4040 while (pindexOld != pindexFork) {
4056 pindexOld = pindexOld->
pprev;
4060 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4061 for (
int nHeight = nForkHeight + 1; nHeight <= pindexNew->
nHeight; ++nHeight) {
4064 uiInterface.ShowProgress(
_(
"Replaying blocks..."), (
int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->
nHeight - nForkHeight)) ,
false);
4112 LogPrintf(
"RewindBlockIndex: unable to flush state to disk (%s)\n",
FormatStateMessage(state));
4134 pindexIter->
nFile = 0;
4138 pindexIter->
nTx = 0;
4142 setDirtyBlockIndex.insert(pindexIter);
4145 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator>
ret =
mapBlocksUnlinked.equal_range(pindexIter->
pprev);
4146 while (
ret.first !=
ret.second) {
4147 if (
ret.first->second == pindexIter) {
4180 LogPrintf(
"RewindBlockIndex: unable to flush state to disk (%s)\n",
FormatStateMessage(state));
4201 pindexBestInvalid =
nullptr;
4204 mapBlocksUnlinked.clear();
4205 vinfoBlockFile.clear();
4207 setDirtyBlockIndex.clear();
4208 setDirtyFileInfo.clear();
4210 for (
int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
4211 warningcache[b].clear();
4215 delete entry.second;
4228 bool ret = LoadBlockIndexDB(chainparams);
4229 if (!
ret)
return false;
4240 LogPrintf(
"Initializing databases...\n");
4258 CDiskBlockPos blockPos = SaveBlockToDisk(block, 0, chainparams,
nullptr);
4260 return error(
"%s: writing genesis block to disk failed", __func__);
4263 }
catch (
const std::runtime_error& e) {
4264 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
4278 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
4284 CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SERIALIZED_SIZE, MAX_BLOCK_SERIALIZED_SIZE+8,
SER_DISK, CLIENT_VERSION);
4285 uint64_t nRewind = blkdat.
GetPos();
4286 while (!blkdat.
eof()) {
4287 boost::this_thread::interruption_point();
4292 unsigned int nSize = 0;
4297 nRewind = blkdat.
GetPos()+1;
4303 if (nSize < 80 || nSize > MAX_BLOCK_SERIALIZED_SIZE)
4305 }
catch (
const std::exception&) {
4311 uint64_t nBlockPos = blkdat.
GetPos();
4313 dbp->
nPos = nBlockPos;
4314 blkdat.
SetLimit(nBlockPos + nSize);
4315 blkdat.
SetPos(nBlockPos);
4316 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
4319 nRewind = blkdat.
GetPos();
4321 uint256 hash = block.GetHash();
4327 block.hashPrevBlock.ToString());
4329 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
4359 std::deque<uint256> queue;
4360 queue.push_back(hash);
4361 while (!queue.empty()) {
4364 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
4365 while (range.first != range.second) {
4366 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
4367 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
4370 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
4377 queue.push_back(pblockrecursive->GetHash());
4381 mapBlocksUnknownParent.erase(it);
4385 }
catch (
const std::exception& e) {
4386 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
4389 }
catch (
const std::runtime_error& e) {
4390 AbortNode(std::string(
"System error: ") + e.what());
4393 LogPrintf(
"Loaded %i blocks from external file in %dms\n", nLoaded,
GetTimeMillis() - nStart);
4414 std::multimap<CBlockIndex*,CBlockIndex*> forward;
4415 for (
const std::pair<const uint256, CBlockIndex*>& entry :
mapBlockIndex) {
4416 forward.insert(std::make_pair(entry.second->pprev, entry.second));
4421 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
4423 rangeGenesis.first++;
4424 assert(rangeGenesis.first == rangeGenesis.second);
4435 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
4437 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
4438 while (pindex !=
nullptr) {
4442 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
4449 if (pindex->
pprev ==
nullptr) {
4460 assert(pindexFirstMissing == pindexFirstNeverProcessed);
4468 assert((pindexFirstNeverProcessed !=
nullptr) == (pindex->
nChainTx == 0));
4469 assert((pindexFirstNotTransactionsValid !=
nullptr) == (pindex->
nChainTx == 0));
4470 assert(pindex->
nHeight == nHeight);
4473 assert(pindexFirstNotTreeValid ==
nullptr);
4477 if (pindexFirstInvalid ==
nullptr) {
4481 if (!CBlockIndexWorkComparator()(pindex,
chainActive.
Tip()) && pindexFirstNeverProcessed ==
nullptr) {
4482 if (pindexFirstInvalid ==
nullptr) {
4487 if (pindexFirstMissing ==
nullptr || pindex ==
chainActive.
Tip()) {
4498 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked =
mapBlocksUnlinked.equal_range(pindex->
pprev);
4499 bool foundInUnlinked =
false;
4500 while (rangeUnlinked.first != rangeUnlinked.second) {
4501 assert(rangeUnlinked.first->first == pindex->
pprev);
4502 if (rangeUnlinked.first->second == pindex) {
4503 foundInUnlinked =
true;
4506 rangeUnlinked.first++;
4508 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
4510 assert(foundInUnlinked);
4513 if (pindexFirstMissing ==
nullptr) assert(!foundInUnlinked);
4514 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
4526 if (pindexFirstInvalid ==
nullptr) {
4527 assert(foundInUnlinked);
4535 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
4536 if (range.first != range.second) {
4538 pindex = range.first->second;
4547 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
4548 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
4549 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
4550 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
4551 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
4552 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
4553 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
4557 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
4558 while (rangePar.first->second != pindex) {
4559 assert(rangePar.first != rangePar.second);
4564 if (rangePar.first != rangePar.second) {
4566 pindex = rangePar.first->second;
4578 assert(nNodes == forward.size());
4588 LOCK(cs_LastBlockFile);
4590 return &vinfoBlockFile.at(n);
4611 static const uint64_t MEMPOOL_DUMP_VERSION = 1;
4616 int64_t nExpiryTimeout =
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
4620 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
4625 int64_t expired = 0;
4627 int64_t already_there = 0;
4633 if (version != MEMPOOL_DUMP_VERSION) {
4646 CAmount amountdelta = nFeeDelta;
4651 if (nTime + nExpiryTimeout > nNow) {
4653 AcceptToMemoryPoolWithTime(chainparams,
mempool, state, tx,
nullptr , nTime,
4654 nullptr ,
false , 0 ,
4675 std::map<uint256, CAmount> mapDeltas;
4678 for (
const auto& i : mapDeltas) {
4681 }
catch (
const std::exception& e) {
4682 LogPrintf(
"Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
4686 LogPrintf(
"Imported mempool transactions from disk: %i succeeded, %i failed, %i expired, %i already there\n", count, failed, expired, already_there);
4694 std::map<uint256, CAmount> mapDeltas;
4695 std::vector<TxMempoolInfo> vinfo;
4697 static Mutex dump_mutex;
4703 mapDeltas[i.first] = i.second;
4718 uint64_t version = MEMPOOL_DUMP_VERSION;
4721 file << (uint64_t)vinfo.size();
4722 for (
const auto& i : vinfo) {
4724 file << (int64_t)i.nTime;
4725 file << (int64_t)i.nFeeDelta;
4726 mapDeltas.erase(i.tx->GetHash());
4731 throw std::runtime_error(
"FileCommit failed");
4735 LogPrintf(
"Dumped mempool: %gs to copy, %gs to dump\n", (mid-
start)*
MICRO, (last-mid)*
MICRO);
4736 }
catch (
const std::exception& e) {
4737 LogPrintf(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
4746 if (pindex ==
nullptr)
4749 int64_t nNow = time(
nullptr);
4759 return pindex->
nChainTx / fTxTotal;
4770 delete (*it1).second;
bool FileCommit(FILE *file)
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
std::multimap< CBlockIndex *, CBlockIndex * > mapBlocksUnlinked
CDiskBlockPos GetBlockPos() const
std::set< CBlockIndex * > m_failed_blocks
In order to efficiently track invalidity of headers, we keep the set of blocks which we tried to conn...
int Expire(int64_t time)
Expire all transaction (and their dependencies) in the mempool older than time.
std::vector< Coin > vprevout
void ReceivedBlockTransactions(const CBlock &block, CBlockIndex *pindexNew, const CDiskBlockPos &pos, const Consensus::Params &consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
std::string ToString() const
int64_t EndTime(const Consensus::Params ¶ms) const override
void resize(size_type new_size)
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
CBlockIndex * FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Return the tip of the chain with the most work in it, that isn't known to be invalid (it's however fa...
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
void NotifyEntryRemoved(CTransactionRef txRemoved, MemPoolRemovalReason reason)
bool fPruneMode
True if we're running in -prune mode.
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
bool ConnectTip(CValidationState &state, const CChainParams &chainparams, CBlockIndex *pindexNew, const std::shared_ptr< const CBlock > &pblock, ConnectTrace &connectTrace, DisconnectedBlockTransactions &disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Connect a new block to chainActive.
std::condition_variable g_best_block_cv
std::pair< int, int64_t > CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector< int > *prevHeights, const CBlockIndex &block)
Calculates the block height and previous block's median time past at which the transaction will be co...
void UnloadBlockIndex()
Unload database information.
CCriticalSection m_cs_chainstate
the ChainState CriticalSection A lock that must be held when modifying this ChainState - held in Acti...
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock...
void PruneBlockIndexCandidates()
Delete all entries in setBlockIndexCandidates that are worse than the current tip.
void Add(std::vector< T > &vChecks)
int64_t GetBlockTime() const
indexed_transaction_set::nth_index< 0 >::type::const_iterator txiter
FILE * fopen(const fs::path &p, const char *mode)
int Threshold(const Consensus::Params ¶ms) const override
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
double dTxRate
estimated number of transactions per second after that timestamp
descends from failed block
CBlockIndex * pprev
pointer to the index of the predecessor of this block
std::vector< TxMempoolInfo > infoAll() const
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or a pruned one if not found.
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN)
bool Flush()
Push the modifications applied to this cache to its base.
void SetBackend(CCoinsView &viewIn)
void CheckBlockIndex(const Consensus::Params &consensusParams)
Make various assertions about the state of the block index.
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > *prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block...
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
CBlockIndex * pindexBestForkBase
int64_t BeginTime(const Consensus::Params ¶ms) const override
bool InvalidateBlock(CValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool LoadGenesisBlock(const CChainParams &chainparams)
Ensures we have a genesis block in the block tree, possibly writing one to disk.
bool ActivateBestChain(CValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Make the best chain active, in multiple steps.
An in-memory indexed chain of blocks.
bool VerifyDB(const CChainParams &chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
void CalculateDescendants(txiter it, setEntries &setDescendants) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Populate setDescendants with all in-mempool descendants of hash.
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
size_t DynamicMemoryUsage() const
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
bool fHavePruned
Pruning-related variables and constants.
std::atomic_bool fReindex(false)
reverse_range< T > reverse_iterate(T &x)
bool PreciousBlock(CValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main)
int Period(const Consensus::Params ¶ms) const override
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
UniValue ret(UniValue::VARR)
std::string ToString() const
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool LoadMempool()
Load the mempool from disk.
bool MoneyRange(const CAmount &nValue)
int Height() const
Return the maximal height in the chain.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
CTxOut out
unspent transaction output
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
cache implements a cache with properties similar to a cuckoo-set
stage after last reached validness failed
unsigned int fCoinBase
whether containing transaction was a coinbase
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
CChainState stores and provides an API to update our local knowledge of the current best chain and he...
bool HasNoInputsOf(const CTransaction &tx) const
Check that none of this transactions inputs are in the mempool, and thus the tx is not dependent on o...
BIP9Stats VersionBitsTipStatistics(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the numerical statistics for the BIP9 state for a given deployment at the current tip...
unsigned int nSize
number of used bytes of block file
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check)
Utility function to add all of a transaction's outputs to a cache.
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
std::set< txiter, CompareIteratorByHash > setEntries
void addTransaction(const CTransactionRef &tx)
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
const CBlock & GenesisBlock() const
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out)
Restore the UTXO in a Coin at a given COutPoint.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
undo data available in rev*.dat
bool ReplayBlocks(const CChainParams ¶ms, CCoinsView *view)
uint32_t VersionBitsMask(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
int nFile
Which # file this block is stored in (blk?????.dat)
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Determine what nVersion a new block should use.
void TrimToSize(size_t sizelimit, std::vector< COutPoint > *pvNoSpendsRemaining=nullptr)
Remove transactions from the mempool until its dynamic size is <= sizelimit.
bool ProcessNewBlock(const CChainParams &chainparams, const std::shared_ptr< const CBlock > pblock, bool fForceProcessing, bool *fNewBlock)
Process an incoming block.
int64_t nTime
UNIX timestamp of last known number of transactions.
bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
Check if transaction will be BIP 68 final in the next block to be created.
const CCheckpointData & Checkpoints() const
bool IsNullDummyEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether NULLDUMMY (BIP 147) has activated.
void BlockChecked(const CBlock &, const CValidationState &)
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
std::shared_ptr< const CTransaction > CTransactionRef
CBlockIndex * pindexBestForkTip
Signals for UI communication.
void RenameThread(const char *name)
bool LoadBlockIndex(const Consensus::Params &consensus_params, CBlockTreeDB &blocktree) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
unsigned int nHeightLast
highest height of block in file
Reads data from an underlying stream, while hashing the read data (SHA-256).
const std::string strMessageMagic
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
bool ActivateBestChain(CValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Find the best known block, and make it the tip of the block chain.
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
const std::vector< CTxIn > vin
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
ThresholdState VersionBitsTipState(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the BIP9 state for a given deployment at the current tip.
bool IsWitnessStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check if the transaction is over standard P2WSH resources limit: 3600bytes witnessScript size...
size_t GetSerializeSize(const T &t, int nVersion=0)
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate)
When adding transactions from a disconnected block back to the mempool, new mempool entries may have ...
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, const CAmount nAbsurdFee, bool test_accept)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &headers, CValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex, CBlockHeader *first_invalid)
Process incoming block headers.
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN) EXCLUSIVE_LOCKS_REQUIRED(cs)
Remove a set of transactions from the mempool.
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
int nSubsidyHalvingInterval
const char * ScriptErrorString(const ScriptError serror)
std::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
bool nBIP34Enabled
Block height and hash at which BIP34 becomes active.
int64_t nTxCount
total number of transactions between genesis and that timestamp
int64_t CAmount
Amount in satoshis (Can be negative)
void SetBestBlock(const uint256 &hashBlock)
bool CheckDiskSpace(uint64_t nAdditionalBytes, bool blocks_dir)
Check whether enough disk space is available for an incoming block.
uint256 GetBlockHash() const
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check transaction inputs to mitigate two potential denial-of-service attacks:
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
#define AssertLockHeld(cs)
CBlockPolicyEstimator feeEstimator
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
Removed for reorganization.
indexed_disconnected_transactions queuedTx
bool SetLimit(uint64_t nPos=(uint64_t)(-1))
std::string FormatISO8601Date(int64_t nTime)
uint64_t PruneAfterHeight() const
void SetCorruptionPossible()
void SetfLargeWorkInvalidChainFound(bool flag)
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
bool ReplayBlocks(const CChainParams ¶ms, CCoinsView *view)
Replay blocks that aren't fully applied to the database.
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
bool TruncateFile(FILE *file, unsigned int length)
uint64_t nTimeFirst
earliest time of block in file
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
FILE * OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
void PruneOneBlockFile(const int fileNumber)
Mark one block file as pruned.
CCriticalSection cs_nBlockSequenceId
Every received block is assigned a unique and increasing identifier, so we know which one to give pri...
int GetSpendHeight(const CCoinsViewCache &inputs)
Return the spend height, which is one more than the inputs.GetBestBlock().
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Access to the block database (blocks/index/)
Abstract view on the open txout dataset.
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
bool exists(const uint256 &hash) const
void removeForBlock(const std::vector< CTransactionRef > &vtx)
An input of a transaction.
bool LoadGenesisBlock(const CChainParams &chainparams)
const uint256 & GetWitnessHash() const
ConnectTrace(CTxMemPool &_pool)
int VersionBitsStateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
bool CheckBlock(const CBlock &block, CValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
The BlockPolicyEstimator is used for estimating the feerate needed for a transaction to be included i...
bool CheckTxInputs(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight, CAmount &txfee)
Check whether all inputs of this transaction are valid (no double spends and amounts) This does not m...
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
const uint256 & GetHash() const
std::unique_ptr< CCoinsViewDB > pcoinsdbview
Global variable that points to the coins database (protected by cs_main)
Removed for conflict with in-block transaction.
CBlockIndex * pindexBestInvalid
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
std::map< uint256, CAmount > mapDeltas
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
Abstract class that implements BIP9-style threshold logic, and caches results.
std::string GetRejectReason() const
Holds various statistics on transactions within a chain.
const std::vector< CTxOut > vout
bool DisconnectTip(CValidationState &state, const CChainParams &chainparams, DisconnectedBlockTransactions *disconnectpool)
Disconnect chainActive's tip.
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
this function tries to make a particular range of a file allocated (corresponding to disk space) it i...
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
bool IsInitialBlockDownload()
Check whether we are doing an initial block download (synchronizing from disk or network) ...
std::shared_ptr< const CBlock > pblock
bool CheckInputs(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData &txdata, std::vector< CScriptCheck > *pvChecks=nullptr)
Check whether all inputs of this transaction are valid (no double spends, scripts & sigs...
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
CMainSignals & GetMainSignals()
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
unsigned int nHeightFirst
lowest height of block in file
void BuildSkip()
Build the skiplist pointer for this entry.
const CMessageHeader::MessageStartChars & MessageStart() const
int VersionBitsTipStateSinceHeight(const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
Get the block height at which the BIP9 deployment switched into the state for the block building on t...
bool AcceptBlock(const std::shared_ptr< const CBlock > &pblock, CValidationState &state, const CChainParams &chainparams, CBlockIndex **ppindex, bool fRequested, const CDiskBlockPos *dbp, bool *fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Store block on disk.
bool TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
std::string ToString() const
An output of a transaction.
std::string ToString() const
void read(char *pch, size_t nSize)
unsigned int size() const
std::vector< uint256 > vHave
CBlockIndex * GetLastCheckpoint(const CCheckpointData &data)
Returns last CBlockIndex* that is a checkpoint.
uint32_t nMinerConfirmationWindow
bool ActivateBestChainStep(CValidationState &state, const CChainParams &chainparams, CBlockIndex *pindexMostWork, const std::shared_ptr< const CBlock > &pblock, bool &fInvalidFound, ConnectTrace &connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Try to make some progress towards making pindexMostWork the active block.
bool SetPos(uint64_t nPos)
class CMainCleanup instance_of_cmaincleanup
Queue for verifications that have to be performed.
const CTransaction * GetConflictTx(const COutPoint &prevout) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Get the transaction in the pool that spends the same prevout.
Parameters that influence chain consensus.
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
void ChainStateFlushed(const CBlockLocator &)
void ThreadScriptCheck()
Run an instance of the script checking thread.
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
An outpoint - a combination of a transaction hash and an index n into its vout.
CScript COINBASE_FLAGS
Constant stuff for coinbase transactions we create:
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
void AddTransactionsUpdated(unsigned int n)
CFeeRate GetMinFee(size_t sizelimit) const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
bool RenameOver(fs::path src, fs::path dest)
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
arith_uint256 nLastPreciousChainwork
chainwork for the last block that preciousblock has been applied to.
bool DumpMempool()
Dump the mempool to disk.
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download...
256-bit unsigned big integer.
int64_t GetMedianTimePast() const
block data in blk*.data was received with a witness-enforcing client
VersionBitsCache versionbitscache
void FlushStateToDisk()
Flush all state, indexes and buffers to disk.
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Closure representing one script verification Note that this stores references to the spending transac...
const fs::path & GetBlocksDir(bool fNetSpecific)
A hasher class for SHA3-256.
bool LoadBlockIndex(const CChainParams &chainparams)
Load the block tree and coins database from disk, initializing state if we're running with -reindex...
bool Error(const std::string &strRejectReasonIn)
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
std::shared_ptr< std::vector< CTransactionRef > > conflictedTxs
int32_t nBlockSequenceId
Blocks loaded from disk are assigned id 0, so start the counter at 1.
bool AcceptBlockHeader(const CBlockHeader &block, CValidationState &state, const CChainParams &chainparams, CBlockIndex **ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
If a block header hasn't already been seen, call CheckBlockHeader on it, ensure that it doesn't desce...
int32_t nVersion
block header
Capture information about block/transaction validation.
class CChainState g_chainstate
bool LoadExternalBlockFile(const CChainParams &chainparams, FILE *fileIn, CDiskBlockPos *dbp)
Import blocks from an external file.
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
std::atomic_bool g_is_mempool_loaded
DisconnectResult DisconnectBlock(const CBlock &block, const CBlockIndex *pindex, CCoinsViewCache &view)
Undo the effects of this block (with given index) on the UTXO set represented by coins.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::vector< CTransactionRef > vtx
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
void Finalize(unsigned char hash[OUTPUT_SIZE])
void SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
const ChainTxData & TxData() const
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
int32_t nBlockReverseSequenceId
Decreasing counter (used by subsequent preciousblock calls).
bool ConnectBlock(const CBlock &block, CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, const CChainParams &chainparams, bool fJustCheck=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of this block (with given index) on the UTXO set represented by coins...
#define LOCKS_EXCLUDED(...)
CBlockIndex * AddToBlockIndex(const CBlockHeader &block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
Undo information for a CTransaction.
std::atomic_bool fImporting(false)
void * memcpy(void *a, const void *b, size_t c)
std::vector< PerBlockConnectTrace > blocksConnected
std::vector< unsigned char > GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
bool GetfLargeWorkForkFound()
CDiskBlockPos GetUndoPos() const
void InitScriptExecutionCache()
Initializes the script-execution cache.
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
void PruneBlockFilesManual(int nManualPruneHeight)
Prune block files up to a given height.
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
int64_t GetAdjustedTime()
setEntries GetIterSet(const std::set< uint256 > &hashes) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Translate a set of hashes into a set of pool iterators to avoid repeated lookups. ...
bool TestBlockValidity(CValidationState &state, const CChainParams &chainparams, const CBlock &block, CBlockIndex *pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
Check a block is completely valid from start to finish (only works on top of our current best block) ...
void runCommand(const std::string &strCommand)
CHash3 & Write(const unsigned char *data, size_t len)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CSHA3 & Write(const unsigned char *data, size_t len)
std::set< CBlockIndex *, CBlockIndexWorkComparator > setBlockIndexCandidates
The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and a...
void SetMiscWarning(const std::string &strWarning)
Fee rate in satoshis per kilobyte: CAmount / kB.
unsigned int nBlocks
number of blocks stored in file
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
#define AssertLockNotHeld(cs)
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
std::string GetDebugMessage() const
bool error(const char *fmt, const Args &... args)
A hasher class for BSHA3's 256-bit hash (double SHA-3).
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
bool CheckTransaction(const CTransaction &tx, CValidationState &state, bool fCheckDuplicateInputs)
Transaction validation functions.
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for block.
unsigned int GetRejectCode() const
bool LoadBlockIndexGuts(const Consensus::Params &consensusParams, std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
bool IsStandardTx(const CTransaction &tx, std::string &reason)
Check for standard transaction types.
void Finalize(unsigned char hash[OUTPUT_SIZE])
A mutable version of CTransaction.
A writer stream (for serialization) that computes a 256-bit SHA-3-256 hash.
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period...
CTransactionRef get(const uint256 &hash) const
bool CorruptionPossible() const
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time...
boost::signals2::signal< void(CTransactionRef, MemPoolRemovalReason)> NotifyEntryRemoved
uint64_t nTimeLast
latest time of block in file
const fs::path & GetDataDir(bool fNetSpecific)
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight)
Called when a block is connected.
arith_uint256 GetBlockProof(const CBlockIndex &block)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
void BlockDisconnected(const std::shared_ptr< const CBlock > &)
CClientUIInterface uiInterface
size_t DynamicMemoryUsage() const
The basic transaction that is broadcasted on the network and contained in blocks. ...
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const CDiskBlockPos &pos, const CMessageHeader::MessageStartChars &message_start)
int nHeight
height of the entry in the chain. The genesis block has height 0
WarningBitsConditionChecker(int bitIn)
const Consensus::Params & GetConsensus() const
std::unordered_map< uint256, CBlockIndex *, BlockHasher > BlockMap
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
BIP9Stats VersionBitsStatistics(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos)
CCoinsView that adds a memory cache for transactions to another CCoinsView.
std::vector< PerBlockConnectTrace > & GetBlocksConnected()
void PruneAndFlush()
Prune block files and flush state to disk.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
full block available in blk*.dat
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
bool Invalid(bool ret=false, unsigned int _chRejectCode=0, const std::string &_strRejectReason="", const std::string &_strDebugMessage="")
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from...
uint64_t CalculateCurrentUsage()
BLOCK PRUNING CODE.
void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::vector< CTxUndo > vtxundo
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::string ToString() const
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
void SetfLargeWorkForkFound(bool flag)
CBlockIndex * maxInputBlock
fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
Translation to a filesystem path.
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
CCoinsView that brings transactions from a mempool into view.
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, int flags)
Compute total signature operation cost of a transaction.
bool RewindBlockIndex(const CChainParams ¶ms)
When there are blocks in the active chain with missing data, rewind the chainstate and remove them fr...
CFeeRate incrementalRelayFee
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
void addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate=true) EXCLUSIVE_LOCKS_REQUIRED(cs)
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
unsigned int nTx
Number of transactions in this block.
bool LoadChainTip(const CChainParams &chainparams)
Update the chain tip based on database information.
void UpdateUncommittedBlockStructures(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Update uncommitted block structures (currently: only the witness reserved value). ...
Non-refcounted RAII wrapper for FILE*.
std::string _(const char *psz)
Translation function.
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
bool RewindBlockIndex(const CChainParams ¶ms)
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params ¶ms)
Return the time it would take to redo the work difference between from and to, assuming the current h...
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, const CChainParams ¶ms) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Apply the effects of a block on the utxo cache, ignoring that it may already have been applied...
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex, const std::shared_ptr< const std::vector< CTransactionRef >> &)
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
void TransactionAddedToMempool(const CTransactionRef &)
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
CBlockIndex * LookupBlockIndex(const uint256 &hash)
Threshold condition checker that triggers when unknown versionbits are seen on the network...