52 #include <boost/algorithm/string/replace.hpp> 53 #include <boost/algorithm/string/join.hpp> 54 #include <boost/thread.hpp> 57 # error "Fabcoin cannot be compiled without assertions." 129 struct CBlockIndexWorkComparator
142 if (pa < pb)
return false;
143 if (pa > pb)
return true;
157 std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
161 std::multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
164 std::vector<CBlockFileInfo> vinfoBlockFile;
165 int nLastBlockFile = 0;
170 bool fCheckForPruning =
false;
178 int32_t nBlockSequenceId = 1;
180 int32_t nBlockReverseSequenceId = -1;
202 std::set<CBlockIndex*> g_failed_blocks;
205 std::set<CBlockIndex*> setDirtyBlockIndex;
208 std::set<int> setDirtyFileInfo;
222 conflictedTxs.push_back(txRemoved);
227 for (
const auto& tx : conflictedTxs) {
230 conflictedTxs.clear();
264 static int GetWitnessCommitmentIndex(
const CBlock& block);
266 static void FindFilesToPruneManual(std::set<int>& setFilesToPrune,
int nManualPruneHeight);
267 static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
269 static FILE* OpenUndoFile(
const CDiskBlockPos &pos,
bool fReadOnly =
false);
289 const int nBlockHeight = chainActive.
Height() + 1;
300 return IsFinalTx(tx, nBlockHeight, nBlockTime);
337 std::pair<int, int64_t> lockPair;
338 if (useExistingLockPoints) {
340 lockPair.first = lp->
height;
341 lockPair.second = lp->
time;
346 std::vector<int> prevheights;
347 prevheights.resize(tx.
vin.size());
348 for (
size_t txinIndex = 0; txinIndex < tx.
vin.size(); txinIndex++) {
349 const CTxIn& txin = tx.
vin[txinIndex];
352 return error(
"%s: Missing input", __func__);
354 if (coin.
nHeight == MEMPOOL_HEIGHT) {
356 prevheights[txinIndex] = tip->
nHeight + 1;
358 prevheights[txinIndex] = coin.
nHeight;
363 lp->
height = lockPair.first;
364 lp->
time = lockPair.second;
378 int maxInputHeight = 0;
379 for (
int height : prevheights) {
381 if (height != tip->
nHeight+1) {
382 maxInputHeight =
std::max(maxInputHeight, height);
394 static void LimitMempoolSize(
CTxMemPool& pool,
size_t limit,
unsigned long age) {
400 std::vector<COutPoint> vNoSpendsRemaining;
402 for (
const COutPoint& removed : vNoSpendsRemaining)
415 static bool IsCurrentForFeeEstimation()
428 return (uint32_t)nHeight >= (uint32_t)params.
FABHeight;
432 if (pindexPrev ==
nullptr) {
460 std::vector<uint256> vHashUpdate;
471 if (!fAddToMempool || (*it)->IsCoinBase() || !
AcceptToMemoryPool(
mempool, stateDummy, *it,
false,
nullptr,
nullptr,
true)) {
476 vHashUpdate.push_back((*it)->GetHash());
491 LimitMempoolSize(
mempool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
513 if (coin.
IsSpent())
return false;
527 return CheckInputs(tx, state, view,
true, flags, cacheSigStore,
true, txdata);
531 bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
532 bool fOverrideMempoolLimit,
const CAmount& nAbsurdFee, std::vector<COutPoint>& coins_to_uncache,
bool rawTx)
538 *pfMissingInputs =
false;
545 return state.
DoS(100,
false, REJECT_INVALID,
"coinbase");
550 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"no-witness-yet",
true);
556 return state.
DoS(0,
false, REJECT_NONSTANDARD, reason);
562 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"non-final");
566 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-already-in-mempool");
570 std::set<uint256> setConflicts;
578 const CTransaction *ptxConflicting = itConflicting->second;
579 if (!setConflicts.count(ptxConflicting->
GetHash()))
593 bool fReplacementOptOut =
true;
596 for (
const CTxIn &_txin : ptxConflicting->
vin)
598 if (_txin.
nSequence <= MAX_BIP125_RBF_SEQUENCE)
600 fReplacementOptOut =
false;
605 if (fReplacementOptOut) {
606 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-mempool-conflict");
609 setConflicts.insert(ptxConflicting->
GetHash());
627 for (
size_t out = 0; out < tx.
vout.size(); out++) {
631 if (!had_coin_in_cache) {
632 coins_to_uncache.push_back(outpoint);
634 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-already-known");
641 coins_to_uncache.push_back(txin.
prevout);
645 for (
size_t out = 0; out < tx.
vout.size(); out++) {
648 return state.
Invalid(
false, REJECT_DUPLICATE,
"txn-already-known");
652 if (pfMissingInputs) {
653 *pfMissingInputs =
true;
673 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"non-BIP68-final");
678 return state.
Invalid(
false, REJECT_NONSTANDARD,
"bad-txns-nonstandard-inputs");
682 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"bad-witness-nonstandard",
true);
687 CAmount nFees = nValueIn-nValueOut;
693 return state.
DoS(1,
false, REJECT_INVALID,
"bad-txns-invalid-contract-before-fork");
697 return state.
DoS(1,
false, REJECT_INVALID,
"bad-txns-invalid-sender-script");
702 uint64_t blockGasLimit = fascDGP.getBlockGasLimit(chainActive.
Tip()->
nHeight + 1);
709 return state.
DoS(100,
error(
"AcceptToMempool(): Contract transaction of the wrong format"), REJECT_INVALID,
"bad-tx-bad-contract-format");
711 std::vector<FascTransaction> fascTransactions = resultConverter.first;
712 std::vector<EthTransactionParams> fascETP = resultConverter.second;
717 sumGas += fascTransaction.gas() * fascTransaction.gasPrice();
720 return state.
DoS(100,
error(
"AcceptToMempool(): Transaction's gas stipend overflows"), REJECT_INVALID,
"bad-tx-gas-stipend-overflow");
724 return state.
DoS(100,
error(
"AcceptToMempool(): Transaction fee does not cover the gas stipend"), REJECT_INVALID,
"bad-txns-fee-notenough");
727 if(txMinGasPrice != 0) {
728 txMinGasPrice =
std::min(txMinGasPrice, fascTransaction.gasPrice());
730 txMinGasPrice = fascTransaction.gasPrice();
732 VersionVM v = fascTransaction.getVersion();
734 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution uses unknown version format"), REJECT_INVALID,
"bad-tx-version-format");
736 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution uses unknown root VM"), REJECT_INVALID,
"bad-tx-version-rootvm");
738 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution uses unknown VM version"), REJECT_INVALID,
"bad-tx-version-vmversion");
740 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution uses unknown flag options"), REJECT_INVALID,
"bad-tx-version-flags");
743 if(fascTransaction.gas() <
gArgs.
GetArg(
"-minmempoolgaslimit", MEMPOOL_MIN_GAS_LIMIT))
744 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution has lower gas limit than allowed to accept into mempool"), REJECT_INVALID,
"bad-tx-too-little-mempool-gas");
747 if(fascTransaction.gas() < MINIMUM_GAS_LIMIT && v.
rootVM != 0)
748 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution has lower gas limit than allowed"), REJECT_INVALID,
"bad-tx-too-little-gas");
750 if(fascTransaction.gas() > UINT32_MAX)
751 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution can not specify greater gas limit than can fit in 32-bits"), REJECT_INVALID,
"bad-tx-too-much-gas");
753 gasAllTxs += fascTransaction.gas();
755 return state.
DoS(1,
false, REJECT_INVALID,
"bad-txns-gas-exceeds-blockgaslimit");
758 if(v.
rootVM!=0 && (uint64_t)fascTransaction.gasPrice() < minGasPrice)
759 return state.
DoS(100,
error(
"AcceptToMempool(): Contract execution has lower gas price than allowed"), REJECT_INVALID,
"bad-tx-low-gas-price");
763 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-small-gasprice");
765 if(count > fascTransactions.size())
766 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-incorrect-format");
769 LogPrintf(
"absurdly-high-fee nAbsurdFee=%d nFees=%d sumGas=%d\n ", nAbsurdFee , nFees , sumGas);
771 REJECT_HIGHFEE,
"absurdly-high-fee",
772 strprintf(
"%d > %d", nFees, nAbsurdFee));
783 bool fSpendsCoinbase =
false;
787 fSpendsCoinbase =
true;
793 fSpendsCoinbase, nSigOpsCost, lp,
CAmount(txMinGasPrice));
802 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"bad-txns-too-many-sigops",
false,
806 if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) {
807 return state.
DoS(0,
false, REJECT_INSUFFICIENTFEE,
"mempool min fee not met",
false,
strprintf(
"%d < %d", nFees, mempoolRejectFee));
811 if (fLimitFree && nModifiedFees < ::minRelayTxFee.
GetFee(nSize)) {
812 return state.
DoS(0,
false, REJECT_INSUFFICIENTFEE,
"min relay fee not met");
816 LogPrintf(
"absurdly-high-fee nAbsurdFee=%d nFees=%d \n", nAbsurdFee , nFees );
818 REJECT_HIGHFEE,
"absurdly-high-fee",
819 strprintf(
"%d > %d", nFees, nAbsurdFee));
824 size_t nLimitAncestors =
gArgs.
GetArg(
"-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
825 size_t nLimitAncestorSize =
gArgs.
GetArg(
"-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
826 size_t nLimitDescendants =
gArgs.
GetArg(
"-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
827 size_t nLimitDescendantSize =
gArgs.
GetArg(
"-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
828 std::string errString;
829 if (!pool.
CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
830 return state.
DoS(0,
false, REJECT_NONSTANDARD,
"too-long-mempool-chain",
false, errString);
839 const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
840 if (setConflicts.count(hashAncestor))
842 return state.
DoS(10,
false,
843 REJECT_INVALID,
"bad-txns-spends-conflicting-tx",
false,
844 strprintf(
"%s spends conflicting transaction %s",
853 size_t nConflictingSize = 0;
854 uint64_t nConflictingCount = 0;
861 const bool fReplacementTransaction = setConflicts.size();
862 if (fReplacementTransaction)
864 CFeeRate newFeeRate(nModifiedFees, nSize);
865 std::set<uint256> setConflictsParents;
866 const int maxDescendantsToVisit = 100;
868 for (
const uint256 &hashConflicting : setConflicts)
871 if (mi == pool.
mapTx.end())
875 setIterConflicting.insert(mi);
893 CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
894 if (newFeeRate <= oldFeeRate)
896 return state.
DoS(0,
false,
897 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
898 strprintf(
"rejecting replacement %s; new feerate %s <= old feerate %s",
901 oldFeeRate.ToString()));
904 for (
const CTxIn &txin : mi->GetTx().vin)
909 nConflictingCount += mi->GetCountWithDescendants();
914 if (nConflictingCount <= maxDescendantsToVisit) {
921 nConflictingFees += it->GetModifiedFee();
922 nConflictingSize += it->GetTxSize();
925 return state.
DoS(0,
false,
926 REJECT_NONSTANDARD,
"too many potential replacements",
false,
927 strprintf(
"rejecting replacement %s; too many potential replacements (%d > %d)\n",
930 maxDescendantsToVisit));
933 for (
unsigned int j = 0; j < tx.
vin.size(); j++)
939 if (!setConflictsParents.count(tx.
vin[j].prevout.hash))
944 if (pool.
mapTx.find(tx.
vin[j].prevout.hash) != pool.
mapTx.end())
945 return state.
DoS(0,
false,
946 REJECT_NONSTANDARD,
"replacement-adds-unconfirmed",
false,
947 strprintf(
"replacement %s adds unconfirmed input, idx %d",
955 if (nModifiedFees < nConflictingFees)
957 return state.
DoS(0,
false,
958 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
959 strprintf(
"rejecting replacement %s, less fees than conflicting txs; %s < %s",
965 CAmount nDeltaFees = nModifiedFees - nConflictingFees;
968 return state.
DoS(0,
false,
969 REJECT_INSUFFICIENTFEE,
"insufficient fee",
false,
970 strprintf(
"rejecting replacement %s, not enough additional fees to relay; %s < %s",
977 unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
979 scriptVerifyFlags =
gArgs.
GetArg(
"-promiscuousmempoolflags", scriptVerifyFlags);
985 if (!
CheckInputs(tx, state, view,
true, scriptVerifyFlags,
true,
false, txdata)) {
1013 unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(chainActive.
Tip(),
Params().
GetConsensus());
1014 if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, currentBlockScriptVerifyFlags,
true, txdata))
1019 if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) {
1020 return error(
"%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against latest-block but not STANDARD flags %s, %s",
1023 if (!
CheckInputs(tx, state, view,
true, MANDATORY_SCRIPT_VERIFY_FLAGS,
true,
false, txdata)) {
1024 return error(
"%s: ConnectInputs failed against MANDATORY but not STANDARD flags due to promiscuous mempool %s, %s",
1027 LogPrintf(
"Warning: -promiscuousmempool flags set to not include currently enforced soft forks, this may break mining or otherwise cause instability!\n");
1036 it->GetTx().GetHash().ToString(),
1039 (int)nSize - (
int)nConflictingSize);
1041 plTxnReplaced->push_back(it->GetSharedTx());
1049 bool validForFeeEstimation = !fReplacementTransaction && IsCurrentForFeeEstimation() && pool.
HasNoInputsOf(tx);
1052 pool.
addUnchecked(hash, entry, setAncestors, validForFeeEstimation);
1055 if (!fOverrideMempoolLimit) {
1056 LimitMempoolSize(pool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
1058 return state.
DoS(0,
false, REJECT_INSUFFICIENTFEE,
"mempool full");
1069 bool* pfMissingInputs, int64_t nAcceptTime, std::list<CTransactionRef>* plTxnReplaced,
1070 bool fOverrideMempoolLimit,
const CAmount nAbsurdFee,
bool rawTx =
false)
1072 std::vector<COutPoint> coins_to_uncache;
1073 bool res = AcceptToMemoryPoolWorker(chainparams, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache, rawTx);
1075 for (
const COutPoint& hashTx : coins_to_uncache)
1097 bool* pfMissingInputs, std::list<CTransactionRef>* plTxnReplaced,
1098 bool fOverrideMempoolLimit,
const CAmount nAbsurdFee,
bool rawTx)
1101 return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, fLimitFree, pfMissingInputs,
GetTime(), plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, rawTx);
1123 return error(
"%s: OpenBlockFile failed", __func__);
1129 }
catch (
const std::exception&
e) {
1130 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1133 if (txOut->GetHash() != hash)
1134 return error(
"%s: txid mismatch", __func__);
1147 for (
const auto& tx : block.
vtx) {
1148 if (tx->GetHash() == hash) {
1174 return error(
"WriteBlockToDisk: OpenBlockFile failed");
1178 fileout <<
FLATDATA(messageStart) << nSize;
1181 long fileOutPos = ftell(fileout.
Get());
1183 return error(
"WriteBlockToDisk: ftell failed");
1184 pos.
nPos = (
unsigned int)fileOutPos;
1190 template <
typename Block>
1198 return error(
"ReadBlockFromDisk: OpenBlockFile failed for %s", pos.
ToString());
1204 catch (
const std::exception&
e) {
1205 return error(
"%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.
ToString());
1210 bool postfork = ( (uint32_t)block.nHeight >= (uint32_t)consensusParams.
FABHeight );
1212 LogPrintf(
"Debug nHeight=%d FABHeight=%d postfork=%d \n", block.nHeight, consensusParams.
FABHeight, postfork );
1213 return error(
"ReadBlockFromDisk: Errors in block header at %s (bad Equihash solution)", pos.
ToString());
1216 if (!
CheckProofOfWork(block.GetHash(), block.nBits, postfork, consensusParams))
1217 return error(
"ReadBlockFromDisk: Errors in block header at %s", pos.
ToString());
1227 return error(
"ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
1242 return error(
"CTransaction::ReadFromDisk() : OpenBlockFile failed");
1251 catch (
const std::exception&
e) {
1252 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1264 if (prevout.
n >= tx.
vout.size())
1277 CAmount nSubsidy = INITIAL_BLOCK_REWARD * COIN;
1282 nSubsidy = INITIAL_BLOCK_REWARD_REGTEST * COIN;
1285 if ( nHeight == 2 && !fRegTest ) {
1286 nSubsidy = 32000000 * COIN;
1291 nSubsidy >>= halvings;
1300 static std::atomic<bool> latchToFalse{
false};
1302 if (latchToFalse.load(std::memory_order_relaxed))
1306 if (latchToFalse.load(std::memory_order_relaxed))
1310 if (chainActive.
Tip() ==
nullptr)
1316 LogPrintf(
"Leaving InitialBlockDownload (latching to false)\n");
1317 latchToFalse.store(
true, std::memory_order_relaxed);
1323 static void AlertNotify(
const std::string& strMessage)
1326 std::string strCmd =
gArgs.
GetArg(
"-alertnotify",
"");
1327 if (strCmd.empty())
return;
1332 std::string singleQuote(
"'");
1334 safeStatus = singleQuote+safeStatus+singleQuote;
1335 boost::replace_all(strCmd,
"%s", safeStatus);
1340 static void CheckForkWarningConditions()
1350 if (pindexBestForkTip && chainActive.
Height() - pindexBestForkTip->
nHeight >= 72)
1351 pindexBestForkTip =
nullptr;
1353 if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.
Tip()->
nChainWork + (
GetBlockProof(*chainActive.
Tip()) * 6)))
1357 std::string warning = std::string(
"'Warning: Large-work fork detected, forking after block ") +
1359 AlertNotify(warning);
1363 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__,
1370 LogPrintf(
"%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
1381 static void CheckForkWarningConditionsOnNewFork(
CBlockIndex* pindexNewForkTip)
1387 while (pfork && pfork != plonger)
1390 plonger = plonger->
pprev;
1391 if (pfork == plonger)
1393 pfork = pfork->
pprev;
1403 if (pfork && (!pindexBestForkTip || pindexNewForkTip->
nHeight > pindexBestForkTip->
nHeight) &&
1407 pindexBestForkTip = pindexNewForkTip;
1411 CheckForkWarningConditions();
1414 void static InvalidChainFound(
CBlockIndex* pindexNew)
1416 if (!pindexBestInvalid || pindexNew->
nChainWork > pindexBestInvalid->nChainWork)
1417 pindexBestInvalid = pindexNew;
1419 LogPrintf(
"%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
1425 LogPrintf(
"%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
1428 CheckForkWarningConditions();
1434 g_failed_blocks.insert(pindex);
1435 setDirtyBlockIndex.insert(pindex);
1436 setBlockIndexCandidates.erase(pindex);
1437 InvalidChainFound(pindex);
1463 const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1472 return pindexPrev->
nHeight + 1;
1485 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);
1486 size_t nElems = scriptExecutionCache.
setup_bytes(nMaxCacheSize);
1487 LogPrintf(
"Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
1488 (nElems*
sizeof(
uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
1513 pvChecks->reserve(tx.
vin.size());
1524 if (fScriptChecks) {
1533 static_assert(55 -
sizeof(flags) - 32 >= 128/8,
"Want at least 128 bits of nonce for script execution cache");
1536 if (scriptExecutionCache.
contains(hashCacheEntry, !cacheFullScriptStore)) {
1540 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
1554 CScriptCheck check(scriptPubKey, amount, tx, i, flags, cacheSigStore, &txdata);
1557 check.
swap(pvChecks->back());
1558 }
else if (!check()) {
1559 if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
1567 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
1582 if (cacheFullScriptStore && !pvChecks) {
1585 scriptExecutionCache.
insert(hashCacheEntry);
1600 return error(
"%s: OpenUndoFile failed", __func__);
1604 fileout <<
FLATDATA(messageStart) << nSize;
1607 long fileOutPos = ftell(fileout.
Get());
1609 return error(
"%s: ftell failed", __func__);
1610 pos.
nPos = (
unsigned int)fileOutPos;
1611 fileout << blockundo;
1615 hasher << hashBlock;
1616 hasher << blockundo;
1627 return error(
"%s: OpenUndoFile failed", __func__);
1633 verifier << hashBlock;
1634 verifier >> blockundo;
1635 filein >> hashChecksum;
1637 catch (
const std::exception&
e) {
1638 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
1642 if (hashChecksum != verifier.
GetHash())
1643 return error(
"%s: Checksum mismatch", __func__);
1649 bool AbortNode(
const std::string& strMessage,
const std::string& userMessage=
"")
1654 userMessage.empty() ?
_(
"Error: A fatal internal error occurred, see debug.log for details") : userMessage,
1660 bool AbortNode(
CValidationState& state,
const std::string& strMessage,
const std::string& userMessage=
"")
1662 AbortNode(strMessage, userMessage);
1663 return state.
Error(strMessage);
1686 if (view.
HaveCoin(out)) fClean =
false;
1688 if (undo.nHeight == 0) {
1694 undo.nHeight = alternate.
nHeight;
1704 view.
AddCoin(out, std::move(undo), !fClean);
1723 error(
"DisconnectBlock(): no undo data available");
1727 error(
"DisconnectBlock(): failure reading undo data");
1731 if (blockUndo.
vtxundo.size() + 1 != block.
vtx.size()) {
1732 error(
"DisconnectBlock(): block and undo data inconsistent");
1737 for (
int i = block.
vtx.size() - 1; i >= 0; i--) {
1744 for (
size_t o = 0; o < tx.
vout.size(); o++) {
1745 if (!tx.
vout[o].scriptPubKey.IsUnspendable()) {
1748 bool is_spent = view.
SpendCoin(out, &coin);
1759 error(
"DisconnectBlock(): transaction and undo data inconsistent");
1762 for (
unsigned int j = tx.
vin.size(); j-- > 0;) {
1785 void static FlushBlockFile(
bool fFinalize =
false)
1787 LOCK(cs_LastBlockFile);
1794 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
1799 fileOld = OpenUndoFile(posOld);
1802 TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
1814 scriptcheckqueue.
Thread();
1823 int32_t nVersion = VERSIONBITS_TOP_BITS;
1853 return ((pindex->
nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
1854 ((pindex->
nVersion >> bit) & 1) != 0 &&
1866 int64_t nBIP16SwitchTime = 1333238400;
1867 bool fStrictPayToScriptHash = (pindex->
GetBlockTime() >= nBIP16SwitchTime);
1897 static int64_t nTimeCheck = 0;
1898 static int64_t nTimeForks = 0;
1899 static int64_t nTimeVerify = 0;
1900 static int64_t nTimeConnect = 0;
1901 static int64_t nTimeIndex = 0;
1902 static int64_t nTimeCallbacks = 0;
1903 static int64_t nTimeTotal = 0;
1922 uint32_t sizeBlockDGP = fascDGP.getBlockSize(pindex->
nHeight + 1);
1923 uint64_t minGasPrice = fascDGP.getMinGasPrice(pindex->
nHeight + 1);
1924 uint64_t blockGasLimit = fascDGP.getBlockGasLimit(pindex->
nHeight + 1);
1928 std::vector<CTxOut> checkVouts;
1930 uint64_t countCumulativeGasUsed = 0;
1939 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-length",
false,
"size limits failed");
1943 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-weight",
false,
strprintf(
"%s : weight limit failed", __func__));
1963 if (!UpdateHashProof(block, state, chainparams.
GetConsensus(), pindex, view)) {
1968 bool fScriptChecks =
true;
1969 if (!hashAssumeValid.
IsNull()) {
1975 BlockMap::const_iterator it =
mapBlockIndex.find(hashAssumeValid);
1977 if (it->second->GetAncestor(pindex->
nHeight) == pindex &&
1994 int64_t nTime1 =
GetTimeMicros(); nTimeCheck += nTime1 - nTimeStart;
1995 LogPrint(
BCLog::BENCH,
" - Sanity checks: %.2fms [%.2fs]\n", 0.001 * (nTime1 - nTimeStart), nTimeCheck * 0.000001);
2026 if (fEnforceBIP30) {
2027 for (
const auto& tx : block.
vtx) {
2028 for (
size_t o = 0; o < tx->vout.size(); o++) {
2030 return state.
DoS(100,
error(
"ConnectBlock(): tried to overwrite transaction"),
2031 REJECT_INVALID,
"bad-txns-BIP30");
2038 int nLockTimeFlags = 0;
2044 unsigned int flags = GetBlockScriptFlags(pindex, chainparams.
GetConsensus());
2046 int64_t nTime2 =
GetTimeMicros(); nTimeForks += nTime2 - nTime1;
2047 LogPrint(
BCLog::BENCH,
" - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001);
2053 std::vector<int> prevheights;
2056 int64_t nSigOpsCost = 0;
2058 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2059 vPos.reserve(block.
vtx.size());
2060 blockundo.
vtxundo.reserve(block.
vtx.size() - 1);
2062 std::map<dev::Address, std::pair<CHeightTxIndexKey, std::vector<uint256>>> heightIndexes;
2064 std::vector<PrecomputedTransactionData> txdata;
2065 txdata.reserve(block.
vtx.size());
2066 uint64_t blockGasUsed = 0;
2068 uint64_t nValueOut = 0;
2069 uint64_t nValueIn = 0;
2070 for (
unsigned int i = 0; i < block.
vtx.size(); i++)
2074 nInputs += tx.
vin.size();
2079 return state.
DoS(100,
error(
"ConnectBlock(): inputs missing/spent"),
2080 REJECT_INVALID,
"bad-txns-inputs-missingorspent");
2085 prevheights.resize(tx.
vin.size());
2086 for (
size_t j = 0; j < tx.
vin.size(); j++) {
2090 if (!
SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
2091 return state.
DoS(100,
error(
"%s: contains a non-BIP68-final transaction", __func__),
2092 REJECT_INVALID,
"bad-txns-nonfinal");
2102 return state.
DoS(100,
error(
"ConnectBlock(): too many sigops"),
2103 REJECT_INVALID,
"bad-blk-sigops");
2105 txdata.emplace_back(tx);
2111 std::vector<CScriptCheck> vChecks;
2112 bool fCacheResults = fJustCheck;
2114 return error(
"ConnectBlock(): CheckInputs on %s failed with %s",
2116 control.
Add(vChecks);
2121 return state.
DoS(100,
error(
"ConnectBlock(): Contract spend without OP_SPEND in scriptSig"),
2122 REJECT_INVALID,
"bad-txns-invalid-contract-spend");
2134 nValueIn += nTxValueIn;
2135 nValueOut += nTxValueOut;
2140 checkBlock.vtx.push_back(block.
vtx[i]);
2144 return state.
DoS(1,
false, REJECT_INVALID,
"bad-txns-invalid-contract-before-fork");
2148 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-invalid-sender-script");
2155 return state.
DoS(100,
error(
"ConnectBlock(): Contract transaction of the wrong format"), REJECT_INVALID,
"bad-tx-bad-contract-format");
2158 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution has lower gas price than allowed"), REJECT_INVALID,
"bad-tx-low-gas-price");
2162 ByteCodeExec exec(block, resultConvertFascTX.first, blockGasLimit);
2166 bool nonZeroVersion =
false;
2173 return state.
DoS(100,
error(
"ConnectBlock(): Transaction's gas stipend overflows"), REJECT_INVALID,
"bad-tx-gas-stipend-overflow");
2177 return state.
DoS(100,
error(
"ConnectBlock(): Transaction fee does not cover the gas stipend"), REJECT_INVALID,
"bad-txns-fee-notenough");
2182 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution uses unknown version format"), REJECT_INVALID,
"bad-tx-version-format");
2184 nonZeroVersion =
true;
2187 if (nonZeroVersion) {
2189 return state.
DoS(100,
error(
"ConnectBlock(): Contract tx has mixed version 0 and non-0 VM executions"), REJECT_INVALID,
"bad-tx-mixed-zero-versions");
2193 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution uses unknown root VM"), REJECT_INVALID,
"bad-tx-version-rootvm");
2195 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution uses unknown VM version"), REJECT_INVALID,
"bad-tx-version-vmversion");
2197 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution uses unknown flag options"), REJECT_INVALID,
"bad-tx-version-flags");
2200 if (qtx.
gas() < MINIMUM_GAS_LIMIT && v.
rootVM != 0)
2201 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution has lower gas limit than allowed"), REJECT_INVALID,
"bad-tx-too-little-gas");
2203 if (qtx.
gas() > UINT32_MAX)
2204 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution can not specify greater gas limit than can fit in 32-bits"), REJECT_INVALID,
"bad-tx-too-much-gas");
2206 gasAllTxs += qtx.
gas();
2207 if (gasAllTxs >
dev::u256(blockGasLimit))
2208 return state.
DoS(1,
false, REJECT_INVALID,
"bad-txns-gas-exceeds-blockgaslimit");
2212 return state.
DoS(100,
error(
"ConnectBlock(): Contract execution has lower gas price than allowed"), REJECT_INVALID,
"bad-tx-low-gas-price");
2215 if (!nonZeroVersion) {
2218 return state.
DoS(100,
error(
"ConnectBlock(): Version 0 contract executions are not allowed unless created by the AAL "), REJECT_INVALID,
"bad-tx-improper-version-0");
2223 return state.
DoS(100,
error(
"ConnectBlock(): Unknown error during contract execution"), REJECT_INVALID,
"bad-tx-unknown-error");
2226 std::vector<ResultExecute> resultExec(exec.
getResult());
2229 return state.
DoS(100,
error(
"ConnectBlock(): Error processing VM execution results"), REJECT_INVALID,
"bad-vm-exec-processing");
2232 countCumulativeGasUsed += bcer.usedGas;
2233 std::vector<TransactionReceiptInfo> tri;
2236 for (
size_t k = 0; k < resultConvertFascTX.first.size(); k++) {
2238 if (!heightIndexes.count(key)) {
2241 heightIndexes[key].second.push_back(tx.
GetHash());
2243 countCumulativeGasUsed, uint64_t(resultExec[k].execRes.gasUsed), resultExec[k].execRes.newAddress, resultExec[k].txRec.log(), resultExec[k].execRes.excepted });
2249 blockGasUsed += bcer.usedGas;
2250 if (blockGasUsed > blockGasLimit) {
2251 return state.
DoS(1000,
error(
"ConnectBlock(): Block exceeds gas limit"), REJECT_INVALID,
"bad-blk-gaslimit");
2253 for (
CTxOut refundVout : bcer.refundOutputs) {
2254 gasRefunds += refundVout.
nValue;
2256 checkVouts.insert(checkVouts.end(), bcer.refundOutputs.begin(), bcer.refundOutputs.end());
2258 checkBlock.vtx.push_back(MakeTransactionRef(std::move(t)));
2265 if (re.execRes.newAddress !=
dev::Address() && !fJustCheck)
2266 dev::g_logPost(std::string(
"Address : " + re.execRes.newAddress.hex()),
nullptr);
2277 vPos.push_back(std::make_pair(tx.
GetHash(), pos));
2280 int64_t nTime3 =
GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
2281 LogPrint(
BCLog::BENCH,
" - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (
unsigned)block.
vtx.size(), 0.001 * (nTime3 - nTime2), 0.001 * (nTime3 - nTime2) / block.
vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * 0.000001);
2283 if (nFees < gasRefunds) {
2284 return state.
DoS(1000,
error(
"ConnectBlock(): Less total fees than gas refund fees"), REJECT_INVALID,
"bad-blk-fees-greater-gasrefund");
2288 return state.
DoS(100,
error(
"ConnectBlock(): Reward check failed"));
2290 if (!control.
Wait())
2291 return state.
DoS(100,
error(
"%s: CheckQueue failed", __func__), REJECT_INVALID,
"block-validation-failed");
2293 int64_t nTime4 =
GetTimeMicros(); nTimeVerify += nTime4 - nTime2;
2294 LogPrint(
BCLog::BENCH,
" - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n", nInputs - 1, 0.001 * (nTime4 - nTime2), nInputs <= 1 ? 0 : 0.001 * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * 0.000001);
2302 if ((checkBlock.GetHash() != block.
GetHash()) && !fJustCheck)
2304 LogPrintf(
"Actual block data does not match block expected by AAL\n");
2308 CBlock dumpCheckBlock(checkBlock);
2309 LogPrintf(
"Debug Dump Checked block: Height %d, others == %s \n", checkBlock.nHeight, dumpCheckBlock.ToString());
2314 if (block.
vtx.size() > checkBlock.vtx.size()) {
2315 LogPrintf(
"Unexpected AAL transactions in block. Actual txs: %i, expected txs: %i\n", block.
vtx.size(), checkBlock.vtx.size());
2316 for (
size_t i = 0; i<block.
vtx.size(); i++) {
2317 if (i > checkBlock.vtx.size()) {
2318 LogPrintf(
"Unexpected transaction: %s\n", block.
vtx[i]->ToString());
2321 if (block.
vtx[i]->GetHash() != block.
vtx[i]->GetHash()) {
2322 LogPrintf(
"Mismatched transaction at entry %i\n", i);
2324 LogPrintf(
"Expected: %s\n", checkBlock.vtx[i]->ToString());
2329 else if (block.
vtx.size() < checkBlock.vtx.size()) {
2330 LogPrintf(
"Actual block is missing AAL transactions. Actual txs: %i, expected txs: %i\n", block.
vtx.size(), checkBlock.vtx.size());
2331 for (
size_t i = 0; i<checkBlock.vtx.size(); i++) {
2332 if (i > block.
vtx.size()) {
2333 LogPrintf(
"Missing transaction: %s\n", checkBlock.vtx[i]->ToString());
2336 if (block.
vtx[i]->GetHash() != block.
vtx[i]->GetHash()) {
2337 LogPrintf(
"Mismatched transaction at entry %i\n", i);
2339 LogPrintf(
"Expected: %s\n", checkBlock.vtx[i]->ToString());
2346 for (
size_t i = 0; i<checkBlock.vtx.size(); i++) {
2347 if (block.
vtx[i]->GetHash() != block.
vtx[i]->GetHash()) {
2348 LogPrintf(
"Mismatched transaction at entry %i\n", i);
2350 LogPrintf(
"Expected: %s\n", checkBlock.vtx[i]->ToString());
2356 LogPrintf(
"Actual block data does not match hashUTXORoot expected by AAL block\n");
2359 LogPrintf(
"Actual block data does not match hashStateRoot expected by AAL block\n");
2362 return state.
DoS(100,
error(
"ConnectBlock(): Incorrect AAL transactions or hashes (hashStateRoot, hashUTXORoot)"),
2363 REJECT_INVALID,
"incorrect-transactions-or-hashes-block");
2386 return error(
"ConnectBlock(): FindUndoPos failed");
2388 return AbortNode(state,
"Failed to write undo data");
2396 setDirtyBlockIndex.insert(pindex);
2401 for (
const auto&
e : heightIndexes)
2404 return AbortNode(state,
"Failed to write height index");
2409 return AbortNode(state,
"Failed to write transaction index");
2414 int64_t nTime5 =
GetTimeMicros(); nTimeIndex += nTime5 - nTime4;
2415 LogPrint(
BCLog::BENCH,
" - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime5 - nTime4), nTimeIndex * 0.000001);
2417 static uint256 hashPrevBestCoinBase;
2419 hashPrevBestCoinBase = block.
vtx[0]->GetHash();
2421 int64_t nTime6 =
GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
2422 LogPrint(
BCLog::BENCH,
" - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001);
2438 static int64_t nLastWrite = 0;
2439 static int64_t nLastFlush = 0;
2440 static int64_t nLastSetChain = 0;
2441 std::set<int> setFilesToPrune;
2442 bool fFlushForPrune =
false;
2443 bool fDoFullFlush =
false;
2447 LOCK(cs_LastBlockFile);
2449 if (nManualPruneHeight > 0) {
2450 FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight);
2453 fCheckForPruning =
false;
2455 if (!setFilesToPrune.empty()) {
2456 fFlushForPrune =
true;
2458 pblocktree->
WriteFlag(
"prunedblockfiles",
true);
2465 if (nLastWrite == 0) {
2468 if (nLastFlush == 0) {
2471 if (nLastSetChain == 0) {
2472 nLastSetChain = nNow;
2474 int64_t nMempoolSizeMax =
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
2476 int64_t nTotalSpace =
nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
2478 bool fCacheLarge = mode ==
FLUSH_STATE_PERIODIC && cacheSize >
std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
2482 bool fPeriodicWrite = mode ==
FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
2484 bool fPeriodicFlush = mode ==
FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
2486 fDoFullFlush = (mode ==
FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
2488 if (fDoFullFlush || fPeriodicWrite) {
2491 return state.
Error(
"out of disk space");
2496 std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
2497 vFiles.reserve(setDirtyFileInfo.size());
2498 for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
2499 vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it]));
2500 setDirtyFileInfo.erase(it++);
2502 std::vector<const CBlockIndex*> vBlocks;
2503 vBlocks.reserve(setDirtyBlockIndex.size());
2504 for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
2505 vBlocks.push_back(*it);
2506 setDirtyBlockIndex.erase(it++);
2508 if (!pblocktree->
WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
2509 return AbortNode(state,
"Failed to write to block index database");
2525 return state.
Error(
"out of disk space");
2527 if (!pcoinsTip->
Flush())
2528 return AbortNode(state,
"Failed to write to coin database");
2535 nLastSetChain = nNow;
2537 }
catch (
const std::runtime_error&
e) {
2538 return AbortNode(state, std::string(
"System error while flushing: ") + e.what());
2551 fCheckForPruning =
true;
2556 static void DoWarning(
const std::string& strWarning)
2558 static bool fWarned =
false;
2561 AlertNotify(strWarning);
2568 chainActive.
SetTip(pindexNew);
2575 std::vector<std::string> warningMessages;
2580 for (
int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
2584 const std::string strWarning =
strprintf(
_(
"Warning: unknown new rules activated (versionbit %i)"), bit);
2586 DoWarning(strWarning);
2588 warningMessages.push_back(strWarning);
2593 for (
int i = 0; i < 100 && pindex !=
nullptr; i++)
2596 if (pindex->
nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->
nVersion & ~nExpectedVersion) != 0)
2598 pindex = pindex->
pprev;
2601 warningMessages.push_back(
strprintf(
_(
"%d of last 100 blocks have unexpected version"), nUpgraded));
2602 if (nUpgraded > 100/2)
2604 std::string strWarning =
_(
"Warning: Unknown block versions being mined! It's possible unknown rules are in effect");
2606 DoWarning(strWarning);
2609 LogPrintf(
"%s: new best=%s height=%d version=0x%08x log2_work=%.8g tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)", __func__,
2614 if (!warningMessages.empty())
2615 LogPrintf(
" warning='%s'", boost::algorithm::join(warningMessages,
", "));
2635 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
2638 return AbortNode(state,
"Failed to read block");
2644 if (DisconnectBlock(block, pindexDelete, view,
nullptr) !=
DISCONNECT_OK)
2646 bool flushed = view.
Flush();
2654 if (disconnectpool) {
2656 for (
auto it = block.vtx.rbegin(); it != block.vtx.rend(); ++it) {
2659 while (disconnectpool->
DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) {
2668 UpdateTip(pindexDelete->
pprev, chainparams);
2675 static int64_t nTimeReadFromDisk = 0;
2676 static int64_t nTimeConnectTotal = 0;
2677 static int64_t nTimeFlush = 0;
2678 static int64_t nTimeChainState = 0;
2679 static int64_t nTimePostConnect = 0;
2698 block.
vtx.erase(block.
vtx.begin()+1,block.
vtx.end());
2704 gasLimit = blockGasLimit - 1;
2715 ByteCodeExec exec(block, std::vector<FascTransaction>(1, callTransaction), blockGasLimit);
2722 if(etp.gasPrice <
dev::u256(minGasPrice))
2731 std::vector<CTxOut> vTempVouts = block.
vtx[0]->vout;
2732 std::vector<CTxOut>::iterator it;
2733 for (
size_t i = 0; i < vouts.size(); i++) {
2734 it = std::find(vTempVouts.begin(), vTempVouts.end(), vouts[i]);
2735 if (it == vTempVouts.end()) {
2736 return state.
DoS(100,
error(
"CheckReward(): Gas refund missing"));
2739 vTempVouts.erase(it);
2745 if (block.
vtx[0]->GetValueOut() > blockReward)
2746 return state.
DoS(100,
error(
"CheckReward(): coinbase pays too much (actual=%d vs limit=%d)",
2747 block.
vtx[0]->GetValueOut(), blockReward), REJECT_INVALID,
"bad-cb-amount");
2754 bool scriptFilled=
false;
2758 for(
auto btx : *blockTxs){
2759 if(btx->GetHash() == tx.
vin[0].prevout.hash){
2760 script = btx->vout[tx.
vin[0].prevout.n].scriptPubKey;
2766 if(!scriptFilled && coinsView){
2768 scriptFilled =
true;
2775 script = txPrevout->vout[tx.
vin[0].prevout.n].scriptPubKey;
2777 LogPrintf(
"Error fetching transaction details of tx %s. This will probably cause more errors", tx.
vin[0].prevout.hash.ToString());
2786 addressBit.type() ==
typeid(
CKeyID)){
2787 CKeyID senderAddress(boost::get<CKeyID>(addressBit));
2831 boost::filesystem::path fascDir =
GetDataDir() /
"vmExecLogs.json";
2832 std::stringstream ss;
2836 std::ofstream file(fascDir.string(), std::ios::out | std::ios::app);
2837 file <<
"{\"logs\":[]}";
2841 for(
size_t i = 0; i < res.size(); i++){
2843 if(i != res.size() - 1){
2850 std::ofstream file(fascDir.string(), std::ios::in | std::ios::out);
2851 file.seekp(-2, std::ios::end);
2864 if(!tx.isCreation() && !
globalState->addressInUse(tx.receiveAddress())){
2879 for(
size_t i = 0; i < result.size(); i++){
2880 uint64_t gasUsed = (uint64_t) result[i].execRes.gasUsed;
2882 if(txs[i].value() > 0){
2891 if(txs[i].gas() > UINT64_MAX ||
2892 result[i].execRes.gasUsed > UINT64_MAX ||
2893 txs[i].gasPrice() > UINT64_MAX){
2896 uint64_t gas = (uint64_t) txs[i].gas();
2897 uint64_t gasPrice = (uint64_t) txs[i].gasPrice();
2900 int64_t amount = (gas - gasUsed) * gasPrice;
2926 for(
int i=0;i<256;i++){
2935 env.
setAuthor(EthAddrFromScript(block.
vtx[0]->vout[0].scriptPubKey));
2944 addressBit.type() ==
typeid(
CKeyID)){
2945 CKeyID addressKey(boost::get<CKeyID>(addressBit));
2946 std::vector<unsigned char> addr(addressKey.
begin(), addressKey.
end());
2955 std::vector<FascTransaction> resultTX;
2956 std::vector<EthTransactionParams> resultETP;
2957 for(
size_t i = 0; i < txBit.vout.size(); i++){
2958 if(txBit.vout[i].scriptPubKey.HasOpCreate() || txBit.vout[i].scriptPubKey.HasOpCall()){
2959 if(receiveStack(txBit.vout[i].scriptPubKey)){
2961 if(parseEthTXParams(params)){
2962 resultTX.push_back(createEthTX(params, i));
2963 resultETP.push_back(params);
2972 fasctx = std::make_pair(resultTX, resultETP);
2981 CScript scriptRest(stack.back().begin(), stack.back().end());
2985 if((opcode ==
OP_CREATE && stack.size() < 4) || (opcode ==
OP_CALL && stack.size() < 5)){
2999 vecAddr = stack.back();
3003 if(stack.size() < 4)
3006 if(stack.back().size() < 1){
3015 if(gasPrice > INT64_MAX || gasLimit > INT64_MAX){
3019 if(gasPrice !=0 && gasLimit > INT64_MAX / gasPrice){
3023 if(stack.back().size() > 4){
3036 LogPrintf(
"Incorrect parameters to VM.");
3096 assert(!blocksConnected.back().pindex);
3099 blocksConnected.back().pindex = pindex;
3100 blocksConnected.back().pblock = std::move(pblock);
3101 blocksConnected.emplace_back();
3110 assert(!blocksConnected.back().pindex);
3111 assert(blocksConnected.back().conflictedTxs->empty());
3112 blocksConnected.pop_back();
3113 return blocksConnected;
3117 assert(!blocksConnected.back().pindex);
3119 blocksConnected.back().conflictedTxs->emplace_back(std::move(txRemoved));
3135 std::shared_ptr<const CBlock> pthisBlock;
3137 std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
3139 return AbortNode(state,
"Failed to read block");
3140 pthisBlock = pblockNew;
3142 pthisBlock = pblock;
3144 const CBlock& blockConnecting = *pthisBlock;
3146 int64_t nTime2 =
GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
3148 LogPrint(
BCLog::BENCH,
" - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
3153 bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
3157 InvalidBlockFound(pindexNew, state);
3163 nTime3 =
GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
3164 LogPrint(
BCLog::BENCH,
" - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
3165 bool flushed = view.
Flush();
3168 int64_t nTime4 =
GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
3169 LogPrint(
BCLog::BENCH,
" - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
3173 int64_t nTime5 =
GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
3174 LogPrint(
BCLog::BENCH,
" - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
3179 UpdateTip(pindexNew, chainparams);
3181 int64_t nTime6 =
GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
3182 LogPrint(
BCLog::BENCH,
" - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
3183 LogPrint(
BCLog::BENCH,
"- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
3199 std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
3200 if (it == setBlockIndexCandidates.rend())
3208 bool fInvalidAncestor =
false;
3209 while (pindexTest && !chainActive.
Contains(pindexTest)) {
3218 if (fFailedChain || fMissingData) {
3220 if (fFailedChain && (pindexBestInvalid ==
nullptr || pindexNew->
nChainWork > pindexBestInvalid->nChainWork))
3221 pindexBestInvalid = pindexNew;
3224 while (pindexTest != pindexFailed) {
3227 }
else if (fMissingData) {
3231 mapBlocksUnlinked.insert(std::make_pair(pindexFailed->
pprev, pindexFailed));
3233 setBlockIndexCandidates.erase(pindexFailed);
3234 pindexFailed = pindexFailed->
pprev;
3236 setBlockIndexCandidates.erase(pindexTest);
3237 fInvalidAncestor =
true;
3240 pindexTest = pindexTest->
pprev;
3242 if (!fInvalidAncestor)
3248 static void PruneBlockIndexCandidates() {
3251 std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
3252 while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.
Tip())) {
3253 setBlockIndexCandidates.erase(it++);
3256 assert(!setBlockIndexCandidates.empty());
3270 bool fBlocksDisconnected =
false;
3272 while (chainActive.
Tip() && chainActive.
Tip() != pindexFork) {
3273 if (!DisconnectTip(state, chainparams, &disconnectpool)) {
3279 fBlocksDisconnected =
true;
3283 std::vector<CBlockIndex*> vpindexToConnect;
3284 int nHeight = pindexFork ? pindexFork->
nHeight : -1;
3285 bool fContinue =
true;
3286 while (fContinue && nHeight != pindexMostWork->
nHeight) {
3290 vpindexToConnect.clear();
3291 vpindexToConnect.reserve(nTargetHeight - nHeight);
3293 while (pindexIter && pindexIter->
nHeight != nHeight) {
3294 vpindexToConnect.push_back(pindexIter);
3295 pindexIter = pindexIter->
pprev;
3297 nHeight = nTargetHeight;
3301 if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
3305 InvalidChainFound(vpindexToConnect.back());
3307 fInvalidFound =
true;
3318 PruneBlockIndexCandidates();
3328 if (fBlocksDisconnected) {
3337 CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
3339 CheckForkWarningConditions();
3344 static void NotifyHeaderTip() {
3345 bool fNotify =
false;
3346 bool fInitialBlockDownload =
false;
3353 if (pindexHeader != pindexHeaderOld) {
3356 pindexHeaderOld = pindexHeader;
3378 int nStopAtHeight =
gArgs.
GetArg(
"-stopatheight", DEFAULT_STOPATHEIGHT);
3380 boost::this_thread::interruption_point();
3385 bool fInitialDownload;
3391 if (pindexMostWork ==
nullptr) {
3392 pindexMostWork = FindMostWorkChain();
3396 if (pindexMostWork ==
nullptr || pindexMostWork == chainActive.
Tip())
3399 bool fInvalidFound =
false;
3400 std::shared_ptr<const CBlock> nullBlockPtr;
3401 if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->
GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace))
3404 if (fInvalidFound) {
3406 pindexMostWork =
nullptr;
3408 pindexNewTip = chainActive.
Tip();
3409 pindexFork = chainActive.
FindFork(pindexOldTip);
3413 assert(trace.pblock && trace.pindex);
3425 if (pindexFork != pindexNewTip) {
3430 }
while (pindexNewTip != pindexMostWork);
3450 if (chainActive.
Tip()->
nChainWork > nLastPreciousChainwork) {
3452 nBlockReverseSequenceId = -1;
3455 setBlockIndexCandidates.erase(pindex);
3460 nBlockReverseSequenceId--;
3463 setBlockIndexCandidates.insert(pindex);
3464 PruneBlockIndexCandidates();
3482 setDirtyBlockIndex.insert(pindex);
3483 setBlockIndexCandidates.erase(pindex);
3484 bool pindex_was_in_chain =
false;
3488 while (chainActive.
Contains(pindex)) {
3491 setDirtyBlockIndex.insert(pindexWalk);
3492 setBlockIndexCandidates.erase(pindexWalk);
3493 pindex_was_in_chain =
true;
3496 if (!DisconnectTip(state, chainparams, &disconnectpool)) {
3507 while (pindex_was_in_chain && invalid_walk_tip != pindex) {
3509 setDirtyBlockIndex.insert(invalid_walk_tip);
3510 setBlockIndexCandidates.erase(invalid_walk_tip);
3511 invalid_walk_tip = invalid_walk_tip->
pprev;
3513 LimitMempoolSize(
mempool,
gArgs.
GetArg(
"-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
3517 setDirtyBlockIndex.insert(pindex);
3518 setBlockIndexCandidates.erase(pindex);
3519 g_failed_blocks.insert(pindex);
3529 if (it->second->IsValid(
BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.
Tip())) {
3530 setBlockIndexCandidates.insert(it->second);
3535 InvalidChainFound(pindex);
3544 int nHeight = pindex->
nHeight;
3549 if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
3551 setDirtyBlockIndex.insert(it->second);
3552 if (it->second->IsValid(
BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.
Tip(), it->second)) {
3553 setBlockIndexCandidates.insert(it->second);
3555 if (it->second == pindexBestInvalid) {
3557 pindexBestInvalid =
nullptr;
3559 g_failed_blocks.erase(it->second);
3565 while (pindex !=
nullptr) {
3568 setDirtyBlockIndex.insert(pindex);
3570 pindex = pindex->
pprev;
3590 BlockMap::iterator mi =
mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
3595 pindexNew->
pprev = (*miPrev).second;
3603 pindexBestHeader = pindexNew;
3605 setDirtyBlockIndex.insert(pindexNew);
3613 pindexNew->
nTx = block.
vtx.size();
3623 setDirtyBlockIndex.insert(pindexNew);
3627 std::deque<CBlockIndex*> queue;
3628 queue.push_back(pindexNew);
3631 while (!queue.empty()) {
3636 LOCK(cs_nBlockSequenceId);
3639 if (chainActive.
Tip() ==
nullptr || !setBlockIndexCandidates.value_comp()(pindex, chainActive.
Tip())) {
3640 setBlockIndexCandidates.insert(pindex);
3642 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
3643 while (range.first != range.second) {
3644 std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
3645 queue.push_back(it->second);
3647 mapBlocksUnlinked.erase(it);
3652 mapBlocksUnlinked.insert(std::make_pair(pindexNew->
pprev, pindexNew));
3659 static bool FindBlockPos(
CValidationState &state,
CDiskBlockPos &pos,
unsigned int nAddSize,
unsigned int nHeight, uint64_t nTime,
bool fKnown =
false)
3661 LOCK(cs_LastBlockFile);
3663 unsigned int nFile = fKnown ? pos.
nFile : nLastBlockFile;
3664 if (vinfoBlockFile.size() <= nFile) {
3665 vinfoBlockFile.resize(nFile + 1);
3669 while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
3671 if (vinfoBlockFile.size() <= nFile) {
3672 vinfoBlockFile.resize(nFile + 1);
3676 pos.
nPos = vinfoBlockFile[nFile].nSize;
3679 if ((
int)nFile != nLastBlockFile) {
3681 LogPrintf(
"Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
3683 FlushBlockFile(!fKnown);
3684 nLastBlockFile = nFile;
3687 vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
3689 vinfoBlockFile[nFile].nSize =
std::max(pos.
nPos + nAddSize, vinfoBlockFile[nFile].nSize);
3691 vinfoBlockFile[nFile].nSize += nAddSize;
3694 unsigned int nOldChunks = (pos.
nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3695 unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
3696 if (nNewChunks > nOldChunks) {
3698 fCheckForPruning =
true;
3702 LogPrintf(
"Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.
nFile);
3708 return state.
Error(
"out of disk space");
3712 setDirtyFileInfo.insert(nFile);
3720 LOCK(cs_LastBlockFile);
3722 unsigned int nNewSize;
3723 pos.
nPos = vinfoBlockFile[nFile].nUndoSize;
3724 nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
3725 setDirtyFileInfo.insert(nFile);
3727 unsigned int nOldChunks = (pos.
nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3728 unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
3729 if (nNewChunks > nOldChunks) {
3731 fCheckForPruning =
true;
3733 FILE *file = OpenUndoFile(pos);
3735 LogPrintf(
"Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.
nFile);
3741 return state.
Error(
"out of disk space");
3750 bool postfork = (uint32_t)block.
nHeight >= (uint32_t)consensusParams.
FABHeight;
3755 LogPrintf(
"CheckBlockHeader(): Equihash solution invalid at height %d\n", block.
nHeight);
3756 return state.
DoS(100,
error(
"CheckBlockHeader(): Equihash solution invalid"),
3757 REJECT_INVALID,
"invalid-solution");
3764 return state.
DoS(50,
false, REJECT_INVALID,
"high-hash",
false,
"proof of work failed");
3779 if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW))
3783 if (fCheckMerkleRoot) {
3787 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txnmrklroot",
true,
"hashMerkleRoot mismatch");
3793 return state.
DoS(100,
false, REJECT_INVALID,
"bad-txns-duplicate",
true,
"duplicate transaction");
3803 if (block.
vtx.empty() || !block.
vtx[0]->IsCoinBase())
3804 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-missing",
false,
"first tx is not coinbase");
3805 for (
unsigned int i = 1; i < block.
vtx.size(); i++)
3806 if (block.
vtx[i]->IsCoinBase())
3807 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-multiple",
false,
"more than one coinbase");
3809 if(block.
vtx[0]->HasOpSpend() || block.
vtx[0]->HasCreateOrCall()){
3810 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-contract",
false,
"coinbase must not contain OP_SPEND, OP_CALL, or OP_CREATE");
3813 bool lastWasContract=
false;
3815 for (
const auto& tx : block.
vtx) {
3822 if(tx->HasOpSpend()){
3823 if(!lastWasContract){
3824 return state.
DoS(100,
false, REJECT_INVALID,
"bad-opspend-tx",
false,
"OP_SPEND transaction without corresponding contract transaction");
3827 lastWasContract = tx->HasCreateOrCall() || tx->HasOpSpend();
3830 unsigned int nSigOps = 0;
3831 for (
const auto& tx : block.
vtx)
3836 return state.
DoS(100,
false, REJECT_INVALID,
"bad-blk-sigops",
false,
"out-of-bounds SigOpCount");
3838 if (fCheckPOW && fCheckMerkleRoot)
3852 static int GetWitnessCommitmentIndex(
const CBlock& block)
3855 if (!block.
vtx.empty()) {
3856 for (
size_t o = 0; o < block.
vtx[0]->vout.size(); o++) {
3857 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) {
3867 int commitpos = GetWitnessCommitmentIndex(block);
3868 static const std::vector<unsigned char> nonce(32, 0x00);
3869 if (commitpos != -1 &&
IsWitnessEnabled(pindexPrev, consensusParams) && !block.
vtx[0]->HasWitness()) {
3871 tx.
vin[0].scriptWitness.stack.resize(1);
3872 tx.
vin[0].scriptWitness.stack[0] = nonce;
3873 block.
vtx[0] = MakeTransactionRef(std::move(tx));
3879 std::vector<unsigned char> commitment;
3880 int commitpos = GetWitnessCommitmentIndex(block);
3881 std::vector<unsigned char> ret(32, 0x00);
3883 if (commitpos == -1) {
3898 tx.vout.push_back(out);
3899 block.
vtx[0] = MakeTransactionRef(std::move(tx));
3911 assert(pindexPrev !=
nullptr);
3912 const int nHeight = pindexPrev->
nHeight + 1;
3917 return state.
DoS(100,
false, REJECT_INVALID,
"bad-diffbits",
false,
"incorrect proof of work");
3925 if (pcheckpoint && nHeight < pcheckpoint->nHeight)
3926 return state.
DoS(100,
error(
"%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT,
"bad-fork-prior-to-checkpoint");
3938 return state.
Invalid(
false, REJECT_INVALID,
"time-too-old",
"block's timestamp is too early");
3943 LogPrintf(
" Debug block.GetBlockTime() =%d =%d MAX_FUTURE_BLOCK_TIME=%d MaxFutureBlockTime=%d", block.
GetBlockTime(), nAdjustedTime, MAX_FUTURE_BLOCK_TIME, consensusParams.
MaxFutureBlockTime);
3944 return state.
Invalid(
false, REJECT_INVALID,
"time-too-new",
"block timestamp too far in the future");
3960 const int nHeight = pindexPrev ==
nullptr ? 0 : pindexPrev->
nHeight + 1;
3963 int nLockTimeFlags = 0;
3973 for (
const auto& tx : block.
vtx) {
3974 if (!
IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
3975 return state.
DoS(10,
false, REJECT_INVALID,
"bad-txns-nonfinal",
false,
"non-final transaction");
3983 if (block.
vtx[0]->vin[0].scriptSig.size() < expect.
size() ||
3984 !std::equal(expect.
begin(), expect.
end(), block.
vtx[0]->vin[0].scriptSig.begin())) {
3985 return state.
DoS(100,
false, REJECT_INVALID,
"bad-cb-height",
false,
"block height mismatch in coinbase");
3997 bool fHaveWitness =
false;
3999 int commitpos = GetWitnessCommitmentIndex(block);
4000 if (commitpos != -1) {
4001 bool malleated =
false;
4006 if (block.
vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.
vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
4007 return state.
DoS(100,
false, REJECT_INVALID,
"bad-witness-nonce-size",
true,
strprintf(
"%s : invalid witness nonce size", __func__));
4010 if (memcmp(hashWitness.
begin(), &block.
vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
4011 return state.
DoS(100,
false, REJECT_INVALID,
"bad-witness-merkle-match",
true,
strprintf(
"%s : witness merkle commitment mismatch", __func__));
4013 fHaveWitness =
true;
4018 if (!fHaveWitness) {
4019 for (
const auto& tx : block.
vtx) {
4020 if (tx->HasWitness()) {
4021 return state.
DoS(100,
false, REJECT_INVALID,
"unexpected-witness",
true,
strprintf(
"%s : unexpected witness data found", __func__));
4033 return state.
DoS(100,
error(
"UpdateHashProof() : incorrect %s",
"proof-of-work" ));
4055 pindex = miSelf->second;
4059 return state.
Invalid(
error(
"%s: block %s is marked invalid", __func__, hash.
ToString()), 0,
"duplicate");
4064 int nBlockMaxConflict =
gArgs.
GetArg(
"-blockmaxconflict", 0);
4067 if ( (nBlockMaxConflict > 0 ) && (conflict_blocks >= nBlockMaxConflict ) ) {
4070 return state.
DoS(10,
error(
"block conflicted with current bestblock chain more than blockmaxconflict setting"), REJECT_INVALID,
"invalid-blocks-over-blockmaxconflict");
4074 if (!CheckBlockHeader(block, state, chainparams.
GetConsensus()))
4082 return state.
DoS(10,
error(
"%s: prev block not found", __func__), 0,
"prev-blk-not-found");
4083 pindexPrev = (*mi).second;
4085 return state.
DoS(100,
error(
"%s: prev block invalid", __func__), REJECT_INVALID,
"bad-prevblk");
4092 for (
const CBlockIndex* failedit : g_failed_blocks) {
4093 if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) {
4096 while (invalid_walk != failedit) {
4098 setDirtyBlockIndex.insert(invalid_walk);
4099 invalid_walk = invalid_walk->
pprev;
4101 return state.
DoS(100,
error(
"%s: prev block invalid", __func__), REJECT_INVALID,
"bad-prevblk");
4107 if (pindex ==
nullptr) {
4109 pindex = AddToBlockIndex(block);
4124 if (first_invalid !=
nullptr) first_invalid->
SetNull();
4130 if (!AcceptBlockHeader(header, state, chainparams, &pindex)) {
4131 if (first_invalid) *first_invalid = header;
4146 const CBlock& block = *pblock;
4148 if (fNewBlock) *fNewBlock =
false;
4152 CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
4154 if (!AcceptBlockHeader(block, state, chainparams, &pindex))
4162 int nHeight = pindex->
nHeight;
4166 return error(
"AcceptBlock() : rejected by synchronized checkpoint");
4170 if (block.
vtx[0]->vin[0].scriptSig.size() < expect.
size() ||
4171 !std::equal(expect.
begin(), expect.
end(), block.
vtx[0]->vin[0].scriptSig.begin()))
4172 return state.
DoS(100,
error(
"AcceptBlock() : block height mismatch in coinbase"));
4184 bool fTooFarAhead = (pindex->
nHeight > int(chainActive.
Height() + MIN_BLOCKS_TO_KEEP));
4193 if (fAlreadyHave)
return true;
4195 if (pindex->
nTx != 0)
return true;
4196 if (!fHasMoreOrSameWork)
return true;
4197 if (fTooFarAhead)
return true;
4203 if (pindex->
nChainWork < nMinimumChainWork)
return true;
4205 if (fNewBlock) *fNewBlock =
true;
4208 !ContextualCheckBlock(block, state, chainparams.
GetConsensus(), pindex->
pprev)) {
4211 setDirtyBlockIndex.insert(pindex);
4227 if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.
GetBlockTime(), dbp !=
nullptr))
4228 return error(
"AcceptBlock(): FindBlockPos failed");
4230 if (!WriteBlockToDisk(block, blockPos, chainparams.
MessageStart()))
4231 AbortNode(state,
"Failed to write block");
4232 if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.
GetConsensus()))
4233 return error(
"AcceptBlock(): ReceivedBlockTransactions failed");
4234 }
catch (
const std::runtime_error&
e) {
4235 return AbortNode(state, std::string(
"System error: ") + e.what());
4238 if (fCheckForPruning)
4244 bool static IsCanonicalBlockSignature(
const std::shared_ptr<const CBlock> pblock,
bool checkLowS)
4253 bool ret = IsCanonicalBlockSignature(pblock,
false);
4256 if(ret) ret = IsCanonicalBlockSignature(pblock,
true);
4265 if (fNewBlock) *fNewBlock =
false;
4274 return error(
"%s: CheckBlock FAILED", __func__);
4282 ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing,
nullptr, fNewBlock);
4289 return error(
"%s: AcceptBlock FAILED", __func__);
4299 return error(
"%s: ActivateBestChain failed", __func__);
4307 assert(pindexPrev && pindexPrev == chainActive.
Tip());
4310 indexDummy.
pprev = pindexPrev;
4318 if (!ContextualCheckBlock(block, state, chainparams.
GetConsensus(), pindexPrev))
4323 if (!ConnectBlock(block, state, &indexDummy, viewNew, chainparams,
true)) {
4341 static uint64_t CalculateCurrentUsage()
4343 uint64_t retval = 0;
4345 retval += file.nSize + file.nUndoSize;
4355 if (pindex->
nFile == fileNumber) {
4361 setDirtyBlockIndex.insert(pindex);
4367 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->
pprev);
4368 while (range.first != range.second) {
4369 std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
4371 if (_it->second == pindex) {
4372 mapBlocksUnlinked.erase(_it);
4378 vinfoBlockFile[fileNumber].SetNull();
4379 setDirtyFileInfo.insert(fileNumber);
4385 for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
4389 LogPrintf(
"Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
4394 static void FindFilesToPruneManual(std::set<int>& setFilesToPrune,
int nManualPruneHeight)
4398 LOCK2(cs_main, cs_LastBlockFile);
4399 if (chainActive.
Tip() ==
nullptr)
4403 unsigned int nLastBlockWeCanPrune =
std::min((
unsigned)nManualPruneHeight, chainActive.
Tip()->
nHeight - MIN_BLOCKS_TO_KEEP);
4405 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4406 if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
4409 setFilesToPrune.insert(fileNumber);
4412 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune, count);
4438 static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight)
4440 LOCK2(cs_main, cs_LastBlockFile);
4444 if ((uint64_t)chainActive.
Tip()->
nHeight <= nPruneAfterHeight) {
4448 unsigned int nLastBlockWeCanPrune = chainActive.
Tip()->
nHeight - MIN_BLOCKS_TO_KEEP;
4449 uint64_t nCurrentUsage = CalculateCurrentUsage();
4453 uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
4454 uint64_t nBytesToPrune;
4458 for (
int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
4459 nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
4461 if (vinfoBlockFile[fileNumber].nSize == 0)
4468 if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
4473 setFilesToPrune.insert(fileNumber);
4474 nCurrentUsage -= nBytesToPrune;
4479 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
4481 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
4482 nLastBlockWeCanPrune, count);
4487 uint64_t nFreeBytesAvailable = fs::space(
GetDataDir()).available;
4490 if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
4491 return AbortNode(
"Disk space is low!",
_(
"Error: Disk space is low!"));
4501 fs::create_directories(path.parent_path());
4503 if (!file && !fReadOnly)
4506 LogPrintf(
"Unable to open file %s\n", path.string());
4510 if (fseek(file, pos.
nPos, SEEK_SET)) {
4511 LogPrintf(
"Unable to seek to position %u of %s\n", pos.
nPos, path.string());
4520 return OpenDiskFile(pos,
"blk", fReadOnly);
4524 static FILE* OpenUndoFile(
const CDiskBlockPos &pos,
bool fReadOnly) {
4525 return OpenDiskFile(pos,
"rev", fReadOnly);
4541 return (*mi).second;
4546 throw std::runtime_error(std::string(__func__) +
": new CBlockIndex failed");
4547 mi =
mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
4548 pindexNew->phashBlock = &((*mi).first);
4553 bool static LoadBlockIndexDB(
const CChainParams& chainparams)
4558 boost::this_thread::interruption_point();
4561 std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
4563 for (
const std::pair<uint256, CBlockIndex*>& item :
mapBlockIndex)
4566 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
4568 sort(vSortedByHeight.begin(), vSortedByHeight.end());
4569 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight)
4576 if (pindex->
nTx > 0) {
4577 if (pindex->
pprev) {
4582 mapBlocksUnlinked.insert(std::make_pair(pindex->
pprev, pindex));
4590 setDirtyBlockIndex.insert(pindex);
4593 setBlockIndexCandidates.insert(pindex);
4595 pindexBestInvalid = pindex;
4599 pindexBestHeader = pindex;
4604 vinfoBlockFile.resize(nLastBlockFile + 1);
4605 LogPrintf(
"%s: last block file = %i\n", __func__, nLastBlockFile);
4606 for (
int nFile = 0; nFile <= nLastBlockFile; nFile++) {
4609 LogPrintf(
"%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
4610 for (
int nFile = nLastBlockFile + 1;
true; nFile++) {
4613 vinfoBlockFile.push_back(info);
4620 LogPrintf(
"Checking all blk files are present...\n");
4621 std::set<int> setBlkDataFiles;
4622 for (
const std::pair<uint256, CBlockIndex*>& item : mapBlockIndex)
4626 setBlkDataFiles.insert(pindex->
nFile);
4629 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
4640 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
4643 bool fReindexing =
false;
4649 LogPrintf(
"%s: transaction index %s\n", __func__,
fTxIndex ?
"enabled" :
"disabled");
4657 if (it == mapBlockIndex.end())
4659 chainActive.
SetTip(it->second);
4661 PruneBlockIndexCandidates();
4663 LogPrintf(
"%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
4678 LogPrintf(
"%s: Connecting genesis block...\n", __func__);
4689 chainActive.
SetTip(it->second);
4691 PruneBlockIndexCandidates();
4693 LogPrintf(
"Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
4713 if (chainActive.
Tip() ==
nullptr || chainActive.
Tip()->
pprev ==
nullptr)
4717 if (nCheckDepth <= 0 || nCheckDepth > chainActive.
Height())
4718 nCheckDepth = chainActive.
Height();
4720 LogPrintf(
"Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
4724 int nGoodTransactions = 0;
4735 boost::this_thread::interruption_point();
4736 int percentageDone =
std::max(1,
std::min(99, (
int)(((
double)(chainActive.
Height() - pindex->
nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
4737 if (reportDone < percentageDone/10) {
4740 reportDone = percentageDone/10;
4747 LogPrintf(
"VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->
nHeight);
4751 uint32_t sizeBlockDGP = fascDGP.getBlockSize(pindex->
nHeight);
4761 return error(
"%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
4764 if (nCheckLevel >= 2 && pindex) {
4780 pindexState = pindex->
pprev;
4782 nGoodTransactions = 0;
4783 pindexFailure = pindex;
4785 nGoodTransactions += block.
vtx.size();
4792 return error(
"VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.
Height() - pindexFailure->
nHeight + 1, nGoodTransactions);
4795 if (nCheckLevel >= 4) {
4797 while (pindex != chainActive.
Tip()) {
4798 boost::this_thread::interruption_point();
4800 pindex = chainActive.
Next(pindex);
4807 if (!ConnectBlock(block, state, pindex, coins, chainparams)) {
4822 LogPrintf(
"No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.
Height() - pindexState->
nHeight, nGoodTransactions);
4837 if (!tx->IsCoinBase()) {
4838 for (
const CTxIn &txin : tx->vin) {
4855 if (hashHeads.empty())
return true;
4856 if (hashHeads.size() != 2)
return error(
"ReplayBlocks(): unknown inconsistent state");
4866 return error(
"ReplayBlocks(): reorganization to unknown block requested");
4870 if (!hashHeads[1].IsNull()) {
4872 return error(
"ReplayBlocks(): reorganization from unknown block requested");
4876 assert(pindexFork !=
nullptr);
4880 while (pindexOld != pindexFork) {
4897 pindexOld = pindexOld->
pprev;
4901 int nForkHeight = pindexFork ? pindexFork->
nHeight : 0;
4902 for (
int nHeight = nForkHeight + 1; nHeight <= pindexNew->
nHeight; ++nHeight) {
4905 if (!RollforwardBlock(pindex, cache, params))
return false;
4921 while (nHeight <= chainActive.
Height()) {
4931 while (chainActive.
Height() >= nHeight) {
4940 if (!DisconnectTip(state, params,
nullptr)) {
4941 return error(
"RewindBlockIndex: unable to disconnect block at height %i", pindex->
nHeight);
4965 pindexIter->
nFile = 0;
4969 pindexIter->
nTx = 0;
4973 setDirtyBlockIndex.insert(pindexIter);
4975 setBlockIndexCandidates.erase(pindexIter);
4976 std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> ret = mapBlocksUnlinked.equal_range(pindexIter->
pprev);
4977 while (ret.first != ret.second) {
4978 if (ret.first->second == pindexIter) {
4979 mapBlocksUnlinked.erase(ret.first++);
4985 setBlockIndexCandidates.insert(pindexIter);
4989 if (chainActive.
Tip() !=
nullptr) {
4992 PruneBlockIndexCandidates();
5013 setBlockIndexCandidates.clear();
5014 chainActive.
SetTip(
nullptr);
5015 pindexBestInvalid =
nullptr;
5016 pindexBestHeader =
nullptr;
5018 mapBlocksUnlinked.clear();
5019 vinfoBlockFile.clear();
5021 nBlockSequenceId = 1;
5022 setDirtyBlockIndex.clear();
5023 g_failed_blocks.clear();
5024 setDirtyFileInfo.clear();
5026 for (
int b = 0;
b < VERSIONBITS_NUM_BITS;
b++) {
5027 warningcache[
b].clear();
5031 delete entry.second;
5033 mapBlockIndex.clear();
5042 bool ret = LoadBlockIndexDB(chainparams);
5043 if (!ret)
return false;
5054 LogPrintf(
"Initializing databases...\n");
5072 if (chainActive.
Genesis() !=
nullptr)
5082 LogPrintf(
"Initializing databases...\n");
5092 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.
GetBlockTime()))
5093 return error(
"LoadBlockIndex(): FindBlockPos failed");
5094 if (!WriteBlockToDisk(block, blockPos, chainparams.
MessageStart()))
5095 return error(
"LoadBlockIndex(): writing genesis block to disk failed");
5099 if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.
GetConsensus()))
5100 return error(
"LoadBlockIndex(): genesis block not accepted");
5104 }
catch (
const std::runtime_error&
e) {
5105 return error(
"LoadBlockIndex(): failed to initialize block database: %s", e.what());
5128 if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.
GetBlockTime()))
5129 return error(
"%s: FindBlockPos failed", __func__);
5130 if (!WriteBlockToDisk(block, blockPos, chainparams.
MessageStart()))
5131 return error(
"%s: writing genesis block to disk failed", __func__);
5134 if (!ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.
GetConsensus()))
5135 return error(
"%s: genesis block not accepted", __func__);
5136 }
catch (
const std::runtime_error&
e) {
5137 return error(
"%s: failed to write genesis block: %s", __func__, e.what());
5146 static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
5153 uint64_t nRewind = blkdat.
GetPos();
5154 while (!blkdat.
eof()) {
5155 boost::this_thread::interruption_point();
5160 unsigned int nSize = 0;
5165 nRewind = blkdat.
GetPos()+1;
5173 }
catch (
const std::exception&) {
5179 uint64_t nBlockPos = blkdat.
GetPos();
5181 dbp->
nPos = nBlockPos;
5182 blkdat.
SetLimit(nBlockPos + nSize);
5183 blkdat.
SetPos(nBlockPos);
5184 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
5187 nRewind = blkdat.
GetPos();
5190 uint256 hash = block.GetHash();
5193 block.hashPrevBlock.ToString());
5195 mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
5203 if (AcceptBlock(pblock, state, chainparams,
nullptr,
true, dbp,
nullptr))
5225 std::deque<uint256> queue;
5226 queue.push_back(hash);
5227 while (!queue.empty()) {
5230 std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
5231 while (range.first != range.second) {
5232 std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
5233 std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
5236 LogPrint(
BCLog::REINDEX,
"%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
5240 if (AcceptBlock(pblockrecursive, dummy, chainparams,
nullptr,
true, &it->second,
nullptr))
5243 queue.push_back(pblockrecursive->GetHash());
5247 mapBlocksUnknownParent.erase(it);
5251 }
catch (
const std::exception&
e) {
5252 LogPrintf(
"%s: Deserialize or I/O error - %s\n", __func__, e.what());
5255 }
catch (
const std::runtime_error&
e) {
5256 AbortNode(std::string(
"System error: ") + e.what());
5274 if (chainActive.
Height() < 0) {
5280 std::multimap<CBlockIndex*,CBlockIndex*> forward;
5282 forward.insert(std::make_pair(it->second->pprev, it->second));
5287 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(
nullptr);
5289 rangeGenesis.first++;
5290 assert(rangeGenesis.first == rangeGenesis.second);
5301 CBlockIndex* pindexFirstNotTransactionsValid =
nullptr;
5303 CBlockIndex* pindexFirstNotScriptsValid =
nullptr;
5304 while (pindex !=
nullptr) {
5308 if (pindexFirstNeverProcessed ==
nullptr && pindex->
nTx == 0) pindexFirstNeverProcessed = pindex;
5315 if (pindex->
pprev ==
nullptr) {
5326 assert(pindexFirstMissing == pindexFirstNeverProcessed);
5334 assert((pindexFirstNeverProcessed !=
nullptr) == (pindex->
nChainTx == 0));
5335 assert((pindexFirstNotTransactionsValid !=
nullptr) == (pindex->
nChainTx == 0));
5339 assert(pindexFirstNotTreeValid ==
nullptr);
5343 if (pindexFirstInvalid ==
nullptr) {
5347 if (!CBlockIndexWorkComparator()(pindex, chainActive.
Tip()) && pindexFirstNeverProcessed ==
nullptr) {
5348 if (pindexFirstInvalid ==
nullptr) {
5353 if (pindexFirstMissing ==
nullptr || pindex == chainActive.
Tip()) {
5354 assert(setBlockIndexCandidates.count(pindex));
5361 assert(setBlockIndexCandidates.count(pindex) == 0);
5364 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->
pprev);
5365 bool foundInUnlinked =
false;
5366 while (rangeUnlinked.first != rangeUnlinked.second) {
5367 assert(rangeUnlinked.first->first == pindex->
pprev);
5368 if (rangeUnlinked.first->second == pindex) {
5369 foundInUnlinked =
true;
5372 rangeUnlinked.first++;
5374 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed !=
nullptr && pindexFirstInvalid ==
nullptr) {
5379 if (pindexFirstMissing ==
nullptr)
assert(!foundInUnlinked);
5380 if (pindex->
pprev && (pindex->
nStatus &
BLOCK_HAVE_DATA) && pindexFirstNeverProcessed ==
nullptr && pindexFirstMissing !=
nullptr) {
5391 if (!CBlockIndexWorkComparator()(pindex, chainActive.
Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
5392 if (pindexFirstInvalid ==
nullptr) {
5401 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
5402 if (range.first != range.second) {
5404 pindex = range.first->second;
5413 if (pindex == pindexFirstInvalid) pindexFirstInvalid =
nullptr;
5414 if (pindex == pindexFirstMissing) pindexFirstMissing =
nullptr;
5415 if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed =
nullptr;
5416 if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid =
nullptr;
5417 if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid =
nullptr;
5418 if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid =
nullptr;
5419 if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid =
nullptr;
5423 std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
5424 while (rangePar.first->second != pindex) {
5425 assert(rangePar.first != rangePar.second);
5430 if (rangePar.first != rangePar.second) {
5432 pindex = rangePar.first->second;
5444 assert(nNodes == forward.size());
5449 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));
5454 return &vinfoBlockFile.at(n);
5475 static const uint64_t MEMPOOL_DUMP_VERSION = 1;
5480 int64_t nExpiryTimeout =
gArgs.
GetArg(
"-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
5484 LogPrintf(
"Failed to open mempool file from disk. Continuing anyway.\n");
5489 int64_t skipped = 0;
5496 if (version != MEMPOOL_DUMP_VERSION) {
5509 CAmount amountdelta = nFeeDelta;
5514 if (nTime + nExpiryTimeout > nNow) {
5528 std::map<uint256, CAmount> mapDeltas;
5531 for (
const auto& i : mapDeltas) {
5534 }
catch (
const std::exception&
e) {
5535 LogPrintf(
"Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
5539 LogPrintf(
"Imported mempool transactions from disk: %i successes, %i failed, %i expired\n", count, failed, skipped);
5547 std::map<uint256, CAmount> mapDeltas;
5548 std::vector<TxMempoolInfo> vinfo;
5553 mapDeltas[i.first] = i.second;
5568 uint64_t
version = MEMPOOL_DUMP_VERSION;
5571 file << (uint64_t)vinfo.size();
5572 for (
const auto& i : vinfo) {
5574 file << (int64_t)i.nTime;
5575 file << (int64_t)i.nFeeDelta;
5576 mapDeltas.erase(i.tx->GetHash());
5584 LogPrintf(
"Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*0.000001, (last-mid)*0.000001);
5585 }
catch (
const std::exception&
e) {
5586 LogPrintf(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
5592 if (pindex ==
nullptr)
5595 int64_t nNow = time(
nullptr);
5605 return pindex->
nChainTx / fTxTotal;
5616 delete (*it1).second;
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::pair< std::vector< FascTransaction >, std::vector< EthTransactionParams >> ExtractFascTX
const Coin & AccessByTxid(const CCoinsViewCache &view, const uint256 &txid)
Utility function to find any unspent output with a given txid.
CSHA256 & Write(const unsigned char *data, size_t len)
std::vector< ResultExecute > & getResult()
bool parseEthTXParams(EthTransactionParams ¶ms)
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 IsPayToPubkeyHash() const
bool error(const char *fmt, const Args &...args)
int Expire(int64_t time)
Expire all transaction (and their dependencies) in the mempool older than time.
dev::eth::ExecutionResult execRes
std::vector< Coin > vprevout
int64_t EndTime(const Consensus::Params ¶ms) const override
bool IsPayToPubkey() const
CDiskBlockPos GetBlockPos() const
void resize(size_type new_size)
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
std::function< void(uint64_t, uint64_t, dev::eth::Instruction, dev::bigint, dev::bigint, dev::bigint, dev::eth::VM *, dev::eth::ExtVMFace const *)> OnOpFunc
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
void AddCoin(const COutPoint &outpoint, Coin &&coin, bool potential_overwrite)
Add a coin.
void NotifyEntryRemoved(CTransactionRef txRemoved, MemPoolRemovalReason reason)
bool fPruneMode
True if we're running in -prune mode.
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params &consensusParams)
boost::condition_variable CConditionVariable
Just a typedef for boost::condition_variable, can be wrapped later if desired.
bool HaveCoinInCache(const COutPoint &outpoint) const
Check if we have the given utxo already loaded in this cache.
std::vector< CTransactionRef > conflictedTxs
void UnloadBlockIndex()
Unload database information.
void Add(std::vector< T > &vChecks)
bool CheckTxInputs(const CTransaction &tx, CValidationState &state, const CCoinsViewCache &inputs, int nSpendHeight)
Check whether all inputs of this transaction are valid (no double spends and amounts) This does not m...
FILE * fopen(const fs::path &p, const char *mode)
int Threshold(const Consensus::Params ¶ms) const override
bool EraseHeightIndex(const unsigned int &height)
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
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, ThresholdConditionCache &cache) const
bool CheckTransaction(const CTransaction &tx, CValidationState &state, bool fCheckDuplicateInputs)
Transaction validation functions.
bool EvaluateSequenceLocks(const CBlockIndex &block, std::pair< int, int64_t > lockPair)
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)
void SetBackend(CCoinsView &viewIn)
unsigned int dgpMaxBlockSerSize
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
bool performByteCode(dev::eth::Permanence type=dev::eth::Permanence::Committed)
void swap(CScriptCheck &check)
static const std::string REGTEST
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
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 ReadReindexing(bool &fReindex)
An in-memory indexed chain of blocks.
bool VerifyDB(const CChainParams &chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
bool receiveStack(const CScript &scriptPubKey)
bool InvalidateBlock(CValidationState &state, const CChainParams &chainparams, CBlockIndex *pindex)
Mark a block as invalid.
CAmount maxTxFee
Absolute maximum transaction fee (in liu) used by wallet and mempool (rejects high fee in sendrawtran...
uint256 GetWitnessHash() 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.
reverse_range< T > reverse_iterate(T &x)
CHash256 & Write(const unsigned char *data, size_t len)
int Period(const Consensus::Params ¶ms) const override
bool ReadLastBlockFile(int &nFile)
CWaitableCriticalSection csBestBlock
boost::signals2::signal< void(const uint256 &)> UpdatedTransaction
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
bool Condition(const CBlockIndex *pindex, const Consensus::Params ¶ms) const override
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...
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.
std::string GetHex() const
FascTransaction createEthTX(const EthTransactionParams &etp, const uint32_t nOut)
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool FlushStateToDisk()
Flush all state, indexes and buffers to disk.
static VersionVM GetEVMDefault()
static const std::string UNITTEST
const Consensus::Params & GetConsensus() const
bool CorruptionPossible() const
bool HaveInputs(const CTransaction &tx) const
Check whether all prevouts of the transaction are present in the UTXO set represented by this view...
CTxOut out
unspent transaction output
std::string ToString() const
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
h160 Address
An Ethereum address: 20 bytes.
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
cache implements a cache with properties similar to a cuckoo-set
stage after last reached validness failed
unsigned int fCoinBase
whether containing transaction was a coinbase
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
int64_t dgpMaxBlockSigOps
The maximum allowed number of signature check operations in a block (network rule) ...
int BIP66Height
Block height at which BIP66 becomes active.
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...
CTransactionRef get(const uint256 &hash) const
unsigned int GetCacheSize() const
Calculate the size of the cache (in number of transaction outputs)
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check)
Utility function to add all of a transaction's outputs to a cache.
uint256 BlockWitnessMerkleRoot(const CBlock &block, bool *mutated)
bool extractionFascTransactions(ExtractFascTX &fascTx)
std::set< txiter, CompareIteratorByHash > setEntries
bool SequenceLocks(const CTransaction &tx, int flags, std::vector< int > *prevHeights, const CBlockIndex &block)
Check if transaction is final per BIP 68 sequence numbers and can be included in a block...
void addTransaction(const CTransactionRef &tx)
std::hash for asio::adress
assert(len-trim+(2 *lenIndices)<=WIDTH)
ScriptError GetScriptError() const
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int ApplyTxInUndo(Coin &&undo, CCoinsViewCache &view, const COutPoint &out)
Restore the UTXO in a Coin at a given COutPoint.
CChainParams defines various tweakable parameters of a given instance of the Fabcoin system...
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
size_t DynamicMemoryUsage() const
undo data available in rev*.dat
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...
Access a block of memory.
boost::signals2::signal< void(const CTransaction &, const CBlockIndex *pindex, int posInBlock)> SyncTransaction
A hasher class for Fabcoin's 256-bit hash (double SHA-256).
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)
void setGasLimit(int64_t _v)
RAII-style controller object for a CCheckQueue that guarantees the passed queue is finished before co...
void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool fAddToMempool)
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Determine what nVersion a new block should use.
Description of the result of executing a transaction.
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.
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)
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.
const std::string strMessageMagic
bool IsFABHardForkEnabledForCurrentBlock(const Consensus::Params ¶ms)
uint32_t FABHeight
Block height at which Fabcoin Equihash hard fork becomes active.
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
bool ActivateBestChain(CValidationState &state, const CChainParams &chainparams, std::shared_ptr< const CBlock > pblock)
Make the best chain active, in multiple steps.
unsigned int dgpMaxBlockSize
indirectmap< COutPoint, const CTransaction * > mapNextTx
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
const std::vector< CTxIn > vin
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...
std::vector< TxMempoolInfo > infoAll() const
bool CheckSync(int nHeight)
Check against automatically selected checkpoint.
void UpdateTransactionsFromBlock(const std::vector< uint256 > &vHashesToUpdate)
When adding transactions from a disconnected block back to the mempool, new mempool entries may have ...
arith_uint256 UintToArith256(const uint256 &a)
bool ProcessNewBlockHeaders(const std::vector< CBlockHeader > &headers, CValidationState &state, const CChainParams &chainparams, const CBlockIndex **ppindex, CBlockHeader *first_invalid)
Process incoming block headers.
std::string ToString() const
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
int nSubsidyHalvingInterval
indexed_transaction_set mapTx
const char * ScriptErrorString(const ScriptError serror)
void Finalize(unsigned char hash[OUTPUT_SIZE])
int64_t CAmount
Amount in lius (Can be negative)
void SetBestBlock(const uint256 &hashBlock)
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams ¶ms)
Check whether the Equihash solution in a block header is valid.
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check for standard transaction types.
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyBlockTip
New block has been accepted.
bool ReadBlockFromDisk(Block &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
boost::signals2::signal< void(bool, const CBlockIndex *)> NotifyHeaderTip
Best header has changed.
bool IsFABHardForkEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
#define AssertLockHeld(cs)
CBlockPolicyEstimator feeEstimator
std::string NetworkIDString() const
Return the BIP70 network string (main, test or regtest)
uint32_t nHeight
at which height this containing transaction was included in the active block chain ...
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.
virtual std::vector< uint256 > GetHeadBlocks() const
Retrieve the range of blocks that may have been only partially written.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
void SetCorruptionPossible()
void SetfLargeWorkInvalidChainFound(bool flag)
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
int Height() const
Return the maximal height in the chain.
bool ReplayBlocks(const CChainParams ¶ms, CCoinsView *view)
Replay blocks that aren't fully applied to the database.
std::vector< h256 > LastHashes
opcodetype
Script opcodes.
unsigned int nTimeMax
(memory only) Maximum nTime in the chain upto and including this block.
bool TruncateFile(FILE *file, unsigned int length)
uint64_t PruneAfterHeight() const
bool push_back(const UniValue &val)
dev::h256 uintToh256(const uint256 &in)
bool CheckFinalTx(const CTransaction &tx, int flags)
Check if transaction will be final in the next block to be created.
FILE * OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
void PruneOneBlockFile(const int fileNumber)
Mark one block file as pruned.
bool CheckProofOfWork(uint256 hash, unsigned int nBits, bool postfork, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
unsigned int nStatus
Verification status of this block. See enum BlockStatus.
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...
int GetSpendHeight(const CCoinsViewCache &inputs)
Return the spend height, which is one more than the inputs.GetBestBlock().
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Access to the block database (blocks/index/)
unsigned int GetP2SHSigOpCount(const CTransaction &tx, const CCoinsViewCache &inputs)
Count ECDSA signature operations in pay-to-script-hash inputs.
Abstract view on the open txout dataset.
MemPoolConflictRemovalTracker(CTxMemPool &_pool)
void updateBlockSizeParams(unsigned int newBlockSize)
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
static uint64_t vch_to_uint64(const std::vector< unsigned char > &vch)
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.
void removeForBlock(const std::vector< CTransactionRef > &vtx)
An input of a transaction.
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...
std::function< void(std::string const &, char const *)> g_logPost
The current method that the logging system uses to output the log messages. Defaults to simpleDebugOu...
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * > > &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
int BIP34Height
Block height and hash at which BIP34 becomes active.
size_t DynamicMemoryUsage() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, txnouttype *typeRet)
uint64_t getBlockGasLimit(unsigned int blockHeight)
CBlockHeader GetBlockHeader() const
std::map< uint256, CAmount > mapDeltas
void CalculateDescendants(txiter it, setEntries &setDescendants)
Populate setDescendants with all in-mempool descendants of hash.
CAmount GetValueOut() const
uint32_t ContractHeight
Block height at which Fabcoin Smart Contract hard fork becomes active.
Abstract class that implements BIP9-style threshold logic, and caches results.
void setLastHashes(LastHashes &&_lh)
void NotifyEntryRemoved(CTransactionRef txRemoved, MemPoolRemovalReason reason)
void setTimestamp(u256 const &_v)
void Finalize(unsigned char hash[OUTPUT_SIZE])
dev::eth::EVMSchedule getGasSchedule(unsigned int blockHeight)
const std::vector< CTxOut > vout
const Coin & AccessCoin(const COutPoint &output) const
Return a reference to Coin in the cache, or a pruned one if not found.
bool AcceptToMemoryPoolWithTime(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, int64_t nAcceptTime, std::list< CTransactionRef > *plTxnReplaced=NULL, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0, bool rawTx=false)
(try to) add transaction to memory pool with a specified acceptance time
valtype GetSenderAddress(const CTransaction &tx, const CCoinsViewCache *coinsView, const std::vector< CTransactionRef > *blockTxs)
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
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...
const ChainTxData & TxData() const
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) ...
bool contains(const Element &e, const bool erase) const
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
std::shared_ptr< const CBlock > pblock
static VersionVM fromRaw(uint32_t val)
CMainSignals & GetMainSignals()
dev::Address receiveAddress
bytes asBytes(std::string const &_b)
Converts a string to a byte array containing the string's (byte) data.
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
void setNumber(u256 const &_v)
void BuildSkip()
Build the skiplist pointer for this entry.
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 TestLockPointValidity(const LockPoints *lp)
Test whether the LockPoints height and time are still valid on the current chain. ...
const CMessageHeader::MessageStartChars & MessageStart() const
std::string ToString() const
An output of a transaction.
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
bool ReadFromDisk(CBlockHeader &block, unsigned int nFile, unsigned int nBlockPos)
std::vector< uint256 > vHave
CBlockIndex * GetLastCheckpoint(const CCheckpointData &data)
Returns last CBlockIndex* in mapBlockIndex that is a checkpoint.
uint32_t nMinerConfirmationWindow
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
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.
Queue for verifications that have to be performed.
Parameters that influence chain consensus.
void ThreadScriptCheck()
Run an instance of the script checking thread.
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 CheckMinGasPrice(std::vector< EthTransactionParams > &etps, const uint64_t &minGasPrice)
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
void AddTransactionsUpdated(unsigned int n)
bool processingResults(ByteCodeExecResult &result)
std::vector< CTxOut > vout
bool RenameOver(fs::path src, fs::path dest)
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
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.
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.
indexed_transaction_set::nth_index< 0 >::type::iterator txiter
block data in blk*.data was received with a witness-enforcing client
VersionBitsCache versionbitscache
TransactionException excepted
void BlockConnected(CBlockIndex *pindex, std::shared_ptr< const CBlock > pblock)
bool ReadFlag(const std::string &name, bool &fValue)
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool fOverrideMempoolLimit, const CAmount nAbsurdFee, bool rawTx)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
uint256 hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo)
unsigned int GetLegacySigOpCount(const CTransaction &tx)
Auxiliary functions for transaction validation (ideally should not be exposed)
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos)
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
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 ...
int BIP65Height
Block height at which BIP65 becomes active.
bool LoadBlockIndex(const CChainParams &chainparams)
Load the block tree and coins database from disk, initializing state if we're running with -reindex...
bool exists(uint256 hash) const
void setVersion(VersionVM v)
bool Error(const std::string &strRejectReasonIn)
std::string GetRejectReason() const
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.
void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const
unsigned int GetRejectCode() const
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
void DumpMempool(void)
Dump the mempool to disk.
std::shared_ptr< std::vector< CTransactionRef > > conflictedTxs
std::string ToString() const
#define LogPrint(category,...)
std::string ToString() const
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
CAmount GetFee(size_t nBytes) const
Return the fee in liu for the given size in bytes.
std::vector< ResultExecute > CallContract(const dev::Address &addrContract, std::vector< unsigned char > opcode, const dev::Address &sender, uint64_t gasLimit)
bool CheckCanonicalBlockSignature(const std::shared_ptr< const CBlock > pblock)
Capture information about block/transaction validation.
int64_t nTimeout
Timeout/expiry MedianTime for the deployment attempt.
bool LoadExternalBlockFile(const CChainParams &chainparams, FILE *fileIn, CDiskBlockPos *dbp)
Import blocks from an external file.
uint256 nMinimumChainWork
std::vector< CTransactionRef > vtx
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.
unsigned int dgpMaxTxSigOps
The maximum number of sigops we're willing to relay/mine in a single tx.
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...
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void check(const CCoinsViewCache *pcoins) const
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
Template mixin that adds -Wthread-safety locking annotations to a subset of the mutex API...
static const int SYNC_TRANSACTION_NOT_IN_BLOCK
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...
PlatformStyle::TableColorType type
CAmount GetValueIn(const CTransaction &tx) const
Amount of fabcoins coming in to a transaction Note that lightweight clients may not know anything bes...
bool ResetBlockFailureFlags(CBlockIndex *pindex)
Remove invalidity status from a block and its descendants.
The block chain is a tree shaped structure starting with the genesis block at the root...
const CBlock & GenesisBlock() const
const CChainParams & Params()
Return the currently selected parameters.
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
boost::signals2::signal< void()> NotifyAlertChanged
Status bar alerts changed.
int64_t MaxFutureBlockTime
Limit BITCOIN_MAX_FUTURE_BLOCK_TIME.
Undo information for a CTransaction.
std::atomic_bool fImporting(false)
void * memcpy(void *a, const void *b, size_t c)
std::vector< PerBlockConnectTrace > blocksConnected
std::vector< unsigned char > GenerateCoinbaseCommitment(CBlock &block, const CBlockIndex *pindexPrev, const Consensus::Params &consensusParams)
Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks...
bool GetfLargeWorkForkFound()
CCoinsView backed by the coin database (chainstate/)
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
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.
void PruneBlockFilesManual(int nManualPruneHeight)
Prune block files up to a given height.
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
int64_t GetAdjustedTime()
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)
bool LoadMempool(void)
Load the mempool from disk.
void addResult(dev::h256 hashTx, std::vector< TransactionReceiptInfo > &result)
unsigned int GetNextWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, const Consensus::Params ¶ms)
bool HasCreateOrCall() const
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
bool PreciousBlock(CValidationState &state, const CChainParams ¶ms, CBlockIndex *pindex)
Mark a block as precious and reorganize.
A reference to a CKey: the Hash160 of its serialized public key.
VersionVM getVersion() const
void forceSender(Address const &_a)
Force the sender to a particular value. This will result in an invalid transaction RLP...
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
void SetMiscWarning(const std::string &strWarning)
bool WriteTxIndex(const std::vector< std::pair< uint256, CDiskTxPos > > &list)
bool CheckReward(const CBlock &block, CValidationState &state, int nHeight, const Consensus::Params &consensusParams, CAmount nFees, CAmount gasRefunds, const std::vector< CTxOut > &vouts)
Fee rate in liu per kilobyte: CAmount / kB.
void setAuthor(Address const &_v)
bool RequireStandard() const
Policy: Filter transactions that do not match well-defined patterns.
std::string GetDebugMessage() const
dev::eth::EnvInfo BuildEVMEnvironment()
int64_t GetTransactionSigOpCost(const CTransaction &tx, const CCoinsViewCache &inputs, int flags)
Compute total signature operation cost of a transaction.
std::string ToString() const
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
void writeVMlog(const std::vector< ResultExecute > &res, const CTransaction &tx, const CBlock &block)
bool IsWitnessEnabled(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms)
Check whether witness commitments are required for block.
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)
A mutable version of CTransaction.
A writer stream (for serialization) that computes a 256-bit hash.
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period...
const uint256 & GetHash() const
std::vector< unsigned char > valtype
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)
void removeForBlock(const std::vector< CTransactionRef > &vtx, unsigned int nBlockHeight)
Called when a block is connected.
arith_uint256 GetBlockProof(const CBlockIndex &block)
std::vector< CTxOut > refundOutputs
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
CDiskBlockPos GetUndoPos() const
void BlockDisconnected(const std::shared_ptr< const CBlock > &)
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
CClientUIInterface uiInterface
The basic transaction that is broadcasted on the network and contained in blocks. ...
int nHeight
height of the entry in the chain. The genesis block has height 0
WarningBitsConditionChecker(int bitIn)
std::unordered_map< uint256, CBlockIndex *, BlockHasher > BlockMap
bool WriteHeightIndex(const CHeightTxIndexKey &heightIndex, const std::vector< uint256 > &hash)
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)
void deleteResults(std::vector< CTransactionRef > const &txs)
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 setDifficulty(u256 const &_v)
CBlockIndex * InsertBlockIndex(uint256 hash)
Create a new block index entry for a given block hash.
bool Invalid(bool ret=false, unsigned int _chRejectCode=0, const std::string &_strRejectReason="", const std::string &_strDebugMessage="")
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to deserialize from...
UniValue vmLogToJSON(const ResultExecute &execRes, const CTransaction &tx, const CBlock &block)
int64_t GetBlockTime() const
A hasher class for SHA-256.
void setNVout(uint32_t vout)
bool CheckSenderScript(const CCoinsViewCache &view, const CTransaction &tx)
dev::Address EthAddrFromScript(const CScript &scriptIn)
std::vector< CTxUndo > vtxundo
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, Consensus::DeploymentPos pos, VersionBitsCache &cache)
void SetfLargeWorkForkFound(bool flag)
Removed for conflict with in-block transaction.
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...
CBlockIndex * maxInputBlock
fs::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
Translation to a filesystem path.
int64_t GetMedianTimePast() const
CCoinsView that brings transactions from a memorypool into view.
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
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.
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags)
void removeEntry(indexed_disconnected_transactions::index< insertion_order >::type::iterator entry)
unsigned int nTx
Number of transactions in this block.
std::unique_ptr< FascState > globalState
Global state.
StorageResults * pstorageresult
bool ContextualCheckBlockHeader(const CBlockHeader &block, CValidationState &state, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev, int64_t nAdjustedTime)
Context-dependent validity checks.
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*.
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.
const CCheckpointData & Checkpoints() const
void setHashWith(const dev::h256 hash)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
uint256 h256Touint(const dev::h256 &in)
uint64_t getMinGasPrice(unsigned int blockHeight)
~MemPoolConflictRemovalTracker()
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]
void UpdateCoins(const CTransaction &tx, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
dev::eth::TransactionReceipt txRec
void RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason=MemPoolRemovalReason::UNKNOWN)
Remove a set of transactions from the mempool.
std::shared_ptr< dev::eth::SealEngineFace > globalSealEngine
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...
uint256 GetBlockHash() const
std::vector< LogEntry > LogEntries
CConditionVariable cvBlockChange
unsigned int dgpMaxBlockWeight
The maximum allowed weight for a block, see BIP 141 (network rule)
bool InitBlockIndex(const CChainParams &chainparams)
Initialize a new block tree database + block data on disk.
bool IsConfirmedInNPrevBlocks(const CDiskTxPos &txindex, const CBlockIndex *pindexFrom, int nMaxDepth, int &nActualDepth)
Check if the transaction is confirmed in N previous blocks.
size_t DynamicMemoryUsage() const
Calculate the size of the cache (in bytes)
Used to track blocks whose transactions were applied to the UTXO state as a part of a single Activate...
LogEntries const & log() const
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
void TransactionAddedToMempool(const CTransactionRef &)
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
std::vector< CTransaction > valueTransfers
Threshold condition checker that triggers when unknown versionbits are seen on the network...