Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show All 14 Lines | |||||
#include <config.h> | #include <config.h> | ||||
#include <consensus/activation.h> | #include <consensus/activation.h> | ||||
#include <consensus/consensus.h> | #include <consensus/consensus.h> | ||||
#include <consensus/merkle.h> | #include <consensus/merkle.h> | ||||
#include <consensus/tx_verify.h> | #include <consensus/tx_verify.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <fs.h> | #include <fs.h> | ||||
#include <hash.h> | #include <hash.h> | ||||
#include <index/txindex.h> | |||||
#include <init.h> | #include <init.h> | ||||
#include <policy/fees.h> | #include <policy/fees.h> | ||||
#include <policy/policy.h> | #include <policy/policy.h> | ||||
#include <pow.h> | #include <pow.h> | ||||
#include <primitives/block.h> | #include <primitives/block.h> | ||||
#include <primitives/transaction.h> | #include <primitives/transaction.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <reverse_iterator.h> | #include <reverse_iterator.h> | ||||
▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | |||||
CChain &chainActive = g_chainstate.chainActive; | CChain &chainActive = g_chainstate.chainActive; | ||||
CBlockIndex *pindexBestHeader = nullptr; | CBlockIndex *pindexBestHeader = nullptr; | ||||
Mutex g_best_block_mutex; | Mutex g_best_block_mutex; | ||||
std::condition_variable g_best_block_cv; | std::condition_variable g_best_block_cv; | ||||
uint256 g_best_block; | uint256 g_best_block; | ||||
int nScriptCheckThreads = 0; | int nScriptCheckThreads = 0; | ||||
std::atomic_bool fImporting(false); | std::atomic_bool fImporting(false); | ||||
std::atomic_bool fReindex(false); | std::atomic_bool fReindex(false); | ||||
bool fTxIndex = false; | |||||
bool fHavePruned = false; | bool fHavePruned = false; | ||||
bool fPruneMode = false; | bool fPruneMode = false; | ||||
bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; | bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; | ||||
bool fRequireStandard = true; | bool fRequireStandard = true; | ||||
bool fCheckBlockIndex = false; | bool fCheckBlockIndex = false; | ||||
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; | bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; | ||||
size_t nCoinCacheUsage = 5000 * 300; | size_t nCoinCacheUsage = 5000 * 300; | ||||
uint64_t nPruneTarget = 0; | uint64_t nPruneTarget = 0; | ||||
▲ Show 20 Lines • Show All 648 Lines • ▼ Show 20 Lines | bool GetTransaction(const Config &config, const TxId &txid, | ||||
if (!blockIndex) { | if (!blockIndex) { | ||||
CTransactionRef ptx = g_mempool.get(txid); | CTransactionRef ptx = g_mempool.get(txid); | ||||
if (ptx) { | if (ptx) { | ||||
txOut = ptx; | txOut = ptx; | ||||
return true; | return true; | ||||
} | } | ||||
if (fTxIndex) { | if (g_txindex) { | ||||
CDiskTxPos postx; | return g_txindex->FindTx(txid, hashBlock, txOut); | ||||
if (pblocktree->ReadTxIndex(txid, postx)) { | |||||
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, | |||||
CLIENT_VERSION); | |||||
if (file.IsNull()) { | |||||
return error("%s: OpenBlockFile failed", __func__); | |||||
} | |||||
CBlockHeader header; | |||||
try { | |||||
file >> header; | |||||
fseek(file.Get(), postx.nTxOffset, SEEK_CUR); | |||||
file >> txOut; | |||||
} catch (const std::exception &e) { | |||||
return error("%s: Deserialize or I/O error - %s", __func__, | |||||
e.what()); | |||||
} | |||||
hashBlock = header.GetHash(); | |||||
if (txOut->GetId() != txid) { | |||||
return error("%s: txid mismatch", __func__); | |||||
} | |||||
return true; | |||||
} | |||||
// transaction not found in index, nothing more can be done | |||||
return false; | |||||
} | } | ||||
// use coin database to locate block that contains transaction, and scan | // use coin database to locate block that contains transaction, and scan | ||||
// it | // it | ||||
if (fAllowSlow) { | if (fAllowSlow) { | ||||
const Coin &coin = AccessByTxid(*pcoinsTip, txid); | const Coin &coin = AccessByTxid(*pcoinsTip, txid); | ||||
if (!coin.IsSpent()) { | if (!coin.IsSpent()) { | ||||
pindexSlow = chainActive[coin.GetHeight()]; | pindexSlow = chainActive[coin.GetHeight()]; | ||||
▲ Show 20 Lines • Show All 690 Lines • ▼ Show 20 Lines | if (pindex->GetUndoPos().IsNull()) { | ||||
pindex->nUndoPos = _pos.nPos; | pindex->nUndoPos = _pos.nPos; | ||||
pindex->nStatus = pindex->nStatus.withUndo(); | pindex->nStatus = pindex->nStatus.withUndo(); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool WriteTxIndexDataForBlock(const CBlock &block, | |||||
CValidationState &state, | |||||
CBlockIndex *pindex) { | |||||
CDiskTxPos pos(pindex->GetBlockPos(), | |||||
GetSizeOfCompactSize(block.vtx.size())); | |||||
std::vector<std::pair<uint256, CDiskTxPos>> vPos; | |||||
vPos.reserve(block.vtx.size()); | |||||
for (const CTransactionRef &tx : block.vtx) { | |||||
vPos.push_back(std::make_pair(tx->GetHash(), pos)); | |||||
pos.nTxOffset += ::GetSerializeSize(*tx, SER_DISK, CLIENT_VERSION); | |||||
} | |||||
if (fTxIndex) { | |||||
if (!pblocktree->WriteTxIndex(vPos)) { | |||||
return AbortNode(state, "Failed to write transaction index"); | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
static CCheckQueue<CScriptCheck> scriptcheckqueue(128); | static CCheckQueue<CScriptCheck> scriptcheckqueue(128); | ||||
void ThreadScriptCheck() { | void ThreadScriptCheck() { | ||||
RenameThread("bitcoin-scriptch"); | RenameThread("bitcoin-scriptch"); | ||||
scriptcheckqueue.Thread(); | scriptcheckqueue.Thread(); | ||||
} | } | ||||
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, | int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, | ||||
▲ Show 20 Lines • Show All 372 Lines • ▼ Show 20 Lines | if (!WriteUndoDataForBlock(blockundo, state, pindex, | ||||
return false; | return false; | ||||
} | } | ||||
if (!pindex->IsValid(BlockValidity::SCRIPTS)) { | if (!pindex->IsValid(BlockValidity::SCRIPTS)) { | ||||
pindex->RaiseValidity(BlockValidity::SCRIPTS); | pindex->RaiseValidity(BlockValidity::SCRIPTS); | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
if (!WriteTxIndexDataForBlock(block, state, pindex)) { | |||||
return false; | |||||
} | |||||
assert(pindex->phashBlock); | assert(pindex->phashBlock); | ||||
// add this block to the view's block chain | // add this block to the view's block chain | ||||
view.SetBestBlock(pindex->GetBlockHash()); | view.SetBestBlock(pindex->GetBlockHash()); | ||||
int64_t nTime5 = GetTimeMicros(); | int64_t nTime5 = GetTimeMicros(); | ||||
nTimeIndex += nTime5 - nTime4; | nTimeIndex += nTime5 - nTime4; | ||||
LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n", | LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n", | ||||
MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, | MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, | ||||
▲ Show 20 Lines • Show All 2,536 Lines • ▼ Show 20 Lines | bool static LoadBlockIndexDB(const Config &config) { | ||||
// Check whether we need to continue reindexing | // Check whether we need to continue reindexing | ||||
bool fReindexing = false; | bool fReindexing = false; | ||||
pblocktree->ReadReindexing(fReindexing); | pblocktree->ReadReindexing(fReindexing); | ||||
if (fReindexing) { | if (fReindexing) { | ||||
fReindex = true; | fReindex = true; | ||||
} | } | ||||
// Check whether we have a transaction index | |||||
pblocktree->ReadFlag("txindex", fTxIndex); | |||||
LogPrintf("%s: transaction index %s\n", __func__, | |||||
fTxIndex ? "enabled" : "disabled"); | |||||
return true; | return true; | ||||
} | } | ||||
bool LoadChainTip(const Config &config) { | bool LoadChainTip(const Config &config) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (chainActive.Tip() && | if (chainActive.Tip() && | ||||
chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) { | chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) { | ||||
▲ Show 20 Lines • Show All 441 Lines • ▼ Show 20 Lines | bool LoadBlockIndex(const Config &config) { | ||||
if (needs_init) { | if (needs_init) { | ||||
// Everything here is for *new* reindex/DBs. Thus, though | // Everything here is for *new* reindex/DBs. Thus, though | ||||
// LoadBlockIndexDB may have set fReindex if we shut down | // LoadBlockIndexDB may have set fReindex if we shut down | ||||
// mid-reindex previously, we don't check fReindex and | // mid-reindex previously, we don't check fReindex and | ||||
// instead only check it prior to LoadBlockIndexDB to set | // instead only check it prior to LoadBlockIndexDB to set | ||||
// needs_init. | // needs_init. | ||||
LogPrintf("Initializing databases...\n"); | LogPrintf("Initializing databases...\n"); | ||||
// Use the provided setting for -txindex in the new database | |||||
fTxIndex = gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX); | |||||
pblocktree->WriteFlag("txindex", fTxIndex); | |||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CChainState::LoadGenesisBlock(const CChainParams &chainparams) { | bool CChainState::LoadGenesisBlock(const CChainParams &chainparams) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
// Check whether we're already initialized by checking for genesis in | // Check whether we're already initialized by checking for genesis in | ||||
▲ Show 20 Lines • Show All 691 Lines • Show Last 20 Lines |