50 #include <boost/algorithm/string/replace.hpp> 51 #include <boost/algorithm/string/join.hpp> 52 #include <boost/thread.hpp> 61 # error "Raven cannot be compiled without assertions." 64 #define MICRO 0.000001 122 struct CBlockIndexWorkComparator
135 if (pa < pb)
return false;
136 if (pa > pb)
return true;
150 std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
154 std::multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
157 std::vector<CBlockFileInfo> vinfoBlockFile;
158 int nLastBlockFile = 0;
163 bool fCheckForPruning =
false;
171 int32_t nBlockSequenceId = 1;
173 int32_t nBlockReverseSequenceId = -1;
195 std::set<CBlockIndex*> g_failed_blocks;
198 std::set<CBlockIndex*> setDirtyBlockIndex;
201 std::set<int> setDirtyFileInfo;
250 static void FindFilesToPruneManual(std::set<int>& setFilesToPrune,
int nManualPruneHeight);
251 static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
253 static FILE* OpenUndoFile(
const CDiskBlockPos &pos,
bool fReadOnly =
false);
265 flags = std::max(flags, 0);
273 const int nBlockHeight = chainActive.
Height() + 1;
284 return IsFinalTx(tx, nBlockHeight, nBlockTime);
311 assert(tip !=
nullptr);
323 std::pair<int, int64_t> lockPair;
324 if (useExistingLockPoints) {
326 lockPair.first = lp->
height;
327 lockPair.second = lp->
time;
332 std::vector<int> prevheights;
333 prevheights.resize(tx.
vin.size());
334 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
335 const CTxIn& txin = tx.
vin[txinIndex];
338 return error(
"%s: Missing input", __func__);
340 if (coin.
nHeight == MEMPOOL_HEIGHT) {
342 prevheights[txinIndex] = tip->
nHeight + 1;
344 prevheights[txinIndex] = coin.
nHeight;
349 lp->
height = lockPair.first;
350 lp->
time = lockPair.second;
364 int maxInputHeight = 0;
365 for (
int height : prevheights) {
367 if (height != tip->
nHeight+1) {
368 maxInputHeight = std::max(maxInputHeight, height);
380 static void LimitMempoolSize(
CTxMemPool& pool,
size_t limit,
unsigned long age) {
386 std::vector<COutPoint> vNoSpendsRemaining;
388 for (
const COutPoint& removed : vNoSpendsRemaining)
401 static bool IsCurrentForFeeEstimation()
429 std::vector<uint256> vHashUpdate;
440 if (!fAddToMempool || (*it)->IsCoinBase() ||
442 nullptr ,
true , 0 )) {
447 vHashUpdate.push_back((*it)->GetHash());
462 LimitMempoolSize(
mempool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
484 if (coin.
IsSpent())
return false;
489 assert(txFrom->vout.size() > txin.
prevout.
n);
493 assert(!coinFromDisk.
IsSpent());
494 assert(coinFromDisk.
out == coin.
out);
498 return CheckInputs(tx, state, view,
true,
flags, cacheSigStore,
true, txdata);
502 bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
503 bool bypass_limits,
const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache)
509 std::vector<std::pair<std::string, uint256>> vReissueAssets;
512 *pfMissingInputs =
false;
518 return state.
DoS(100,
false, REJECT_INVALID,
"coinbase");
523 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"no-witness-yet",
true);
529 return state.
DoS(0,
false, REJECT_NONSTANDARD, reason);
535 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"non-final");
539 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-already-in-mempool");
543 std::set<uint256> setConflicts;
551 const CTransaction *ptxConflicting = itConflicting->second;
552 if (!setConflicts.count(ptxConflicting->
GetHash()))
566 bool fReplacementOptOut =
true;
569 for (
const CTxIn &_txin : ptxConflicting->
vin)
571 if (_txin.
nSequence <= MAX_BIP125_RBF_SEQUENCE)
573 fReplacementOptOut =
false;
578 if (fReplacementOptOut) {
579 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-mempool-conflict");
582 setConflicts.insert(ptxConflicting->
GetHash());
601 coins_to_uncache.push_back(txin.
prevout);
605 for (
size_t out = 0; out < tx.
vout.size(); out++) {
608 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-already-known");
612 if (pfMissingInputs) {
613 *pfMissingInputs =
true;
631 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"non-BIP68-final");
642 for (
auto out : tx.
vout) {
643 if (out.scriptPubKey.IsAssetScript())
644 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-contained-asset-when-not-active");
657 return state.
Invalid(
false, REJECT_NONSTANDARD,
"bad-txns-nonstandard-inputs");
661 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"bad-witness-nonstandard",
true);
671 bool fSpendsCoinbase =
false;
675 fSpendsCoinbase =
true;
681 fSpendsCoinbase, nSigOpsCost, lp);
689 if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
690 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"bad-txns-too-many-sigops",
false,
694 if (!bypass_limits && mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
695 return state.
DoS(0,
false, REJECT_INSUFFICIENTFEE,
"mempool min fee not met",
false,
strprintf(
"%d < %d", nFees, mempoolRejectFee));
702 return state.
DoS(0,
false, REJECT_INSUFFICIENTFEE,
"min relay fee not met");
705 if (nAbsurdFee && nFees > nAbsurdFee)
707 REJECT_HIGHFEE,
"absurdly-high-fee",
708 strprintf(
"%d > %d", nFees, nAbsurdFee));
712 size_t nLimitAncestors =
gArgs.
GetArg(
"-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
713 size_t nLimitAncestorSize =
gArgs.
GetArg(
"-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
714 size_t nLimitDescendants =
gArgs.
GetArg(
"-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
715 size_t nLimitDescendantSize =
gArgs.
GetArg(
"-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
716 std::string errString;
717 if (!pool.
CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
718 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"too-long-mempool-chain",
false, errString);
727 const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
728 if (setConflicts.count(hashAncestor))
730 return state.
DoS(10,
false,
731 REJECT_INVALID,
"bad-txns-spends-conflicting-tx",
false,
732 strprintf(
"%s spends conflicting transaction %s",
741 size_t nConflictingSize = 0;
742 uint64_t nConflictingCount = 0;
749 const bool fReplacementTransaction = setConflicts.size();
750 if (fReplacementTransaction)
752 CFeeRate newFeeRate(nModifiedFees, nSize);
753 std::set<uint256> setConflictsParents;
754 const int maxDescendantsToVisit = 100;
756 for (
const uint256 &hashConflicting : setConflicts)
759 if (mi == pool.
mapTx.end())
763 setIterConflicting.insert(mi);
781 CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
782 if (newFeeRate <= oldFeeRate)
784 return state.
DoS(0,
false,
785 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
786 strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
789 oldFeeRate.ToString()));
792 for (
const CTxIn &txin : mi->GetTx().vin)
797 nConflictingCount += mi->GetCountWithDescendants();
802 if (nConflictingCount <= maxDescendantsToVisit) {
809 nConflictingFees += it->GetModifiedFee();
810 nConflictingSize += it->GetTxSize();
813 return state.
DoS(0,
false,
814 REJECT_NONSTANDARD,
"too many potential replacements",
false,
815 strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
818 maxDescendantsToVisit));
821 for (
unsigned int j = 0; j < tx.
vin.size(); j++)
827 if (!setConflictsParents.count(tx.
vin[j].prevout.hash))
832 if (pool.
mapTx.find(tx.
vin[j].prevout.hash) != pool.
mapTx.end())
833 return state.
DoS(0,
false,
834 REJECT_NONSTANDARD,
"replacement-adds-unconfirmed",
false,
835 strprintf(
"replacement %s adds unconfirmed input, idx %d",
843 if (nModifiedFees < nConflictingFees)
845 return state.
DoS(0,
false,
846 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
847 strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
853 CAmount nDeltaFees = nModifiedFees - nConflictingFees;
856 return state.
DoS(0,
false,
857 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
858 strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
865 unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
867 scriptVerifyFlags =
gArgs.
GetArg(
"-promiscuousmempoolflags", scriptVerifyFlags);
873 if (!
CheckInputs(tx, state, view,
true, scriptVerifyFlags,
true,
false, txdata)) {
901 unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(chainActive.
Tip(),
Params().
GetConsensus());
902 if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, currentBlockScriptVerifyFlags,
true, txdata))
907 if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) {
908 return error(
"%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against latest-block but not STANDARD flags %s, %s",
911 if (!
CheckInputs(tx, state, view,
true, MANDATORY_SCRIPT_VERIFY_FLAGS,
true,
false, txdata)) {
912 return error(
"%s: ConnectInputs failed against MANDATORY but not STANDARD flags due to promiscuous mempool %s, %s",
915 LogPrintf(
"Warning: -promiscuousmempool flags set to not include currently enforced soft forks, this may break mining or otherwise cause instability!\n");
924 it->GetTx().GetHash().ToString(),
927 (int)nSize - (
int)nConflictingSize);
929 plTxnReplaced->push_back(it->GetSharedTx());
938 bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation() && pool.
HasNoInputsOf(tx);
941 pool.
addUnchecked(hash, entry, setAncestors, validForFeeEstimation);
954 if (!bypass_limits) {
955 LimitMempoolSize(pool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
957 return state.
DoS(0,
false, REJECT_INSUFFICIENTFEE,
"mempool full");
960 for (
auto out : vReissueAssets) {
966 for (
auto out : tx.
vout) {
967 if (out.scriptPubKey.IsAssetScript()) {
993 for (
auto in : tx.
vin) {
1022 bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
1023 bool bypass_limits,
const CAmount nAbsurdFee)
1025 std::vector<COutPoint> coins_to_uncache;
1026 bool res = AcceptToMemoryPoolWorker(chainparams, pool, state, tx, pfMissingInputs, nAcceptTime, plTxnReplaced, bypass_limits, nAbsurdFee, coins_to_uncache);
1028 for (
const COutPoint& hashTx : coins_to_uncache)
1038 bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced,
1039 bool bypass_limits,
const CAmount nAbsurdFee)
1042 return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, pfMissingInputs,
GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee);
1045 bool GetTimestampIndex(
const unsigned int &
high,
const unsigned int &
low,
const bool fActiveOnly, std::vector<std::pair<uint256, unsigned int> > &hashes)
1048 return error(
"Timestamp index not enabled");
1051 return error(
"Unable to get hashes for timestamps");
1074 if (!chainActive.
Contains(pblockindex)) {
1082 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,
int start,
int end)
1085 return error(
"address index not enabled");
1087 if (!pblocktree->
ReadAddressIndex(addressHash, type, assetName, addressIndex, start, end))
1088 return error(
"unable to get txids for address");
1094 std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,
int start,
int end)
1097 return error(
"address index not enabled");
1099 if (!pblocktree->
ReadAddressIndex(addressHash, type, addressIndex, start, end))
1100 return error(
"unable to get txids for address");
1106 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1109 return error(
"address index not enabled");
1112 return error(
"unable to get txids for address");
1118 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs)
1121 return error(
"address index not enabled");
1124 return error(
"unable to get txids for address");
1148 return error(
"%s: OpenBlockFile failed", __func__);
1154 }
catch (
const std::exception& e) {
1155 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1158 if (txOut->GetHash() != hash)
1159 return error(
"%s: txid mismatch", __func__);
1175 for (
const auto& tx : block.
vtx) {
1203 return error(
"WriteBlockToDisk: OpenBlockFile failed");
1207 fileout <<
FLATDATA(messageStart) << nSize;
1210 long fileOutPos = ftell(fileout.
Get());
1212 return error(
"WriteBlockToDisk: ftell failed");
1213 pos.
nPos = (
unsigned int)fileOutPos;
1226 return error(
"ReadBlockFromDisk: OpenBlockFile failed for %s", pos.
ToString());
1232 catch (
const std::exception& e) {
1233 return error(
"%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.
ToString());
1238 return error(
"ReadBlockFromDisk: Errors in block header at %s", pos.
ToString());
1248 return error(
"ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
1260 CAmount nSubsidy = 5000 * COIN;
1262 nSubsidy >>= halvings;
1269 static std::atomic<bool> latchToFalse{
false};
1271 if (latchToFalse.load(std::memory_order_relaxed))
1275 if (latchToFalse.load(std::memory_order_relaxed))
1282 if (chainActive.
Tip() ==
nullptr)
1300 latchToFalse.store(
true, std::memory_order_relaxed);
1307 static std::atomic<bool> syncLatchToFalse{
false};
1309 if (syncLatchToFalse.load(std::memory_order_relaxed))
1313 if (syncLatchToFalse.load(std::memory_order_relaxed))
1320 if (chainActive.
Tip() ==
nullptr)
1338 syncLatchToFalse.store(
true, std::memory_order_relaxed);
1344 static void AlertNotify(
const std::string& strMessage)
1347 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1348 if (strCmd.empty())
return;
1353 std::string singleQuote(
"'");
1355 safeStatus = singleQuote+safeStatus+singleQuote;
1356 boost::replace_all(strCmd,
"%s", safeStatus);
1361 static void CheckForkWarningConditions()
1371 if (pindexBestForkTip && chainActive.
Height() - pindexBestForkTip->
nHeight >= 72)
1372 pindexBestForkTip =
nullptr;
1374 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.
Tip()->
nChainWork + (
GetBlockProof(*chainActive.
Tip()) * 6)))
1378 std::string warning = std::string(
"'Warning: Large-work fork detected, forking after block ") +
1380 AlertNotify(warning);
1384 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__,
1391 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1402 static void CheckForkWarningConditionsOnNewFork(
CBlockIndex* pindexNewForkTip)
1408 while (pfork && pfork != plonger)
1411 plonger = plonger->
pprev;
1412 if (pfork == plonger)
1414 pfork = pfork->
pprev;
1424 if (pfork && (!pindexBestForkTip || pindexNewForkTip->
nHeight > pindexBestForkTip->
nHeight) &&
1428 pindexBestForkTip = pindexNewForkTip;
1432 CheckForkWarningConditions();
1435 void static InvalidChainFound(
CBlockIndex* pindexNew)
1437 if (!pindexBestInvalid || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
1438 pindexBestInvalid = pindexNew;
1440 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
1446 LogPrintf(
"%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
1449 CheckForkWarningConditions();
1455 g_failed_blocks.insert(pindex);
1456 setDirtyBlockIndex.insert(pindex);
1457 setBlockIndexCandidates.erase(pindex);
1458 InvalidChainFound(pindex);
1474 AddCoins(inputs, tx, nHeight, blockHash,
false, assetCache, undoAssetData);
1484 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1493 return pindexPrev->
nHeight + 1;
1503 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);
1504 size_t nElems = scriptExecutionCache.
setup_bytes(nMaxCacheSize);
1505 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1506 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1528 pvChecks->reserve(tx.
vin.size());
1539 if (fScriptChecks) {
1548 static_assert(55 -
sizeof(flags) - 32 >= 128/8,
"Want at least 128 bits of nonce for script execution cache");
1551 if (scriptExecutionCache.
contains(hashCacheEntry, !cacheFullScriptStore)) {
1555 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1570 check.swap(pvChecks->back());
1571 }
else if (!check()) {
1572 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
1580 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
1592 return state.
DoS(100,
false, REJECT_INVALID,
strprintf(
"mandatory-script-verify-flag-failed (%s)",
ScriptErrorString(check.GetScriptError())));
1596 if (cacheFullScriptStore && !pvChecks) {
1599 scriptExecutionCache.
insert(hashCacheEntry);
1614 return error(
"%s: OpenUndoFile failed", __func__);
1618 fileout <<
FLATDATA(messageStart) << nSize;
1621 long fileOutPos = ftell(fileout.
Get());
1623 return error(
"%s: ftell failed", __func__);
1624 pos.
nPos = (
unsigned int)fileOutPos;
1625 fileout << blockundo;
1629 hasher << hashBlock;
1630 hasher << blockundo;
1641 return error(
"%s: OpenUndoFile failed", __func__);
1647 verifier << hashBlock;
1648 verifier >> blockundo;
1649 filein >> hashChecksum;
1651 catch (
const std::exception& e) {
1652 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1656 if (hashChecksum != verifier.
GetHash())
1657 return error(
"%s: Checksum mismatch", __func__);
1663 bool AbortNode(
const std::string& strMessage,
const std::string& userMessage=
"")
1668 userMessage.empty() ?
_(
"Error: A fatal internal error occurred, see debug.log for details") : userMessage,
1675 bool AbortNode(
CValidationState& state,
const std::string& strMessage,
const std::string& userMessage=
"")
1677 AbortNode(strMessage, userMessage);
1678 return state.
Error(strMessage);
1704 bool fIsAsset =
false;
1705 if (undo.IsAsset()) {
1711 if (view.
HaveCoin(out)) fClean =
false;
1713 if (undo.nHeight == 0) {
1719 undo.nHeight = alternate.
nHeight;
1729 view.
AddCoin(out, std::move(undo), !fClean);
1733 if (assetCache && fIsAsset) {
1734 if (!assetCache->UndoAssetCoin(tempCoin, out))
1752 error(
"DisconnectBlock(): no undo data available");
1756 error(
"DisconnectBlock(): failure reading undo data");
1760 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1761 error(
"DisconnectBlock(): block and undo data inconsistent");
1765 std::vector<std::pair<std::string, CBlockAssetUndo> > vUndoData;
1767 error(
"DisconnectBlock(): block asset undo data inconsistent");
1771 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
1772 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
1773 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
1777 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1782 std::vector<int> vAssetTxIndex;
1783 std::vector<int> vNullAssetTxIndex;
1785 for (
unsigned int k = tx.
vout.size(); k-- > 0;) {
1813 std::string assetName;
1822 addressIndex.push_back(std::make_pair(
1824 false), assetAmount));
1827 addressUnspentIndex.push_back(
1841 int indexOfRestrictedAssetVerifierString = -1;
1842 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1843 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1846 bool is_spent = view.
SpendCoin(out, &coin, &tempCache);
1855 vAssetTxIndex.emplace_back(o);
1862 if (tx.
vout[o].scriptPubKey.IsNullAsset()) {
1863 if (tx.
vout[o].scriptPubKey.IsNullAssetVerifierTxDataScript()) {
1864 indexOfRestrictedAssetVerifierString = o;
1866 vNullAssetTxIndex.emplace_back(o);
1880 std::string strAddress;
1882 error(
"%s : Failed to get asset from transaction. TXID : %s", __func__, tx.
GetHash().
GetHex());
1885 if (assetsCache->ContainsAsset(asset)) {
1886 if (!assetsCache->RemoveNewAsset(asset, strAddress)) {
1887 error(
"%s : Failed to Remove Asset. Asset Name : %s", __func__, asset.
strName);
1893 std::string ownerName;
1894 std::string ownerAddress;
1896 error(
"%s : Failed to get owner from transaction. TXID : %s", __func__, tx.
GetHash().
GetHex());
1900 if (!assetsCache->RemoveOwnerAsset(ownerName, ownerAddress)) {
1901 error(
"%s : Failed to Remove Owner from transaction. TXID : %s", __func__, tx.
GetHash().
GetHex());
1906 std::string strAddress;
1909 error(
"%s : Failed to get reissue asset from transaction. TXID : %s", __func__,
1914 if (assetsCache->ContainsAsset(reissue.
strName)) {
1915 if (!assetsCache->RemoveReissueAsset(reissue, strAddress,
1918 error(
"%s : Failed to Undo Reissue Asset. Asset Name : %s", __func__, reissue.
strName);
1923 for (
int n = 0; n < (int)tx.
vout.size(); n++) {
1924 auto out = tx.
vout[n];
1926 std::string strAddress;
1930 error(
"%s : Failed to get unique asset from transaction. TXID : %s, vout: %s", __func__,
1935 if (assetsCache->ContainsAsset(asset.
strName)) {
1936 if (!assetsCache->RemoveNewAsset(asset, strAddress)) {
1937 error(
"%s : Failed to Undo Unique Asset. Asset Name : %s", __func__, asset.
strName);
1945 std::string strAddress;
1948 error(
"%s : Failed to get msgchannel asset from transaction. TXID : %s", __func__,
1953 if (assetsCache->ContainsAsset(asset.
strName)) {
1954 if (!assetsCache->RemoveNewAsset(asset, strAddress)) {
1955 error(
"%s : Failed to Undo Msg Channel Asset. Asset Name : %s", __func__, asset.
strName);
1961 std::string strAddress;
1964 error(
"%s : Failed to get qualifier asset from transaction. TXID : %s", __func__,
1969 if (assetsCache->ContainsAsset(asset.
strName)) {
1970 if (!assetsCache->RemoveNewAsset(asset, strAddress)) {
1971 error(
"%s : Failed to Undo Qualifier Asset. Asset Name : %s", __func__, asset.
strName);
1977 std::string strAddress;
1980 error(
"%s : Failed to get restricted asset from transaction. TXID : %s", __func__,
1985 if (assetsCache->ContainsAsset(asset.
strName)) {
1986 if (!assetsCache->RemoveNewAsset(asset, strAddress)) {
1987 error(
"%s : Failed to Undo Restricted Asset. Asset Name : %s", __func__, asset.
strName);
1992 if (indexOfRestrictedAssetVerifierString < 0) {
1993 error(
"%s : Failed to find the restricted asset verifier string index from trasaction. TxID : %s", __func__, tx.
GetHash().
GetHex());
1999 error(
"%s : Failed to get the restricted asset verifier string from trasaction. TxID : %s", __func__, tx.
GetHash().
GetHex());
2004 error(
"%s : Failed to Remove Restricted Verifier from transaction. TXID : %s", __func__, tx.
GetHash().
GetHex());
2009 for (
auto index : vAssetTxIndex) {
2011 std::string strAddress;
2013 error(
"%s : Failed to get transfer asset from transaction. CTxOut : %s", __func__,
2014 tx.
vout[index].ToString());
2019 if (!assetsCache->RemoveTransfer(transfer, strAddress, out)) {
2020 error(
"%s : Failed to Remove the transfer of an asset. Asset Name : %s, COutPoint : %s",
2040 for (
auto index: vNullAssetTxIndex) {
2045 std::string address;
2047 error(
"%s : Failed to get null asset data from transaction. CTxOut : %s", __func__,
2048 tx.
vout[index].ToString());
2058 error(
"%s : Failed to remove qualifier from address, Qualifier : %s, Flag Removing : %d, Address : %s",
2065 error(
"%s : Failed to remove restriction from address, Restriction : %s, Flag Removing : %d, Address : %s",
2072 std::string address;
2074 error(
"%s : Failed to get global null asset data from transaction. CTxOut : %s", __func__,
2075 tx.
vout[index].ToString());
2080 error(
"%s : Failed to remove global restriction from cache. Asset Name: %s, Flag Removing %d", __func__, data.
asset_name, data.
flag);
2097 error(
"DisconnectBlock(): transaction and undo data inconsistent");
2100 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
2103 int res =
ApplyTxInUndo(std::move(undo), view, out, assetsCache);
2142 std::string assetName;
2151 addressIndex.push_back(std::make_pair(
2153 true), assetAmount * -1));
2156 addressUnspentIndex.push_back(std::make_pair(
2178 error(
"Failed to delete address index");
2182 error(
"Failed to write address unspent index");
2190 void static FlushBlockFile(
bool fFinalize =
false)
2192 LOCK(cs_LastBlockFile);
2199 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2204 fileOld = OpenUndoFile(posOld);
2207 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2219 scriptcheckqueue.
Thread();
2228 int32_t nVersion = VERSIONBITS_TOP_BITS;
2232 nVersion = VERSIONBITS_TOP_BITS_ASSETS;
2235 nVersion = VERSIONBITS_TOP_BITS_MESSAGING;
2238 nVersion = VERSIONBITS_TOP_BITS_RESTRICTED;
2268 return ((pindex->
nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
2269 ((pindex->
nVersion >> bit) & 1) != 0 &&
2281 int64_t nBIP16SwitchTime = 1333238400;
2282 bool fStrictPayToScriptHash = (pindex->
GetBlockTime() >= nBIP16SwitchTime);
2312 static int64_t nTimeCheck = 0;
2313 static int64_t nTimeForks = 0;
2314 static int64_t nTimeVerify = 0;
2315 static int64_t nTimeConnect = 0;
2316 static int64_t nTimeIndex = 0;
2317 static int64_t nTimeCallbacks = 0;
2318 static int64_t nTimeTotal = 0;
2319 static int64_t nBlocksTotal = 0;
2325 CCoinsViewCache& view,
const CChainParams& chainparams,
CAssetsCache* assetsCache =
nullptr,
bool fJustCheck =
false,
bool ignoreAddressIndex =
false, std::set<CMessage>* messageCache =
nullptr)
2353 bool fScriptChecks =
true;
2354 if (!hashAssumeValid.
IsNull()) {
2360 BlockMap::const_iterator it =
mapBlockIndex.find(hashAssumeValid);
2362 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
2379 int64_t nTime1 =
GetTimeMicros(); nTimeCheck += nTime1 - nTimeStart;
2421 int nLockTimeFlags = 0;
2429 int64_t nTime2 =
GetTimeMicros(); nTimeForks += nTime2 - nTime1;
2430 LogPrint(
BCLog::BENCH,
" - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks *
MILLI / nBlocksTotal);
2433 std::vector<std::pair<std::string, CBlockAssetUndo> > vUndoAssetData;
2437 std::vector<int> prevheights;
2440 int64_t nSigOpsCost = 0;
2442 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2443 vPos.reserve(block.
vtx.size());
2444 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
2445 std::vector<PrecomputedTransactionData> txdata;
2446 txdata.reserve(block.
vtx.size());
2448 std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
2449 std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
2450 std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
2452 std::set<CMessage> setMessages;
2453 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2458 nInputs += tx.
vin.size();
2468 return state.
DoS(100,
error(
"%s: accumulated fee in the block out of range.", __func__),
2469 REJECT_INVALID,
"bad-txns-accumulated-fee-outofrange");
2474 for (
auto out : tx.
vout)
2475 if (out.scriptPubKey.IsAssetScript())
2476 return state.
DoS(100,
error(
"%s : Received Block with tx that contained an asset when assets wasn't active", __func__), REJECT_INVALID,
"bad-txns-assets-not-active");
2477 else if (out.scriptPubKey.IsNullAsset())
2478 return state.
DoS(100,
error(
"%s : Received Block with tx that contained an null asset data tx when assets wasn't active", __func__), REJECT_INVALID,
"bad-txns-null-data-assets-not-active");
2482 std::vector<std::pair<std::string, uint256>> vReissueAssets;
2494 prevheights.resize(tx.
vin.size());
2495 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2499 if (!
SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
2500 return state.
DoS(100,
error(
"%s: contains a non-BIP68-final transaction", __func__),
2501 REJECT_INVALID,
"bad-txns-nonfinal");
2506 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2511 int addressType = 0;
2512 bool isAsset =
false;
2513 std::string assetName;
2546 addressIndex.push_back(std::make_pair(
CAddressIndexKey(addressType, hashBytes, assetName, pindex->
nHeight, i, txhash, j,
true), assetAmount * -1));
2576 if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST)
2577 return state.
DoS(100,
error(
"ConnectBlock(): too many sigops"),
2578 REJECT_INVALID,
"bad-blk-sigops");
2580 txdata.emplace_back(tx);
2583 std::vector<CScriptCheck> vChecks;
2584 bool fCacheResults = fJustCheck;
2586 return error(
"ConnectBlock(): CheckInputs on %s failed with %s",
2588 control.
Add(vChecks);
2592 for (
unsigned int k = 0; k < tx.
vout.size(); k++) {
2615 addressIndex.push_back(
2618 addressUnspentIndex.push_back(std::make_pair(
CAddressUnspentKey(1, hashBytes, txhash, k),
2624 std::string assetName;
2633 addressIndex.push_back(std::make_pair(
2638 addressUnspentIndex.push_back(
2657 std::pair<std::string, CBlockAssetUndo> undoPair = std::make_pair(
"",
CBlockAssetUndo());
2658 std::pair<std::string, CBlockAssetUndo>* undoAssetData = &undoPair;
2664 if (!undoAssetData->first.empty()) {
2665 vUndoAssetData.emplace_back(*undoAssetData);
2669 vPos.push_back(std::make_pair(tx.
GetHash(), pos));
2672 int64_t nTime3 =
GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
2673 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);
2676 if (block.
vtx[0]->GetValueOut() > blockReward)
2677 return state.
DoS(100,
2678 error(
"ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
2679 block.
vtx[0]->GetValueOut(), blockReward),
2680 REJECT_INVALID,
"bad-cb-amount");
2682 if (!control.
Wait())
2683 return state.
DoS(100,
error(
"%s: CheckQueue failed", __func__), REJECT_INVALID,
"block-validation-failed");
2684 int64_t nTime4 =
GetTimeMicros(); nTimeVerify += nTime4 - nTime2;
2685 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);
2696 return error(
"ConnectBlock(): FindUndoPos failed");
2698 return AbortNode(state,
"Failed to write undo data");
2705 if (vUndoAssetData.size()) {
2707 return AbortNode(state,
"Failed to write asset undo data");
2711 setDirtyBlockIndex.insert(pindex);
2716 return AbortNode(state,
"Failed to write transaction index");
2720 return AbortNode(state,
"Failed to write address index");
2724 return AbortNode(state,
"Failed to write address unspent index");
2730 return AbortNode(state,
"Failed to write transaction index");
2733 unsigned int logicalTS = pindex->
nTime;
2734 unsigned int prevLogicalTS = 0;
2739 LogPrintf(
"%s: Failed to read previous block's logical timestamp\n", __func__);
2741 if (logicalTS <= prevLogicalTS) {
2742 logicalTS = prevLogicalTS + 1;
2743 LogPrintf(
"%s: Previous logical timestamp is newer Actual[%d] prevLogical[%d] Logical[%d]\n", __func__, pindex->
nTime, prevLogicalTS, logicalTS);
2747 return AbortNode(state,
"Failed to write timestamp index");
2750 return AbortNode(state,
"Failed to write blockhash index");
2755 for (
auto message : setMessages) {
2759 message.nBlockHeight = nHeight;
2761 if (message.nExpiredTime == 0 ||
GetTime() < message.nExpiredTime)
2774 int64_t nTime5 =
GetTimeMicros(); nTimeIndex += nTime5 - nTime4;
2775 LogPrint(
BCLog::BENCH,
" - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, nTimeIndex *
MILLI / nBlocksTotal);
2777 int64_t nTime6 =
GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
2778 LogPrint(
BCLog::BENCH,
" - Callbacks: %.2fms [%.2fs (%.2fms/blk)]\n",
MILLI * (nTime6 - nTime5), nTimeCallbacks * MICRO, nTimeCallbacks *
MILLI / nBlocksTotal);
2792 static int64_t nLastWrite = 0;
2793 static int64_t nLastFlush = 0;
2794 static int64_t nLastSetChain = 0;
2795 std::set<int> setFilesToPrune;
2796 bool fFlushForPrune =
false;
2797 bool fDoFullFlush =
false;
2802 LOCK(cs_LastBlockFile);
2804 if (nManualPruneHeight > 0) {
2805 FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight);
2808 fCheckForPruning =
false;
2810 if (!setFilesToPrune.empty()) {
2811 fFlushForPrune =
true;
2813 pblocktree->
WriteFlag(
"prunedblockfiles",
true);
2820 if (nLastWrite == 0) {
2823 if (nLastFlush == 0) {
2826 if (nLastSetChain == 0) {
2827 nLastSetChain = nNow;
2831 int64_t assetDynamicSize = 0;
2832 int64_t assetDirtyCacheSize = 0;
2833 size_t assetMapAmountSize = 0;
2836 if (currentActiveAssetCache) {
2837 assetDynamicSize = currentActiveAssetCache->DynamicMemoryUsage();
2838 assetDirtyCacheSize = currentActiveAssetCache->GetCacheSizeV2();
2839 assetMapAmountSize = currentActiveAssetCache->mapAssetsAddressAmount.size();
2843 int messageCacheSize = 0;
2849 int64_t nMempoolSizeMax =
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
2850 int64_t cacheSize = pcoinsTip->
DynamicMemoryUsage() + assetDynamicSize + assetDirtyCacheSize + messageCacheSize;
2851 int64_t nTotalSpace =
nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
2853 bool fCacheLarge = mode ==
FLUSH_STATE_PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
2855 bool fCacheCritical = mode ==
FLUSH_STATE_IF_NEEDED && (cacheSize > nTotalSpace || assetMapAmountSize > 1000000);
2857 bool fPeriodicWrite = mode ==
FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
2859 bool fPeriodicFlush = mode ==
FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
2862 fDoFullFlush = (mode ==
FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2864 if (!fDoFullFlush &&
IsInitialSyncSpeedUp() && nNow > nLastFlush + (int64_t) DATABASE_FLUSH_INTERVAL_SPEEDY * 1000000) {
2865 LogPrintf(
"Flushing to database sooner for speedy sync\n");
2866 fDoFullFlush =
true;
2870 if (fDoFullFlush || fPeriodicWrite) {
2873 return state.
Error(
"out of disk space");
2878 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2879 vFiles.reserve(setDirtyFileInfo.size());
2880 for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
2881 vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it]));
2882 setDirtyFileInfo.erase(it++);
2884 std::vector<const CBlockIndex*> vBlocks;
2885 vBlocks.reserve(setDirtyBlockIndex.size());
2886 for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
2887 vBlocks.push_back(*it);
2888 setDirtyBlockIndex.erase(it++);
2890 if (!pblocktree->
WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
2891 return AbortNode(state,
"Failed to write to block index database");
2909 return state.
Error(
"out of disk space");
2912 if (!pcoinsTip->
Flush())
2913 return AbortNode(state,
"Failed to write to coin database");
2920 if (currentActiveAssetCache) {
2921 if (!currentActiveAssetCache->DumpCacheToDatabase())
2922 return AbortNode(state,
"Failed to write to asset database");
2933 if (!pmessagedb->
Flush())
2934 return AbortNode(state,
"Failed to Flush the message database");
2937 if (pmessagechanneldb) {
2939 if (!pmessagechanneldb->
Flush())
2940 return AbortNode(state,
"Failed to Flush the message channel database");
2951 nLastSetChain = nNow;
2953 }
catch (
const std::runtime_error& e) {
2954 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2967 fCheckForPruning =
true;
2972 static void DoWarning(
const std::string& strWarning)
2974 static bool fWarned =
false;
2977 AlertNotify(strWarning);
2984 chainActive.
SetTip(pindexNew);
2991 std::vector<std::string> warningMessages;
2996 for (
int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
3000 const std::string strWarning =
strprintf(
_(
"Warning: unknown new rules activated (versionbit %i)"), bit);
3004 DoWarning(strWarning);
3006 warningMessages.push_back(strWarning);
3011 for (
int i = 0; i < 100 && pindex !=
nullptr; i++)
3014 if (pindex->
nVersion > nExpectedVersion)
3016 pindex = pindex->
pprev;
3019 warningMessages.push_back(
strprintf(
_(
"%d of last 100 blocks have unexpected version"), nUpgraded));
3020 if (nUpgraded > 100/2)
3022 std::string strWarning =
_(
"Warning: Unknown block versions being mined! It's possible unknown rules are in effect");
3024 DoWarning(strWarning);
3027 LogPrintf(
"%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)", __func__,
3032 if (!warningMessages.empty())
3033 LogPrintf(
" warning='%s'", boost::algorithm::join(warningMessages,
", "));
3051 assert(pindexDelete);
3053 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
3056 return AbortNode(state,
"Failed to read block");
3064 if (DisconnectBlock(block, pindexDelete, view, &assetCache) !=
DISCONNECT_OK)
3066 bool flushed = view.
Flush();
3069 bool assetsFlushed = assetCache.
Flush();
3070 assert(assetsFlushed);
3077 if (disconnectpool) {
3079 for (
auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
3082 while (disconnectpool->
DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) {
3091 UpdateTip(pindexDelete->
pprev, chainparams);
3098 static int64_t nTimeReadFromDisk = 0;
3099 static int64_t nTimeConnectTotal = 0;
3100 static int64_t nTimeFlush = 0;
3101 static int64_t nTimeAssetFlush = 0;
3102 static int64_t nTimeAssetTasks = 0;
3103 static int64_t nTimeChainState = 0;
3104 static int64_t nTimePostConnect = 0;
3143 assert(!blocksConnected.back().pindex);
3146 blocksConnected.back().pindex = pindex;
3147 blocksConnected.back().pblock = std::move(pblock);
3148 blocksConnected.emplace_back();
3157 assert(!blocksConnected.back().pindex);
3158 assert(blocksConnected.back().conflictedTxs->empty());
3159 blocksConnected.pop_back();
3160 return blocksConnected;
3164 assert(!blocksConnected.back().pindex);
3166 blocksConnected.back().conflictedTxs->emplace_back(std::move(txRemoved));
3179 assert(pindexNew->
pprev == chainActive.
Tip());
3182 std::shared_ptr<const CBlock> pthisBlock;
3184 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
3186 return AbortNode(state,
"Failed to read block");
3187 pthisBlock = pblockNew;
3189 pthisBlock = pblock;
3191 const CBlock& blockConnecting = *pthisBlock;
3193 int64_t nTime2 =
GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3196 int64_t nTimeAssetsFlush;
3215 bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams, &assetCache);
3219 InvalidBlockFound(pindexNew, state);
3223 LogPrint(
BCLog::BENCH,
" - Connect Block only time: %.2fms [%.2fs (%.2fms/blk)]\n", (nTimeConnectDone - nTimeConnectStart) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal);
3232 for (
auto tx : blockConnecting.
vtx) {
3239 int64_t nTimeAssetsEnd =
GetTimeMicros(); nTimeAssetTasks += nTimeAssetsEnd - nTimeAssetsStart;
3240 LogPrint(
BCLog::BENCH,
" - Compute Asset Tasks total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTimeAssetsEnd - nTimeAssetsStart) * MILLI, nTimeAssetsEnd * MICRO, nTimeAssetsEnd * MILLI / nBlocksTotal);
3243 nTime3 =
GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3244 LogPrint(
BCLog::BENCH,
" - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal);
3245 bool flushed = view.
Flush();
3248 LogPrint(
BCLog::BENCH,
" - Flush RVN: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
3252 bool assetFlushed = assetCache.
Flush();
3253 assert(assetFlushed);
3254 int64_t nTimeAssetFlushFinished =
GetTimeMicros(); nTimeAssetFlush += nTimeAssetFlushFinished - nTimeAssetsFlush;
3255 LogPrint(
BCLog::BENCH,
" - Flush Assets: %.2fms [%.2fs (%.2fms/blk)]\n", (nTimeAssetFlushFinished - nTimeAssetsFlush) * MILLI, nTimeAssetFlush * MICRO, nTimeAssetFlush * MILLI / nBlocksTotal);
3262 int64_t nTime5 =
GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3263 LogPrint(
BCLog::BENCH,
" - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
3268 UpdateTip(pindexNew, chainparams);
3270 int64_t nTime6 =
GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3271 LogPrint(
BCLog::BENCH,
" - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
3272 LogPrint(
BCLog::BENCH,
"- Connect block: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime1) * MILLI, nTimeTotal * MICRO, nTimeTotal * MILLI / nBlocksTotal);
3288 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3289 if (it == setBlockIndexCandidates.rend())
3297 bool fInvalidAncestor =
false;
3298 while (pindexTest && !chainActive.
Contains(pindexTest)) {
3307 if (fFailedChain || fMissingData) {
3309 if (fFailedChain && (pindexBestInvalid ==
nullptr || pindexNew->
nChainWork > pindexBestInvalid->nChainWork))
3310 pindexBestInvalid = pindexNew;
3313 while (pindexTest != pindexFailed) {
3316 }
else if (fMissingData) {
3320 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->
pprev, pindexFailed));
3322 setBlockIndexCandidates.erase(pindexFailed);
3323 pindexFailed = pindexFailed->
pprev;
3325 setBlockIndexCandidates.erase(pindexTest);
3326 fInvalidAncestor =
true;
3329 pindexTest = pindexTest->
pprev;
3331 if (!fInvalidAncestor)
3337 static void PruneBlockIndexCandidates() {
3340 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3341 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.
Tip())) {
3342 setBlockIndexCandidates.erase(it++);
3345 assert(!setBlockIndexCandidates.empty());
3359 bool fBlocksDisconnected =
false;
3361 while (chainActive.
Tip() && chainActive.
Tip() != pindexFork) {
3362 if (!DisconnectTip(state, chainparams, &disconnectpool)) {
3368 fBlocksDisconnected =
true;
3372 std::vector<CBlockIndex*> vpindexToConnect;
3373 bool fContinue =
true;
3374 int nHeight = pindexFork ? pindexFork->
nHeight : -1;
3375 while (fContinue && nHeight != pindexMostWork->
nHeight) {
3378 int nTargetHeight = std::min(nHeight + 32, pindexMostWork->
nHeight);
3379 vpindexToConnect.clear();
3380 vpindexToConnect.reserve(nTargetHeight - nHeight);
3382 while (pindexIter && pindexIter->
nHeight != nHeight) {
3383 vpindexToConnect.push_back(pindexIter);
3384 pindexIter = pindexIter->
pprev;
3386 nHeight = nTargetHeight;
3390 if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
3394 InvalidChainFound(vpindexToConnect.back());
3396 fInvalidFound =
true;
3407 PruneBlockIndexCandidates();
3417 if (fBlocksDisconnected) {
3426 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
3428 CheckForkWarningConditions();
3433 static void NotifyHeaderTip() {
3434 bool fNotify =
false;
3435 bool fInitialBlockDownload =
false;
3442 if (pindexHeader != pindexHeaderOld) {
3445 pindexHeaderOld = pindexHeader;
3467 int nStopAtHeight =
gArgs.
GetArg(
"-stopatheight", DEFAULT_STOPATHEIGHT);
3469 boost::this_thread::interruption_point();
3474 bool fInitialDownload;
3480 if (pindexMostWork ==
nullptr) {
3481 pindexMostWork = FindMostWorkChain();
3485 if (pindexMostWork ==
nullptr || pindexMostWork == chainActive.
Tip())
3488 bool fInvalidFound =
false;
3489 std::shared_ptr<const CBlock> nullBlockPtr;
3490 if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
3493 if (fInvalidFound) {
3495 pindexMostWork =
nullptr;
3497 pindexNewTip = chainActive.
Tip();
3498 pindexFork = chainActive.
FindFork(pindexOldTip);
3502 assert(trace.pblock && trace.pindex);
3514 if (pindexFork != pindexNewTip) {
3519 }
while (pindexNewTip != pindexMostWork);
3539 if (chainActive.
Tip()->
nChainWork > nLastPreciousChainwork) {
3541 nBlockReverseSequenceId = -1;
3544 setBlockIndexCandidates.erase(pindex);
3546 if (nBlockReverseSequenceId > std::numeric_limits<int32_t>::min()) {
3549 nBlockReverseSequenceId--;
3552 setBlockIndexCandidates.insert(pindex);
3553 PruneBlockIndexCandidates();
3570 bool pindex_was_in_chain =
false;
3574 while (chainActive.
Contains(pindex)) {
3575 pindex_was_in_chain =
true;
3578 if (!DisconnectTip(state, chainparams, &disconnectpool)) {
3588 while (pindex_was_in_chain && invalid_walk_tip != pindex) {
3590 setDirtyBlockIndex.insert(invalid_walk_tip);
3591 setBlockIndexCandidates.erase(invalid_walk_tip);
3592 invalid_walk_tip = invalid_walk_tip->
pprev;
3597 setDirtyBlockIndex.insert(pindex);
3598 setBlockIndexCandidates.erase(pindex);
3599 g_failed_blocks.insert(pindex);
3609 if (it->second->IsValid(
BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.
Tip())) {
3610 setBlockIndexCandidates.insert(it->second);
3615 InvalidChainFound(pindex);
3623 int nHeight = pindex->
nHeight;
3628 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
3630 setDirtyBlockIndex.insert(it->second);
3631 if (it->second->IsValid(
BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.
Tip(), it->second)) {
3632 setBlockIndexCandidates.insert(it->second);
3634 if (it->second == pindexBestInvalid) {
3636 pindexBestInvalid =
nullptr;
3638 g_failed_blocks.erase(it->second);
3644 while (pindex !=
nullptr) {
3647 setDirtyBlockIndex.insert(pindex);
3649 pindex = pindex->
pprev;
3668 BlockMap::iterator mi =
mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
3673 pindexNew->
pprev = (*miPrev).second;
3681 pindexBestHeader = pindexNew;
3683 setDirtyBlockIndex.insert(pindexNew);
3691 pindexNew->
nTx = block.
vtx.size();
3701 setDirtyBlockIndex.insert(pindexNew);
3705 std::deque<CBlockIndex*> queue;
3706 queue.push_back(pindexNew);
3709 while (!queue.empty()) {
3714 LOCK(cs_nBlockSequenceId);
3717 if (chainActive.
Tip() ==
nullptr || !setBlockIndexCandidates.value_comp()(pindex, chainActive.
Tip())) {
3718 setBlockIndexCandidates.insert(pindex);
3720 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
3721 while (range.first != range.second) {
3722 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3723 queue.push_back(it->second);
3725 mapBlocksUnlinked.erase(it);
3730 mapBlocksUnlinked.insert(std::make_pair(pindexNew->
pprev, pindexNew));
3737 static bool FindBlockPos(
CValidationState &state,
CDiskBlockPos &pos,
unsigned int nAddSize,
unsigned int nHeight, uint64_t nTime,
bool fKnown =
false)
3739 LOCK(cs_LastBlockFile);
3741 unsigned int nFile = fKnown ? pos.
nFile : nLastBlockFile;
3742 if (vinfoBlockFile.size() <= nFile) {
3743 vinfoBlockFile.resize(nFile + 1);
3747 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
3749 if (vinfoBlockFile.size() <= nFile) {
3750 vinfoBlockFile.resize(nFile + 1);
3754 pos.
nPos = vinfoBlockFile[nFile].nSize;
3757 if ((
int)nFile != nLastBlockFile) {
3759 LogPrintf(
"Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
3761 FlushBlockFile(!fKnown);
3762 nLastBlockFile = nFile;
3765 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
3767 vinfoBlockFile[nFile].nSize = std::max(pos.
nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3769 vinfoBlockFile[nFile].nSize += nAddSize;
3772 unsigned int nOldChunks = (pos.
nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3773 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3774 if (nNewChunks > nOldChunks) {
3776 fCheckForPruning =
true;
3780 LogPrintf(
"Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.
nFile);
3786 return state.
Error(
"out of disk space");
3790 setDirtyFileInfo.insert(nFile);
3798 LOCK(cs_LastBlockFile);
3800 unsigned int nNewSize;
3801 pos.
nPos = vinfoBlockFile[nFile].nUndoSize;
3802 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
3803 setDirtyFileInfo.insert(nFile);
3805 unsigned int nOldChunks = (pos.
nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3806 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3807 if (nNewChunks > nOldChunks) {
3809 fCheckForPruning =
true;
3811 FILE *file = OpenUndoFile(pos);
3813 LogPrintf(
"Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.
nFile);
3819 return state.
Error(
"out of disk space");
3829 return state.
DoS(50,
false, REJECT_INVALID,
"high-hash",
false,
"proof of work failed");
3842 if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW))
3846 if (fCheckMerkleRoot) {
3850 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txnmrklroot",
true,
"hashMerkleRoot mismatch");
3856 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-duplicate",
true,
"duplicate transaction");
3867 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-length",
false,
"size limits failed");
3870 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3871 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-missing",
false,
"first tx is not coinbase");
3873 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3874 if (block.
vtx[i]->IsCoinBase())
3875 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-multiple",
false,
"more than one coinbase");
3878 for (
const auto& tx : block.
vtx)
3883 unsigned int nSigOps = 0;
3884 for (
const auto& tx : block.
vtx)
3888 if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST)
3889 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-sigops",
false,
"out-of-bounds SigOpCount");
3891 if (fCheckPOW && fCheckMerkleRoot)
3907 static int GetWitnessCommitmentIndex(
const CBlock& block)
3910 if (!block.
vtx.empty()) {
3911 for (
size_t o = 0; o < block.
vtx[0]->vout.size(); o++) {
3912 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] == 0xaa && block.
vtx[0]->vout[o].scriptPubKey[3] == 0x21 && block.
vtx[0]->vout[o].scriptPubKey[4] == 0xa9 && block.
vtx[0]->vout[o].scriptPubKey[5] == 0xed) {
3922 int commitpos = GetWitnessCommitmentIndex(block);
3923 static const std::vector<unsigned char> nonce(32, 0x00);
3924 if (commitpos != -1 &&
IsWitnessEnabled(pindexPrev, consensusParams) && !block.
vtx[0]->HasWitness()) {
3926 tx.
vin[0].scriptWitness.stack.resize(1);
3927 tx.
vin[0].scriptWitness.stack[0] = nonce;
3928 block.
vtx[0] = MakeTransactionRef(std::move(tx));
3934 std::vector<unsigned char> commitment;
3935 int commitpos = GetWitnessCommitmentIndex(block);
3936 std::vector<unsigned char> ret(32, 0x00);
3938 if (commitpos == -1) {
3953 tx.vout.push_back(out);
3954 block.
vtx[0] = MakeTransactionRef(std::move(tx));
3966 assert(pindexPrev !=
nullptr);
3967 const int nHeight = pindexPrev->
nHeight + 1;
3970 int nMaxReorgDepth =
gArgs.
GetArg(
"-maxreorg",
Params().MaxReorganizationDepth());
3971 int nMinReorgPeers =
gArgs.
GetArg(
"-minreorgpeers",
Params().MinReorganizationPeers());
3972 int nMinReorgAge =
gArgs.
GetArg(
"-minreorgage",
Params().MinReorganizationAge());
3973 bool fGreaterThanMaxReorg = (chainActive.
Height() - (nHeight - 1)) >= nMaxReorgDepth;
3974 if (fGreaterThanMaxReorg &&
g_connman) {
3976 bool bIsCurrentChainCaughtUp = (
GetTime() - chainActive.
Tip()->
nTime) <= nMinReorgAge;
3977 if ((nCurrentNodeCount >= nMinReorgPeers) && bIsCurrentChainCaughtUp)
3978 return state.
DoS(10,
3979 error(
"%s: forked chain older than max reorganization depth (height %d), with connections (count %d), and caught up with active chain (%s)",
3980 __func__, nHeight, nCurrentNodeCount, bIsCurrentChainCaughtUp ?
"true" :
"false"),
3981 REJECT_MAXREORGDEPTH,
"bad-fork-prior-to-maxreorgdepth");
3987 return state.
DoS(100,
false, REJECT_INVALID,
"bad-diffbits",
false,
"incorrect proof of work");
3995 if (pcheckpoint && nHeight < pcheckpoint->nHeight)
3996 return state.
DoS(100,
error(
"%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT,
"bad-fork-prior-to-checkpoint");
4001 return state.
Invalid(
false, REJECT_INVALID,
"time-too-old",
"block's timestamp is too early");
4006 if (block.
GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME_DGW)
4007 return state.
Invalid(
false, REJECT_INVALID,
"time-too-new",
"block timestamp too far in the future");
4011 if (block.
GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
4012 return state.
Invalid(
false, REJECT_INVALID,
"time-too-new",
"block timestamp too far in the future");
4029 if (block.
nVersion < VERSIONBITS_TOP_BITS_MESSAGING) {
4036 if (block.
nVersion < VERSIONBITS_TOP_BITS_RESTRICTED) {
4047 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
4050 int nLockTimeFlags = 0;
4060 for (
const auto& tx : block.
vtx) {
4061 if (!
IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
4062 return state.
DoS(10,
false, REJECT_INVALID,
"bad-txns-nonfinal",
false,
"non-final transaction");
4071 if (block.
vtx[0]->vin[0].scriptSig.size() < expect.
size() ||
4072 !std::equal(expect.
begin(), expect.
end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
4073 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-height",
false,
"block height mismatch in coinbase");
4084 bool fHaveWitness =
false;
4086 int commitpos = GetWitnessCommitmentIndex(block);
4087 if (commitpos != -1) {
4088 bool malleated =
false;
4093 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
4094 return state.
DoS(100,
false, REJECT_INVALID,
"bad-witness-nonce-size",
true,
strprintf(
"%s : invalid witness nonce size", __func__));
4097 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
4098 return state.
DoS(100,
false, REJECT_INVALID,
"bad-witness-merkle-match",
true,
strprintf(
"%s : witness merkle commitment mismatch", __func__));
4100 fHaveWitness =
true;
4104 if (!fHaveWitness) {
4105 for (
const auto& tx : block.
vtx) {
4107 return state.
DoS(100,
false, REJECT_INVALID,
"unexpected-witness",
true,
strprintf(
"%s : unexpected witness data found", __func__));
4119 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-weight",
false,
strprintf(
"%s : weight limit failed", __func__));
4136 pindex = miSelf->second;
4140 return state.
Invalid(
error(
"%s: block %s is marked invalid", __func__, hash.
ToString()), 0,
"duplicate");
4144 if (!CheckBlockHeader(block, state, chainparams.
GetConsensus()))
4151 return state.
DoS(10,
error(
"%s: prev block not found", __func__), 0,
"prev-blk-not-found");
4152 pindexPrev = (*mi).second;
4154 return state.
DoS(100,
error(
"%s: prev block invalid", __func__), REJECT_INVALID,
"bad-prevblk");
4155 if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev,
GetAdjustedTime()))
4159 for (
const CBlockIndex* failedit : g_failed_blocks) {
4160 if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) {
4163 while (invalid_walk != failedit) {
4165 setDirtyBlockIndex.insert(invalid_walk);
4166 invalid_walk = invalid_walk->
pprev;
4168 return state.
DoS(100,
error(
"%s: prev block invalid", __func__), REJECT_INVALID,
"bad-prevblk");
4173 if (pindex ==
nullptr)
4174 pindex = AddToBlockIndex(block);
4187 if (first_invalid !=
nullptr) first_invalid->
SetNull();
4192 if (!AcceptBlockHeader(header, state, chainparams, &pindex)) {
4193 if (first_invalid) *first_invalid = header;
4208 const CBlock& block = *pblock;
4210 if (fNewBlock) *fNewBlock =
false;
4214 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
4216 if (!AcceptBlockHeader(block, state, chainparams, &pindex))
4229 bool fTooFarAhead = (pindex->
nHeight > int(chainActive.
Height() + MIN_BLOCKS_TO_KEEP));
4237 if (fAlreadyHave)
return true;
4239 if (pindex->
nTx != 0)
return true;
4240 if (!fHasMoreWork)
return true;
4241 if (fTooFarAhead)
return true;
4247 if (pindex->
nChainWork < nMinimumChainWork)
return true;
4250 if (fNewBlock) *fNewBlock =
true;
4255 !ContextualCheckBlock(block, state, chainparams.
GetConsensus(), pindex->
pprev, currentActiveAssetCache)) {
4258 setDirtyBlockIndex.insert(pindex);
4268 int nHeight = pindex->
nHeight;
4276 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.
GetBlockTime(), dbp !=
nullptr))
4277 return error(
"AcceptBlock(): FindBlockPos failed");
4279 if (!WriteBlockToDisk(block, blockPos, chainparams.
MessageStart()))
4280 AbortNode(state,
"Failed to write block");
4281 if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.
GetConsensus()))
4282 return error(
"AcceptBlock(): ReceivedBlockTransactions failed");
4283 }
catch (
const std::runtime_error& e) {
4284 return AbortNode(state, std::string(
"System error: ") + e.what());
4287 if (fCheckForPruning)
4297 if (fNewBlock) *fNewBlock =
false;
4308 ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing,
nullptr, fNewBlock);
4321 return error(
"%s: ActivateBestChain failed", __func__);
4329 assert(pindexPrev && pindexPrev == chainActive.
Tip());
4332 indexDummy.
pprev = pindexPrev;
4340 if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev,
GetAdjustedTime()))
4344 if (!ContextualCheckBlock(block, state, chainparams.
GetConsensus(), pindexPrev, &assetCache))
4346 if (!ConnectBlock(block, state, &indexDummy, viewNew, chainparams, &assetCache,
true))
4360 LOCK(cs_LastBlockFile);
4362 uint64_t retval = 0;
4364 retval += file.nSize + file.nUndoSize;
4372 LOCK(cs_LastBlockFile);
4376 if (pindex->
nFile == fileNumber) {
4382 setDirtyBlockIndex.insert(pindex);
4388 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->
pprev);
4389 while (range.first != range.second) {
4390 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
4392 if (_it->second == pindex) {
4393 mapBlocksUnlinked.erase(_it);
4399 vinfoBlockFile[fileNumber].SetNull();
4400 setDirtyFileInfo.insert(fileNumber);
4406 for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
4410 LogPrintf(
"Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
4415 static void FindFilesToPruneManual(std::set<int>& setFilesToPrune,
int nManualPruneHeight)
4417 assert(
fPruneMode && nManualPruneHeight > 0);
4419 LOCK2(cs_main, cs_LastBlockFile);
4420 if (chainActive.
Tip() ==
nullptr)
4424 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight, chainActive.
Tip()->
nHeight - MIN_BLOCKS_TO_KEEP);
4426 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4427 if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
4430 setFilesToPrune.insert(fileNumber);
4433 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune, count);
4459 static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight)
4461 LOCK2(cs_main, cs_LastBlockFile);
4465 if ((uint64_t)chainActive.
Tip()->
nHeight <= nPruneAfterHeight) {
4469 unsigned int nLastBlockWeCanPrune = chainActive.
Tip()->
nHeight - MIN_BLOCKS_TO_KEEP;
4474 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
4475 uint64_t nBytesToPrune;
4479 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4480 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
4482 if (vinfoBlockFile[fileNumber].nSize == 0)
4489 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
4494 setFilesToPrune.insert(fileNumber);
4495 nCurrentUsage -= nBytesToPrune;
4500 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
4502 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4503 nLastBlockWeCanPrune, count);
4508 uint64_t nFreeBytesAvailable = fs::space(
GetDataDir()).available;
4511 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
4512 return AbortNode(
"Disk space is low!",
_(
"Error: Disk space is low!"));
4522 fs::create_directories(path.parent_path());
4524 if (!file && !fReadOnly)
4527 LogPrintf(
"Unable to open file %s\n", path.string());
4531 if (fseek(file, pos.
nPos, SEEK_SET)) {
4532 LogPrintf(
"Unable to seek to position %u of %s\n", pos.
nPos, path.string());
4541 return OpenDiskFile(pos,
"blk", fReadOnly);
4545 static FILE* OpenUndoFile(
const CDiskBlockPos &pos,
bool fReadOnly) {
4546 return OpenDiskFile(pos,
"rev", fReadOnly);
4562 return (*mi).second;
4566 mi =
mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
4572 bool static LoadBlockIndexDB(
const CChainParams& chainparams)
4577 boost::this_thread::interruption_point();
4580 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
4582 for (
const std::pair<uint256, CBlockIndex*>& item :
mapBlockIndex)
4585 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
4587 sort(vSortedByHeight.begin(), vSortedByHeight.end());
4588 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
4595 if (pindex->
nTx > 0) {
4596 if (pindex->
pprev) {
4601 mapBlocksUnlinked.insert(std::make_pair(pindex->
pprev, pindex));
4609 setDirtyBlockIndex.insert(pindex);
4612 setBlockIndexCandidates.insert(pindex);
4614 pindexBestInvalid = pindex;
4618 pindexBestHeader = pindex;
4623 vinfoBlockFile.resize(nLastBlockFile + 1);
4624 LogPrintf(
"%s: last block file = %i\n", __func__, nLastBlockFile);
4625 for (
int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4628 LogPrintf(
"%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
4629 for (
int nFile = nLastBlockFile + 1;
true; nFile++) {
4632 vinfoBlockFile.push_back(info);
4639 LogPrintf(
"Checking all blk files are present...\n");
4640 std::set<int> setBlkDataFiles;
4641 for (
const std::pair<uint256, CBlockIndex*>& item : mapBlockIndex)
4645 setBlkDataFiles.insert(pindex->
nFile);
4648 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
4659 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
4662 bool fReindexing =
false;
4668 LogPrintf(
"%s: transaction index %s\n", __func__,
fTxIndex ?
"enabled" :
"disabled");
4694 LogPrintf(
"%s: Connecting genesis block...\n", __func__);
4705 chainActive.
SetTip(it->second);
4707 PruneBlockIndexCandidates();
4709 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4729 if (chainActive.
Tip() ==
nullptr || chainActive.
Tip()->
pprev ==
nullptr)
4733 if (nCheckDepth <= 0 || nCheckDepth > chainActive.
Height())
4734 nCheckDepth = chainActive.
Height();
4735 nCheckLevel = std::max(0, std::min(4, nCheckLevel));
4736 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4740 int nGoodTransactions = 0;
4749 boost::this_thread::interruption_point();
4750 int percentageDone = std::max(1, std::min(99, (
int)(((
double)(chainActive.
Height() - pindex->
nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
4751 if (reportDone < percentageDone/10) {
4754 reportDone = percentageDone/10;
4761 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
4770 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
4773 if (nCheckLevel >= 2 && pindex) {
4784 DisconnectResult res = DisconnectBlock(block, pindex, coins, &assetCache,
true,
false);
4788 pindexState = pindex->
pprev;
4790 nGoodTransactions = 0;
4791 pindexFailure = pindex;
4793 nGoodTransactions += block.
vtx.size();
4800 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
4803 if (nCheckLevel >= 4) {
4805 while (pindex != chainActive.
Tip()) {
4806 boost::this_thread::interruption_point();
4808 pindex = chainActive.
Next(pindex);
4812 if (!ConnectBlock(block, state, pindex, coins, chainparams, &assetCache,
false,
true))
4818 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.
Height() - pindexState->
nHeight, nGoodTransactions);
4833 if (!tx->IsCoinBase()) {
4834 for (
const CTxIn &txin : tx->vin) {
4853 if (hashHeads.empty())
return true;
4854 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4864 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4868 if (!hashHeads[1].IsNull()) {
4870 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4874 assert(pindexFork !=
nullptr);
4878 while (pindexOld != pindexFork) {
4885 DisconnectResult res = DisconnectBlock(block, pindexOld, cache, &assetsCache);
4894 pindexOld = pindexOld->
pprev;
4898 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4899 for (
int nHeight = nForkHeight + 1; nHeight <= pindexNew->
nHeight; ++nHeight) {
4902 if (!RollforwardBlock(pindex, cache, params))
return false;
4907 assetsCache.
Flush();
4919 while (nHeight <= chainActive.
Height()) {
4929 while (chainActive.
Height() >= nHeight) {
4938 if (!DisconnectTip(state, params,
nullptr)) {
4939 return error(
"RewindBlockIndex: unable to disconnect block at height %i", pindex->
nHeight);
4963 pindexIter->
nFile = 0;
4967 pindexIter->
nTx = 0;
4971 setDirtyBlockIndex.insert(pindexIter);
4973 setBlockIndexCandidates.erase(pindexIter);
4974 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> ret = mapBlocksUnlinked.equal_range(pindexIter->
pprev);
4975 while (ret.first != ret.second) {
4976 if (ret.first->second == pindexIter) {
4977 mapBlocksUnlinked.erase(ret.first++);
4983 setBlockIndexCandidates.insert(pindexIter);
4987 if (chainActive.
Tip() !=
nullptr) {
4990 PruneBlockIndexCandidates();
5011 setBlockIndexCandidates.clear();
5012 chainActive.
SetTip(
nullptr);
5013 pindexBestInvalid =
nullptr;
5014 pindexBestHeader =
nullptr;
5016 mapBlocksUnlinked.clear();
5017 vinfoBlockFile.clear();
5019 nBlockSequenceId = 1;
5020 setDirtyBlockIndex.clear();
5021 g_failed_blocks.clear();
5022 setDirtyFileInfo.clear();
5023 versionbitscache.
Clear();
5024 for (
int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
5025 warningcache[b].clear();
5029 delete entry.second;
5031 mapBlockIndex.clear();
5040 bool ret = LoadBlockIndexDB(chainparams);
5041 if (!ret)
return false;
5052 LogPrintf(
"Initializing databases...\n");
5057 LogPrintf(
"%s: transaction index %s\n", __func__,
fTxIndex ?
"enabled" :
"disabled");
5100 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.
GetBlockTime()))
5101 return error(
"%s: FindBlockPos failed", __func__);
5102 if (!WriteBlockToDisk(block, blockPos, chainparams.
MessageStart()))
5103 return error(
"%s: writing genesis block to disk failed", __func__);
5105 if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.
GetConsensus()))
5106 return error(
"%s: genesis block not accepted", __func__);
5107 }
catch (
const std::runtime_error& e) {
5108 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
5117 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5124 uint64_t nRewind = blkdat.
GetPos();
5125 while (!blkdat.
eof()) {
5126 boost::this_thread::interruption_point();
5131 unsigned int nSize = 0;
5136 nRewind = blkdat.
GetPos()+1;
5144 }
catch (
const std::exception&) {
5150 uint64_t nBlockPos = blkdat.
GetPos();
5152 dbp->
nPos = nBlockPos;
5153 blkdat.
SetLimit(nBlockPos + nSize);
5154 blkdat.
SetPos(nBlockPos);
5155 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
5158 nRewind = blkdat.
GetPos();
5161 uint256 hash = block.GetHash();
5164 block.hashPrevBlock.ToString());
5166 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5174 if (AcceptBlock(pblock, state, chainparams,
nullptr,
true, dbp,
nullptr)) {
5194 std::deque<uint256> queue;
5195 queue.push_back(hash);
5196 while (!queue.empty()) {
5199 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5200 while (range.first != range.second) {
5201 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5202 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
5205 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
5209 if (AcceptBlock(pblockrecursive, dummy, chainparams,
nullptr,
true, &it->second,
nullptr))
5212 queue.push_back(pblockrecursive->GetHash());
5216 mapBlocksUnknownParent.erase(it);
5220 }
catch (
const std::exception& e) {
5221 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
5224 }
catch (
const std::runtime_error& e) {
5225 AbortNode(std::string(
"System error: ") + e.what());
5243 if (chainActive.
Height() < 0) {
5249 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5251 forward.insert(std::make_pair(it->second->pprev, it->second));
5256 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
5258 rangeGenesis.first++;
5259 assert(rangeGenesis.first == rangeGenesis.second);
5270 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
5272 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
5273 while (pindex !=
nullptr) {
5277 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
5284 if (pindex->
pprev ==
nullptr) {
5287 assert(pindex == chainActive.
Genesis());
5295 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5303 assert((pindexFirstNeverProcessed !=
nullptr) == (pindex->
nChainTx == 0));
5304 assert((pindexFirstNotTransactionsValid !=
nullptr) == (pindex->
nChainTx == 0));
5305 assert(pindex->
nHeight == nHeight);
5308 assert(pindexFirstNotTreeValid ==
nullptr);
5312 if (pindexFirstInvalid ==
nullptr) {
5316 if (!CBlockIndexWorkComparator()(pindex, chainActive.
Tip()) && pindexFirstNeverProcessed ==
nullptr) {
5317 if (pindexFirstInvalid ==
nullptr) {
5322 if (pindexFirstMissing ==
nullptr || pindex == chainActive.
Tip()) {
5323 assert(setBlockIndexCandidates.count(pindex));
5330 assert(setBlockIndexCandidates.count(pindex) == 0);
5333 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->
pprev);
5334 bool foundInUnlinked =
false;
5335 while (rangeUnlinked.first != rangeUnlinked.second) {
5336 assert(rangeUnlinked.first->first == pindex->
pprev);
5337 if (rangeUnlinked.first->second == pindex) {
5338 foundInUnlinked =
true;
5341 rangeUnlinked.first++;
5343 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
5345 assert(foundInUnlinked);
5348 if (pindexFirstMissing ==
nullptr) assert(!foundInUnlinked);
5349 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
5360 if (!CBlockIndexWorkComparator()(pindex, chainActive.
Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5361 if (pindexFirstInvalid ==
nullptr) {
5362 assert(foundInUnlinked);
5370 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5371 if (range.first != range.second) {
5373 pindex = range.first->second;
5382 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
5383 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
5384 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
5385 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
5386 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
5387 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
5388 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
5392 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
5393 while (rangePar.first->second != pindex) {
5394 assert(rangePar.first != rangePar.second);
5399 if (rangePar.first != rangePar.second) {
5401 pindex = rangePar.first->second;
5413 assert(nNodes == forward.size());
5418 return strprintf(
"CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast,
DateTimeStrFormat(
"%Y-%m-%d", nTimeFirst),
DateTimeStrFormat(
"%Y-%m-%d", nTimeLast));
5423 LOCK(cs_LastBlockFile);
5425 return &vinfoBlockFile.at(n);
5446 static const uint64_t MEMPOOL_DUMP_VERSION = 1;
5451 int64_t nExpiryTimeout =
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
5455 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
5460 int64_t expired = 0;
5462 int64_t already_there = 0;
5468 if (version != MEMPOOL_DUMP_VERSION) {
5481 CAmount amountdelta = nFeeDelta;
5486 if (nTime + nExpiryTimeout > nNow) {
5488 AcceptToMemoryPoolWithTime(chainparams,
mempool, state, tx,
nullptr , nTime,
5489 nullptr ,
false , 0 );
5509 std::map<uint256, CAmount> mapDeltas;
5512 for (
const auto& i : mapDeltas) {
5515 }
catch (
const std::exception& e) {
5516 LogPrintf(
"Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
5520 LogPrintf(
"Imported mempool transactions from disk: %i succeeded, %i failed, %i expired, %i already there\n", count, failed, expired, already_there);
5528 std::map<uint256, CAmount> mapDeltas;
5529 std::vector<TxMempoolInfo> vinfo;
5534 mapDeltas[i.first] = i.second;
5549 uint64_t version = MEMPOOL_DUMP_VERSION;
5552 file << (uint64_t)vinfo.size();
5553 for (
const auto& i : vinfo) {
5555 file << (int64_t)i.nTime;
5556 file << (int64_t)i.nFeeDelta;
5557 mapDeltas.erase(i.tx->GetHash());
5565 LogPrintf(
"Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*
MICRO, (last-mid)*MICRO);
5566 }
catch (
const std::exception& e) {
5567 LogPrintf(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
5575 if (pindex ==
nullptr)
5578 int64_t nNow = time(
nullptr);
5588 return pindex->
nChainTx / fTxTotal;
5594 if (fAssetsIsActive)
5599 fAssetsIsActive =
true;
5601 return fAssetsIsActive;
5606 if (fMessagesIsActive)
5611 fMessagesIsActive =
true;
5613 return fMessagesIsActive;
5618 if (fRestrictedAssetsIsActive)
5623 fRestrictedAssetsIsActive =
true;
5625 return fRestrictedAssetsIsActive;
5633 if (
Params().MessagingActivationBlock()) {
5642 if (
Params().RestrictedActivationBlock()) {
5663 delete (*it1).second;
bool QualifierAssetFromTransaction(const CTransaction &tx, CNewAsset &asset, std::string &strAddress)
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 ...
std::set< CAssetCacheRestrictedVerifiers > setNewRestrictedVerifierToAdd
Restricted Assets Verifier Caches.
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
bool ReadTimestampBlockIndex(const uint256 &hash, unsigned int &logicalTS)
CSHA256 & Write(const unsigned char *data, size_t len)
CDiskBlockPos GetBlockPos() const
int Expire(int64_t time)
Expire all transaction (and their dependencies) in the mempool older than time.
std::vector< Coin > vprevout
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 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
void addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view)
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
boost::condition_variable CConditionVariable
Just a typedef for boost::condition_variable, can be wrapped later if desired.
bool DumpMempool(void)
Dump the mempool to disk.
bool WriteReissuedMempoolState()
bool GetAddressIndex(uint160 addressHash, int type, std::string assetName, std::vector< std::pair< CAddressIndexKey, CAmount > > &addressIndex, int start, int end)
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...
std::set< CAssetCacheRestrictedAddress > setNewRestrictedAddressToAdd
Restricted Address Asset Caches.
void UnloadBlockIndex()
Unload database information.
bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector< std::pair< uint256, unsigned int > > &hashes)
uint256 GetWitnessHash() const
void Add(std::vector< T > &vChecks)
int64_t GetBlockTime() const
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...
descends from failed block
CBlockIndex * pprev
pointer to the index of the predecessor of this block
std::vector< TxMempoolInfo > infoAll() const
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr, CAssetsCache *assetsCache=nullptr)
Spend a coin.
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
std::map< uint256, std::set< std::string > > mapHashQualifiersChanged
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 FileCommit(FILE *file)
bool IsNewRestrictedAsset() const
Make sure to call VerifyNewAsset if this call returns true.
void SetBackend(CCoinsView &viewIn)
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out, CAssetsCache *assetCache=nullptr)
Restore the UTXO in a Coin at a given COutPoint.
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...
CLRUCache< std::string, int8_t > * passetsQualifierCache
Global variable that points to the asset address qualifier LRU Cache (protected by cs_main) ...
bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, const bool fActiveOnly, std::vector< std::pair< uint256, unsigned int > > &vect)
CBlockIndex * pindexBestForkBase
int64_t BeginTime(const Consensus::Params ¶ms) const override
bool LoadGenesisBlock(const CChainParams &chainparams)
Ensures we have a genesis block in the block tree, possibly writing one to disk.
bool WriteBlockUndoAssetData(const uint256 &blockhash, const std::vector< std::pair< std::string, CBlockAssetUndo > > &assetUndoData)
bool IsPayToScriptHash() const
unsigned int MessagingActivationBlock() const
unsigned int GetMaxBlockWeight()
An in-memory indexed chain of blocks.
bool VerifyDB(const CChainParams &chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
bool InvalidateBlock(CValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex)
Mark a block as invalid.
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
size_t DynamicMemoryUsage() const
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
bool fHavePruned
Pruning-related variables and constants.
unsigned int RestrictedActivationBlock() const
std::atomic_bool fReindex(false)
reverse_range< T > reverse_iterate(T &x)
CHash256 & Write(const unsigned char *data, size_t len)
CRestrictedDB * prestricteddb
Global variable that points to the active restricted asset database (protected by cs_main) ...
int Period(const Consensus::Params ¶ms) const override
bool ReadLastBlockFile(int &nFile)
CWaitableCriticalSection csBestBlock
size_t GetMessageDirtyCacheSize()
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
bool ReadBlockUndoAssetData(const uint256 &blockhash, std::vector< std::pair< std::string, CBlockAssetUndo > > &assetUndoData)
bool AssetFromScript(const CScript &scriptPubKey, CNewAsset &assetNew, std::string &strAddress)
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool MoneyRange(const CAmount &nValue)
bool TransferAssetFromScript(const CScript &scriptPubKey, CAssetTransfer &assetTransfer, std::string &strAddress)
Get specific asset type metadata from the given scripts.
std::map< uint256, std::set< std::string > > mapHashVerifierChanged
std::map< uint256, std::set< std::string > > mapHashMarkedGlobalFrozen
int Height() const
Return the maximal height in the chain.
CMessageChannelDB * pmessagechanneldb
Global variable that points to the message channel database (protected by cs_main) ...
CCriticalSection cs_main
Global state.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
CTxOut out
unspent transaction output
void NewAssetMessage(const CMessage &)
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
bool WriteTimestampBlockIndex(const CTimestampBlockIndexKey &blockhashIndex, const CTimestampBlockIndexValue &logicalts)
bool Flush()
Flush all new cache entries into the passets global cache.
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
bool AssetFromTransaction(const CTransaction &tx, CNewAsset &asset, std::string &strAddress)
These types of asset tx, have specific metadata at certain indexes in the transaction.
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
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...
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
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...
CChainParams defines various tweakable parameters of a given instance of the Raven system...
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
bool contains(const Element &e, const bool erase) const
undo data available in rev*.dat
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool AssetNullDataFromScript(const CScript &scriptPubKey, CNullAssetTxData &assetData, std::string &strAddress)
A hasher class for Raven's 256-bit hash (double SHA-256).
std::string ToString() const
void Thread()
Worker thread.
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...
void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool)
uint160 Hash160(const T1 pbegin, const T1 pend)
Compute the 160-bit hash an object.
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.
CAssetsDB * passetsdb
RVN START.
bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
bool IsNewQualifierAsset() const
Make sure to call VerifyNewQualifierAsset if this call returns true.
const CCheckpointData & Checkpoints() const
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
void RenameThread(const char *name)
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight, ConnectedBlockAssetData &connectedBlockData)
Called when a block is connected.
Reads data from an underlying stream, while hashing the read data.
double GuessVerificationProgress(const ChainTxData &data, CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index.
CLRUCache< std::string, int > * pMessageSubscribedChannelsCache
Global variable that points to the subscribed channel LRU Cache (protected by cs_main) ...
const std::string strMessageMagic
bool IsNewAsset() const
RVN START.
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
bool GetAddressUnspent(uint160 addressHash, int type, std::string assetName, std::vector< std::pair< CAddressUnspentKey, CAddressUnspentValue > > &unspentOutputs)
bool IsRestrictedActive(unsigned int nBlockNumber)
bool ActivateBestChain(CValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Make the best chain active, in multiple steps.
indirectmap< COutPoint, const CTransaction * > mapNextTx
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...
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate)
When adding transactions from a disconnected block back to the mempool, new mempool entries may have ...
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &headers, CValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex, CBlockHeader *first_invalid)
Process incoming block headers.
bool ReadReindexing(bool &fReindexing)
CLRUCache< std::string, int8_t > * passetsRestrictionCache
Global variable that points to the asset address restriction LRU Cache (protected by cs_main) ...
bool IsMessagingActive(unsigned int nBlockNumber)
bool GetAssetData(const CScript &script, CAssetOutputEntry &data)
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
indexed_transaction_set mapTx
const char * ScriptErrorString(const ScriptError serror)
bool IsAssetNameAnMsgChannel(const std::string &name)
Check if an asset is a message channel.
bool nBIP34Enabled
Block height and hash at which BIP34 becomes active.
void Finalize(unsigned char hash[OUTPUT_SIZE])
int64_t CAmount
Amount in corbies (Can be negative)
void SetBestBlock(const uint256 &hashBlock)
uint256 GetBlockHash() const
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check transaction inputs to mitigate two potential denial-of-service attacks:
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyBlockTip
New block has been accepted.
CLRUCache< std::string, CMessage > * pMessagesCache
Global variable that points to the subscribed channel LRU Cache (protected by cs_main) ...
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyHeaderTip
Best header has changed.
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 ...
bool OwnerFromTransaction(const CTransaction &tx, std::string &ownerName, std::string &strAddress)
Removed in size limiting.
indexed_disconnected_transactions queuedTx
bool SetLimit(uint64_t nPos=(uint64_t)(-1))
bool CheckDiskSpace(uint64_t nAdditionalBytes)
Check whether enough disk space is available for an incoming block.
bool AreMessagingDeployed()
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
uint64_t PruneAfterHeight() const
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
bool IsPayToPublicKey() const
RVN END.
void SetCorruptionPossible()
void SetfLargeWorkInvalidChainFound(bool flag)
bool GlobalAssetNullDataFromScript(const CScript &scriptPubKey, CNullAssetTxData &assetData)
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
bool IsAssetNameValid(const std::string &name, AssetType &assetType, std::string &error)
bool ReplayBlocks(const CChainParams ¶ms, CCoinsView *view)
Replay blocks that aren't fully applied to the database.
bool EraseAddressIndex(const std::vector< std::pair< CAddressIndexKey, CAmount > > &vect)
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
bool ReadAddressUnspentIndex(uint160 addressHash, int type, std::string assetName, std::vector< std::pair< CAddressUnspentKey, CAddressUnspentValue > > &vect)
bool TruncateFile(FILE *file, unsigned int length)
bool UpdateAddressUnspentIndex(const std::vector< std::pair< CAddressUnspentKey, CAddressUnspentValue > > &vect)
bool IsInitialSyncSpeedUp()
std::map< uint256, std::string > mapHashToAsset
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.
CLRUCache< std::string, CNullAssetTxVerifierString > * passetsVerifierCache
Global variable that points to the asset verifier LRU Cache (protected by cs_main) ...
bool AreAssetsDeployed()
RVN START.
int GetSpendHeight(const CCoinsViewCache &inputs)
RVN END.
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Access to the block database (blocks/index/)
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, const CAmount nAbsurdFee)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
UniValue transfer(const JSONRPCRequest &request)
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.
CAssetsCache * GetCurrentAssetCache()
void removeForBlock(const std::vector< CTransactionRef > &vtx)
An input of a transaction.
bool MsgChannelAssetFromTransaction(const CTransaction &tx, CNewAsset &asset, std::string &strAddress)
ConnectTrace(CTxMemPool &_pool)
int VersionBitsStateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex, const std::vector< CTransactionRef > &)
bool CheckBlock(const CBlock &block, CValidationState &state, const Consensus::Params &consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
Functions for validating blocks and updating the block tree.
We want to be able to estimate feerates that are needed on tx's to be included in a certain number of...
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...
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
const uint256 & GetHash() const
CMessageDB * pmessagedb
Global variable that points to the messages database (protected by cs_main)
bool IsDGWActive(unsigned int nBlockNumber)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
std::map< std::string, uint256 > mapReissuedAssets
std::map< uint256, CAmount > mapDeltas
void CalculateDescendants(txiter it, setEntries &setDescendants)
Populate setDescendants with all in-mempool descendants of hash.
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
Abstract class that implements BIP9-style threshold logic, and caches results.
bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex)
std::string GetRejectReason() const
bool ParseAssetScript(CScript scriptPubKey, uint160 &hashBytes, std::string &assetName, CAmount &assetAmount)
Helper method for extracting address bytes, asset name and amount from an asset script.
void Finalize(unsigned char hash[OUTPUT_SIZE])
const std::vector< CTxOut > vout
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::map< std::string, std::set< uint256 > > mapAssetVerifierChanged
std::map< std::string, std::set< uint256 > > mapAddressesQualifiersChanged
std::shared_ptr< const CBlock > pblock
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)
CCriticalSection cs_messaging
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 exists(uint256 hash) const
bool TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
std::set< CAssetCacheQualifierAddress > setNewQualifierAddressToAdd
Qualfier Address Asset Caches.
std::string ToString() const
An output of a transaction.
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
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
Try to calculate all in-mempool ancestors of entry.
std::string ToString() const
std::vector< uint256 > vHave
CBlockIndex * GetLastCheckpoint(const CCheckpointData &data)
Returns last CBlockIndex* in mapBlockIndex that is a checkpoint.
uint32_t nMinerConfirmationWindow
bool SetPos(uint64_t nPos)
class CMainCleanup instance_of_cmaincleanup
bool IsStandardTx(const CTransaction &tx, std::string &reason, const bool witnessEnabled)
Check for standard transaction types.
bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
Queue for verifications that have to be performed.
Parameters that influence chain consensus.
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:
bool IsNullAssetVerifierTxDataScript() const
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)
CLRUCache< std::string, int8_t > * passetsGlobalRestrictionCache
Global variable that points to the global asset restriction LRU Cache (protected by cs_main) ...
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints *lp, bool useExistingLockPoints)
Check if transaction will be BIP 68 final in the next block to be created.
bool WriteAddressIndex(const std::vector< std::pair< CAddressIndexKey, CAmount > > &vect)
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
indexed_transaction_set::nth_index< 0 >::type::iterator txiter
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)
bool ReadFlag(const std::string &name, bool &fValue)
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo *> > &fileInfo, int nLastFile, const std::vector< const CBlockIndex *> &blockinfo)
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
std::map< std::pair< std::string, std::string >, std::set< uint256 > > mapAddressesMarkedFrozen
Restricted assets maps.
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos)
CFeeRate minRelayTxFeeV2
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
bool RestrictedAssetFromTransaction(const CTransaction &tx, CNewAsset &asset, std::string &strAddress)
Closure representing one script verification Note that this stores references to the spending transac...
void insert(Element e)
insert loops at most depth_limit times trying to insert a hash at various locations in the table via ...
bool HashOnchainActive(const uint256 &hash)
bool LoadBlockIndex(const CChainParams &chainparams)
Load the block tree and coins database from disk, initializing state if we're running with -reindex...
bool AreRestrictedAssetsDeployed()
bool Error(const std::string &strRejectReasonIn)
uint32_t setup_bytes(size_t bytes)
setup_bytes is a convenience function which accounts for internal memory usage when deciding how many...
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
std::set< CAssetCacheNewAsset > setNewAssetsToAdd
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
bool IsScriptTransferAsset(const CScript &scriptPubKey)
Check script and see if it matches the transfer asset template.
std::shared_ptr< std::vector< CTransactionRef > > conflictedTxs
#define LogPrint(category,...)
int32_t nVersion
block header
bool LoadExternalBlockFile(const CChainParams &chainparams, FILE *fileIn, CDiskBlockPos *dbp)
Import blocks from an external file.
CAssetsCache * passets
Global variable that point to the active assets (protected by cs_main)
bool RequireStandard() const
Policy: Filter transactions that do not match well-defined patterns.
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 SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
const ChainTxData & TxData() const
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow)
Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock...
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, ThresholdConditionCache &cache) const
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
std::map< uint256, std::set< std::pair< std::string, std::string > > > mapHashToAddressMarkedFrozen
std::string EncodeDestination(const CTxDestination &dest)
Template mixin that adds -Wthread-safety locking annotations to a subset of the mutex API...
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...
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
bool ResetBlockFailureFlags(CBlockIndex *pindex)
Remove invalidity status from a block and its descendants.
bool ReissueAssetFromTransaction(const CTransaction &tx, CReissueAsset &reissue, std::string &strAddress)
std::map< std::string, uint256 > mapAssetToHash
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
bool IsNewMsgChannelAsset() const
Make sure to call VerifyNewUniqueAsset if this call returns true.
bool IsNullAssetTxDataScript() const
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
boost::signals2::signal< void()> NotifyAlertChanged
Status bar alerts changed.
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()
CCoinsView backed by the coin database (chainstate/)
CDiskBlockPos GetUndoPos() const
void AddMessage(const CMessage &message)
void InitScriptExecutionCache()
Initializes the script-execution cache.
void Uncache(const COutPoint &outpoint)
Removes the UTXO with the given outpoint from the cache, if it is not modified.
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.
std::string verifier_string
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
int64_t GetAdjustedTime()
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)
std::map< uint256, std::string > mapReissuedTx
bool LoadMempool(void)
Load the mempool from disk.
bool PreciousBlock(CValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex)
Mark a block as precious and reorganize.
std::set< CAssetCacheRestrictedGlobal > setNewRestrictedGlobalToAdd
Restricted Global Asset Caches.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
std::string GetHex() const
void OrphanMessage(const COutPoint &out)
void SetMiscWarning(const std::string &strWarning)
Fee rate in satoshis per kilobyte: CAmount / kB.
std::unique_ptr< CConnman > g_connman
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
unsigned int DGWActivationBlock() const
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, uint256 blockHash, CAssetsCache *assetCache, std::pair< std::string, CBlockAssetUndo > *undoAssetData)
std::string GetDebugMessage() const
bool error(const char *fmt, const Args &... args)
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.
bool AssetNullVerifierDataFromScript(const CScript &scriptPubKey, CNullAssetTxVerifierString &verifierData)
unsigned int GetRejectCode() const
bool LoadBlockIndexGuts(const Consensus::Params &consensusParams, std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
CBlockTreeDB * pblocktree
Global variable that points to the active block tree (protected by cs_main)
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
bool WriteFlag(const std::string &name, bool fValue)
bool CheckTxAssets(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, CAssetsCache *assetCache, bool fCheckMempool, std::vector< std::pair< std::string, uint256 > > &vPairReissueAssets, const bool fRunningUnitTests=false, std::set< CMessage > *setMessages=nullptr, int64_t nBlocktime=0)
RVN START.
A mutable version of CTransaction.
A writer stream (for serialization) that computes a 256-bit hash.
uint32_t nRuleChangeActivationThreshold
Block height at which BIP65 becomes active.
CTransactionRef get(const uint256 &hash) const
bool CorruptionPossible() const
bool getSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
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...
void SetBestChain(const CBlockLocator &)
boost::signals2::signal< void(CTransactionRef, MemPoolRemovalReason)> NotifyEntryRemoved
const fs::path & GetDataDir(bool fNetSpecific)
bool addUnchecked(const uint256 &hash, const CTxMemPoolEntry &entry, bool validFeeEstimate=true)
arith_uint256 GetBlockProof(const CBlockIndex &block)
bool IsReissueAsset() const
std::map< std::string, std::set< uint256 > > mapAssetMarkedGlobalFrozen
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
std::string ToString() const
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. ...
CLRUCache< std::string, CDatabasedAssetData > * passetsCache
Global variable that point to the assets metadata LRU Cache (protected by cs_main) ...
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.
CCoinsViewDB * pcoinsdbview
Global variable that points to the coins database (protected by cs_main)
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
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, uint256 blockHash, bool check, CAssetsCache *assetsCache, std::pair< std::string, CBlockAssetUndo > *undoAssetData)
Utility function to add all of a transaction's outputs to a cache.
CBlockIndex * InsertBlockIndex(uint256 hash)
Create a new block index entry for a given block hash.
unsigned int GetMaxBlockSerializedSize()
bool Invalid(bool ret=false, unsigned int _chRejectCode=0, const std::string &_strRejectReason="", const std::string &_strDebugMessage="")
CTxDestination destination
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from...
A hasher class for SHA-256.
uint64_t CalculateCurrentUsage()
BLOCK PRUNING CODE.
void addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewCache &view)
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)
bool IsNewUniqueAsset() const
Make sure to call VerifyNewUniqueAsset if this call returns true.
void SetfLargeWorkForkFound(bool flag)
Removed for conflict with in-block transaction.
bool UpdateSpentIndex(const std::vector< std::pair< CSpentIndexKey, CSpentIndexValue > > &vect)
boost::signals2::signal< void(const std::string &title, int nProgress, bool resume_possible)> ShowProgress
Show progress e.g.
CBlockIndex * maxInputBlock
fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
Translation to a filesystem path.
bool ReadAddressIndex(uint160 addressHash, int type, std::string assetName, std::vector< std::pair< CAddressIndexKey, CAmount > > &addressIndex, int start=0, int end=0)
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 memorypool 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
bool IsPayToPublicKeyHash() const
iterator find(const K &key)
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
void PrioritiseTransaction(const uint256 &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
bool IsNullGlobalRestrictionAssetTxDataScript() const
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags)
bool WriteTxIndex(const std::vector< std::pair< uint256, CDiskTxPos > > &vect)
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
Access to the block database (blocks/index/)
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 nonce).
Non-refcounted RAII wrapper for FILE*.
CLRUCache< std::string, int > * pMessagesSeenAddressCache
Global variable that points to the address seen LRU Cache (protected by cs_main)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
UniValue reissue(const JSONRPCRequest &request)
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN)
Remove a set of transactions from the mempool.
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...
CConditionVariable cvBlockChange
bool IsAssetNameAnRestricted(const std::string &name)
Check if an asset is a restricted asset.
bool IsChannelSubscribed(const std::string &name)
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
bool IsAssetNameAnOwner(const std::string &name)
Check if an asset is an owner.
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
bool IsScriptNewUniqueAsset(const CScript &scriptPubKey)
Check script and see if it matches the unquie issuance template.
void TransactionAddedToMempool(const CTransactionRef &)
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
Threshold condition checker that triggers when unknown versionbits are seen on the network...