Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 146 Lines • ▼ Show 20 Lines | public: | ||||
// Block (dis)connection on a given view: | // Block (dis)connection on a given view: | ||||
DisconnectResult DisconnectBlock(const CBlock &block, | DisconnectResult DisconnectBlock(const CBlock &block, | ||||
const CBlockIndex *pindex, | const CBlockIndex *pindex, | ||||
CCoinsViewCache &view); | CCoinsViewCache &view); | ||||
bool ConnectBlock(const CBlock &block, CValidationState &state, | bool ConnectBlock(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindex, CCoinsViewCache &view, | CBlockIndex *pindex, CCoinsViewCache &view, | ||||
const CChainParams ¶ms, | const CChainParams ¶ms, | ||||
BlockValidationOptions options, bool fJustCheck = false); | BlockValidationOptions options, bool fJustCheck = false) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
// Block disconnection on our pcoinsTip: | // Block disconnection on our pcoinsTip: | ||||
bool DisconnectTip(const Config &config, CValidationState &state, | bool DisconnectTip(const Config &config, CValidationState &state, | ||||
DisconnectedBlockTransactions *disconnectpool); | DisconnectedBlockTransactions *disconnectpool) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
// Manual block validity manipulation: | // Manual block validity manipulation: | ||||
bool PreciousBlock(const Config &config, CValidationState &state, | bool PreciousBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex); | CBlockIndex *pindex); | ||||
bool UnwindBlock(const Config &config, CValidationState &state, | bool UnwindBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex, bool invalidate); | CBlockIndex *pindex, bool invalidate); | ||||
bool ResetBlockFailureFlags(CBlockIndex *pindex); | bool ResetBlockFailureFlags(CBlockIndex *pindex); | ||||
template <typename F> | template <typename F> | ||||
void UpdateFlagsForBlock(CBlockIndex *pindexBase, CBlockIndex *pindex, F f); | void UpdateFlagsForBlock(CBlockIndex *pindexBase, CBlockIndex *pindex, F f); | ||||
template <typename F, typename C> | template <typename F, typename C> | ||||
void UpdateFlags(CBlockIndex *pindex, F f, C fchild); | void UpdateFlags(CBlockIndex *pindex, F f, C fchild) | ||||
template <typename F> void UpdateFlags(CBlockIndex *pindex, F f); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
template <typename F> | |||||
void UpdateFlags(CBlockIndex *pindex, F f) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
/** Remove parked status from a block and its descendants. */ | /** Remove parked status from a block and its descendants. */ | ||||
bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren); | bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren); | ||||
bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view); | bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view); | ||||
bool RewindBlockIndex(const Config &config); | bool RewindBlockIndex(const Config &config); | ||||
bool LoadGenesisBlock(const CChainParams &chainparams); | bool LoadGenesisBlock(const CChainParams &chainparams); | ||||
void PruneBlockIndexCandidates(); | void PruneBlockIndexCandidates(); | ||||
void UnloadBlockIndex(); | void UnloadBlockIndex(); | ||||
private: | private: | ||||
bool ActivateBestChainStep(const Config &config, CValidationState &state, | bool ActivateBestChainStep(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindexMostWork, | CBlockIndex *pindexMostWork, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
bool &fInvalidFound, ConnectTrace &connectTrace); | bool &fInvalidFound, ConnectTrace &connectTrace) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
bool ConnectTip(const Config &config, CValidationState &state, | bool ConnectTip(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
ConnectTrace &connectTrace, | ConnectTrace &connectTrace, | ||||
DisconnectedBlockTransactions &disconnectpool); | DisconnectedBlockTransactions &disconnectpool) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
CBlockIndex *AddToBlockIndex(const CBlockHeader &block); | CBlockIndex *AddToBlockIndex(const CBlockHeader &block) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
/** Create a new block index entry for a given block hash */ | /** Create a new block index entry for a given block hash */ | ||||
CBlockIndex *InsertBlockIndex(const uint256 &hash); | CBlockIndex *InsertBlockIndex(const uint256 &hash); | ||||
void CheckBlockIndex(const Consensus::Params &consensusParams); | void CheckBlockIndex(const Consensus::Params &consensusParams); | ||||
void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state); | void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) | ||||
CBlockIndex *FindMostWorkChain(); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
CBlockIndex *FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const FlatFilePos &pos); | const FlatFilePos &pos) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
Fabien: This one is from PR13481 | |||||
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | ||||
const Consensus::Params ¶ms); | const Consensus::Params ¶ms); | ||||
} g_chainstate; | } g_chainstate; | ||||
/** | /** | ||||
* Global state | * Global state | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | ||||
int nManualPruneHeight); | int nManualPruneHeight); | ||||
static void FindFilesToPrune(std::set<int> &setFilesToPrune, | static void FindFilesToPrune(std::set<int> &setFilesToPrune, | ||||
uint64_t nPruneAfterHeight); | uint64_t nPruneAfterHeight); | ||||
static FILE *OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false); | static FILE *OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false); | ||||
static FlatFileSeq BlockFileSeq(); | static FlatFileSeq BlockFileSeq(); | ||||
static FlatFileSeq UndoFileSeq(); | static FlatFileSeq UndoFileSeq(); | ||||
static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | ||||
const CBlockIndex *pindex); | const CBlockIndex *pindex) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | |||||
bool TestLockPointValidity(const LockPoints *lp) { | bool TestLockPointValidity(const LockPoints *lp) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
assert(lp); | assert(lp); | ||||
// If there are relative lock times then the maxInputBlock will be set | // If there are relative lock times then the maxInputBlock will be set | ||||
// If there are no relative lock times, the LockPoints don't depend on the | // If there are no relative lock times, the LockPoints don't depend on the | ||||
// chain | // chain | ||||
if (lp->maxInputBlock) { | if (lp->maxInputBlock) { | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
std::string FormatStateMessage(const CValidationState &state) { | std::string FormatStateMessage(const CValidationState &state) { | ||||
return strprintf( | return strprintf( | ||||
"%s%s (code %i)", state.GetRejectReason(), | "%s%s (code %i)", state.GetRejectReason(), | ||||
state.GetDebugMessage().empty() ? "" : ", " + state.GetDebugMessage(), | state.GetDebugMessage().empty() ? "" : ", " + state.GetDebugMessage(), | ||||
state.GetRejectCode()); | state.GetRejectCode()); | ||||
} | } | ||||
static bool | static bool | ||||
IsMagneticAnomalyEnabledForCurrentBlock(const Consensus::Params ¶ms) { | IsMagneticAnomalyEnabledForCurrentBlock(const Consensus::Params ¶ms) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return IsMagneticAnomalyEnabled(params, chainActive.Tip()); | return IsMagneticAnomalyEnabled(params, chainActive.Tip()); | ||||
} | } | ||||
static bool IsGravitonEnabledForCurrentBlock(const Consensus::Params ¶ms) { | static bool IsGravitonEnabledForCurrentBlock(const Consensus::Params ¶ms) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return IsGravitonEnabled(params, chainActive.Tip()); | return IsGravitonEnabled(params, chainActive.Tip()); | ||||
} | } | ||||
// Command-line argument "-replayprotectionactivationtime=<timestamp>" will | // Command-line argument "-replayprotectionactivationtime=<timestamp>" will | ||||
// cause the node to switch to replay protected SigHash ForkID value when the | // cause the node to switch to replay protected SigHash ForkID value when the | ||||
// median timestamp of the previous 11 blocks is greater than or equal to | // median timestamp of the previous 11 blocks is greater than or equal to | ||||
// <timestamp>. Defaults to the pre-defined timestamp when not set. | // <timestamp>. Defaults to the pre-defined timestamp when not set. | ||||
static bool IsReplayProtectionEnabled(const Consensus::Params ¶ms, | static bool IsReplayProtectionEnabled(const Consensus::Params ¶ms, | ||||
int64_t nMedianTimePast) { | int64_t nMedianTimePast) { | ||||
return nMedianTimePast >= gArgs.GetArg("-replayprotectionactivationtime", | return nMedianTimePast >= gArgs.GetArg("-replayprotectionactivationtime", | ||||
params.phononActivationTime); | params.phononActivationTime); | ||||
} | } | ||||
static bool IsReplayProtectionEnabled(const Consensus::Params ¶ms, | static bool IsReplayProtectionEnabled(const Consensus::Params ¶ms, | ||||
const CBlockIndex *pindexPrev) { | const CBlockIndex *pindexPrev) { | ||||
if (pindexPrev == nullptr) { | if (pindexPrev == nullptr) { | ||||
return false; | return false; | ||||
} | } | ||||
return IsReplayProtectionEnabled(params, pindexPrev->GetMedianTimePast()); | return IsReplayProtectionEnabled(params, pindexPrev->GetMedianTimePast()); | ||||
} | } | ||||
static bool | static bool | ||||
IsReplayProtectionEnabledForCurrentBlock(const Consensus::Params ¶ms) { | IsReplayProtectionEnabledForCurrentBlock(const Consensus::Params ¶ms) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return IsReplayProtectionEnabled(params, chainActive.Tip()); | return IsReplayProtectionEnabled(params, chainActive.Tip()); | ||||
} | } | ||||
// Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool | // Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool | ||||
// were somehow broken and returning the wrong scriptPubKeys | // were somehow broken and returning the wrong scriptPubKeys | ||||
static bool CheckInputsFromMempoolAndCache( | static bool CheckInputsFromMempoolAndCache( | ||||
const CTransaction &tx, CValidationState &state, | const CTransaction &tx, CValidationState &state, | ||||
const CCoinsViewCache &view, const CTxMemPool &pool, const uint32_t flags, | const CCoinsViewCache &view, const CTxMemPool &pool, const uint32_t flags, | ||||
bool cacheSigStore, PrecomputedTransactionData &txdata) { | bool cacheSigStore, PrecomputedTransactionData &txdata) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// pool.cs should be locked already, but go ahead and re-take the lock here | // pool.cs should be locked already, but go ahead and re-take the lock here | ||||
// to enforce that mempool doesn't change between when we check the view and | // to enforce that mempool doesn't change between when we check the view and | ||||
// when we actually call through to CheckInputs | // when we actually call through to CheckInputs | ||||
LOCK(pool.cs); | LOCK(pool.cs); | ||||
assert(!tx.IsCoinBase()); | assert(!tx.IsCoinBase()); | ||||
Show All 23 Lines | static bool CheckInputsFromMempoolAndCache( | ||||
return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, | return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, | ||||
txdata); | txdata); | ||||
} | } | ||||
static bool AcceptToMemoryPoolWorker( | static bool AcceptToMemoryPoolWorker( | ||||
const Config &config, CTxMemPool &pool, CValidationState &state, | const Config &config, CTxMemPool &pool, CValidationState &state, | ||||
const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, | const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, | ||||
int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, | int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, | ||||
std::vector<COutPoint> &coins_to_uncache, bool test_accept) { | std::vector<COutPoint> &coins_to_uncache, bool test_accept) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const Consensus::Params &consensusParams = | const Consensus::Params &consensusParams = | ||||
config.GetChainParams().GetConsensus(); | config.GetChainParams().GetConsensus(); | ||||
const CTransaction &tx = *ptx; | const CTransaction &tx = *ptx; | ||||
const TxId txid = tx.GetId(); | const TxId txid = tx.GetId(); | ||||
▲ Show 20 Lines • Show All 307 Lines • ▼ Show 20 Lines | static bool AcceptToMemoryPoolWorker( | ||||
GetMainSignals().TransactionAddedToMempool(ptx); | GetMainSignals().TransactionAddedToMempool(ptx); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* (try to) add transaction to memory pool with a specified acceptance time. | * (try to) add transaction to memory pool with a specified acceptance time. | ||||
*/ | */ | ||||
static bool | static bool AcceptToMemoryPoolWithTime( | ||||
AcceptToMemoryPoolWithTime(const Config &config, CTxMemPool &pool, | const Config &config, CTxMemPool &pool, CValidationState &state, | ||||
CValidationState &state, const CTransactionRef &tx, | const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, | ||||
bool fLimitFree, bool *pfMissingInputs, | int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, | ||||
int64_t nAcceptTime, bool fOverrideMempoolLimit, | bool test_accept) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
const Amount nAbsurdFee, bool test_accept) { | |||||
std::vector<COutPoint> coins_to_uncache; | std::vector<COutPoint> coins_to_uncache; | ||||
bool res = AcceptToMemoryPoolWorker( | bool res = AcceptToMemoryPoolWorker( | ||||
config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, | config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, | ||||
fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache, test_accept); | fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache, test_accept); | ||||
if (!res) { | if (!res) { | ||||
for (const COutPoint &outpoint : coins_to_uncache) { | for (const COutPoint &outpoint : coins_to_uncache) { | ||||
pcoinsTip->Uncache(outpoint); | pcoinsTip->Uncache(outpoint); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 204 Lines • ▼ Show 20 Lines | static void AlertNotify(const std::string &strMessage) { | ||||
safeStatus = singleQuote + safeStatus + singleQuote; | safeStatus = singleQuote + safeStatus + singleQuote; | ||||
boost::replace_all(strCmd, "%s", safeStatus); | boost::replace_all(strCmd, "%s", safeStatus); | ||||
std::thread t(runCommand, strCmd); | std::thread t(runCommand, strCmd); | ||||
// thread runs free | // thread runs free | ||||
t.detach(); | t.detach(); | ||||
} | } | ||||
static void CheckForkWarningConditions() { | static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// Before we get past initial download, we cannot reliably alert about forks | // Before we get past initial download, we cannot reliably alert about forks | ||||
// (we assume we don't get stuck on a fork before finishing our initial | // (we assume we don't get stuck on a fork before finishing our initial | ||||
// sync) | // sync) | ||||
if (IsInitialBlockDownload()) { | if (IsInitialBlockDownload()) { | ||||
return; | return; | ||||
} | } | ||||
Show All 34 Lines | if (pindexBestForkTip || | ||||
SetfLargeWorkInvalidChainFound(true); | SetfLargeWorkInvalidChainFound(true); | ||||
} | } | ||||
} else { | } else { | ||||
SetfLargeWorkForkFound(false); | SetfLargeWorkForkFound(false); | ||||
SetfLargeWorkInvalidChainFound(false); | SetfLargeWorkInvalidChainFound(false); | ||||
} | } | ||||
} | } | ||||
static void | static void CheckForkWarningConditionsOnNewFork(CBlockIndex *pindexNewForkTip) | ||||
CheckForkWarningConditionsOnNewFork(const CBlockIndex *pindexNewForkTip) { | EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// If we are on a fork that is sufficiently large, set a warning flag. | // If we are on a fork that is sufficiently large, set a warning flag. | ||||
const CBlockIndex *pfork = chainActive.FindFork(pindexNewForkTip); | const CBlockIndex *pfork = chainActive.FindFork(pindexNewForkTip); | ||||
// We define a condition where we should warn the user about as a fork of at | // We define a condition where we should warn the user about as a fork of at | ||||
// least 7 blocks with a tip within 72 blocks (+/- 12 hours if no one mines | // least 7 blocks with a tip within 72 blocks (+/- 12 hours if no one mines | ||||
// it) of ours. We use 7 blocks rather arbitrarily as it represents just | // it) of ours. We use 7 blocks rather arbitrarily as it represents just | ||||
// under 10% of sustained network hash rate operating on the fork, or a | // under 10% of sustained network hash rate operating on the fork, or a | ||||
Show All 9 Lines | if (pfork && | ||||
chainActive.Height() - pindexNewForkTip->nHeight < 72) { | chainActive.Height() - pindexNewForkTip->nHeight < 72) { | ||||
pindexBestForkTip = pindexNewForkTip; | pindexBestForkTip = pindexNewForkTip; | ||||
pindexBestForkBase = pfork; | pindexBestForkBase = pfork; | ||||
} | } | ||||
CheckForkWarningConditions(); | CheckForkWarningConditions(); | ||||
} | } | ||||
static void InvalidChainFound(CBlockIndex *pindexNew) { | void static InvalidChainFound(CBlockIndex *pindexNew) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
if (!pindexBestInvalid || | if (!pindexBestInvalid || | ||||
pindexNew->nChainWork > pindexBestInvalid->nChainWork) { | pindexNew->nChainWork > pindexBestInvalid->nChainWork) { | ||||
pindexBestInvalid = pindexNew; | pindexBestInvalid = pindexNew; | ||||
} | } | ||||
// If the invalid chain found is supposed to be finalized, we need to move | // If the invalid chain found is supposed to be finalized, we need to move | ||||
// back the finalization point. | // back the finalization point. | ||||
if (IsBlockFinalized(pindexNew)) { | if (IsBlockFinalized(pindexNew)) { | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | int GetSpendHeight(const CCoinsViewCache &inputs) { | ||||
return pindexPrev->nHeight + 1; | return pindexPrev->nHeight + 1; | ||||
} | } | ||||
bool CheckInputs(const CTransaction &tx, CValidationState &state, | bool CheckInputs(const CTransaction &tx, CValidationState &state, | ||||
const CCoinsViewCache &inputs, bool fScriptChecks, | const CCoinsViewCache &inputs, bool fScriptChecks, | ||||
const uint32_t flags, bool sigCacheStore, | const uint32_t flags, bool sigCacheStore, | ||||
bool scriptCacheStore, | bool scriptCacheStore, | ||||
const PrecomputedTransactionData &txdata, | const PrecomputedTransactionData &txdata, | ||||
std::vector<CScriptCheck> *pvChecks) { | std::vector<CScriptCheck> *pvChecks) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
assert(!tx.IsCoinBase()); | assert(!tx.IsCoinBase()); | ||||
if (pvChecks) { | if (pvChecks) { | ||||
pvChecks->reserve(tx.vin.size()); | pvChecks->reserve(tx.vin.size()); | ||||
} | } | ||||
// Skip script verification when connecting blocks under the assumevalid | // Skip script verification when connecting blocks under the assumevalid | ||||
// block. Assuming the assumevalid block is valid this is safe because | // block. Assuming the assumevalid block is valid this is safe because | ||||
▲ Show 20 Lines • Show All 347 Lines • ▼ Show 20 Lines | int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, | ||||
const Consensus::Params ¶ms) { | const Consensus::Params ¶ms) { | ||||
int32_t nVersion = VERSIONBITS_TOP_BITS; | int32_t nVersion = VERSIONBITS_TOP_BITS; | ||||
return nVersion; | return nVersion; | ||||
} | } | ||||
// Returns the script flags which should be checked for the block after | // Returns the script flags which should be checked for the block after | ||||
// the given block. | // the given block. | ||||
static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, | ||||
const CBlockIndex *pindex) { | const CBlockIndex *pindex) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
uint32_t flags = SCRIPT_VERIFY_NONE; | uint32_t flags = SCRIPT_VERIFY_NONE; | ||||
// Start enforcing P2SH (BIP16) | // Start enforcing P2SH (BIP16) | ||||
if ((pindex->nHeight + 1) >= params.BIP16Height) { | if ((pindex->nHeight + 1) >= params.BIP16Height) { | ||||
flags |= SCRIPT_VERIFY_P2SH; | flags |= SCRIPT_VERIFY_P2SH; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
* Apply the effects of this block (with given index) on the UTXO set | * Apply the effects of this block (with given index) on the UTXO set | ||||
* represented by coins. Validity checks that depend on the UTXO set are also | * represented by coins. Validity checks that depend on the UTXO set are also | ||||
* done; ConnectBlock() can fail if those validity checks fail (among other | * done; ConnectBlock() can fail if those validity checks fail (among other | ||||
* reasons). | * reasons). | ||||
*/ | */ | ||||
bool CChainState::ConnectBlock(const CBlock &block, CValidationState &state, | bool CChainState::ConnectBlock(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindex, CCoinsViewCache &view, | CBlockIndex *pindex, CCoinsViewCache &view, | ||||
const CChainParams ¶ms, | const CChainParams ¶ms, | ||||
BlockValidationOptions options, | BlockValidationOptions options, bool fJustCheck) | ||||
bool fJustCheck) { | EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
assert(pindex); | assert(pindex); | ||||
assert(*pindex->phashBlock == block.GetHash()); | assert(*pindex->phashBlock == block.GetHash()); | ||||
int64_t nTimeStart = GetTimeMicros(); | int64_t nTimeStart = GetTimeMicros(); | ||||
const Consensus::Params &consensusParams = params.GetConsensus(); | const Consensus::Params &consensusParams = params.GetConsensus(); | ||||
// Check it again in case a previous version let a bad block in | // Check it again in case a previous version let a bad block in | ||||
▲ Show 20 Lines • Show All 522 Lines • ▼ Show 20 Lines | |||||
* should make the mempool consistent again by calling updateMempoolForReorg. | * should make the mempool consistent again by calling updateMempoolForReorg. | ||||
* with cs_main held. | * with cs_main held. | ||||
* | * | ||||
* If disconnectpool is nullptr, then no disconnected transactions are added to | * If disconnectpool is nullptr, then no disconnected transactions are added to | ||||
* disconnectpool (note that the caller is responsible for mempool consistency | * disconnectpool (note that the caller is responsible for mempool consistency | ||||
* in any case). | * in any case). | ||||
*/ | */ | ||||
bool CChainState::DisconnectTip(const Config &config, CValidationState &state, | bool CChainState::DisconnectTip(const Config &config, CValidationState &state, | ||||
DisconnectedBlockTransactions *disconnectpool) { | DisconnectedBlockTransactions *disconnectpool) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
CBlockIndex *pindexDelete = chainActive.Tip(); | CBlockIndex *pindexDelete = chainActive.Tip(); | ||||
const Consensus::Params &consensusParams = | const Consensus::Params &consensusParams = | ||||
config.GetChainParams().GetConsensus(); | config.GetChainParams().GetConsensus(); | ||||
assert(pindexDelete); | assert(pindexDelete); | ||||
// Read block from disk. | // Read block from disk. | ||||
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); | std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); | ||||
▲ Show 20 Lines • Show All 878 Lines • ▼ Show 20 Lines | bool CChainState::UnwindBlock(const Config &config, CValidationState &state, | ||||
// Only notify about a new block tip if the active chain was modified. | // Only notify about a new block tip if the active chain was modified. | ||||
if (pindex_was_in_chain) { | if (pindex_was_in_chain) { | ||||
uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev); | uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state, | bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (!FinalizeBlockInternal(config, state, pindex)) { | if (!FinalizeBlockInternal(config, state, pindex)) { | ||||
// state is set by FinalizeBlockInternal. | // state is set by FinalizeBlockInternal. | ||||
return false; | return false; | ||||
} | } | ||||
// We have a valid candidate, make sure it is not parked. | // We have a valid candidate, make sure it is not parked. | ||||
if (pindex->nStatus.isOnParkedChain()) { | if (pindex->nStatus.isOnParkedChain()) { | ||||
Show All 36 Lines | if (pindex->nStatus != newStatus && | ||||
if (pindex->IsValid(BlockValidity::TRANSACTIONS) && pindex->nChainTx && | if (pindex->IsValid(BlockValidity::TRANSACTIONS) && pindex->nChainTx && | ||||
setBlockIndexCandidates.value_comp()(chainActive.Tip(), pindex)) { | setBlockIndexCandidates.value_comp()(chainActive.Tip(), pindex)) { | ||||
setBlockIndexCandidates.insert(pindex); | setBlockIndexCandidates.insert(pindex); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
template <typename F, typename C> | template <typename F, typename C> | ||||
void CChainState::UpdateFlags(CBlockIndex *pindex, F f, C fchild) { | void CChainState::UpdateFlags(CBlockIndex *pindex, F f, C fchild) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// Update the current block. | // Update the current block. | ||||
UpdateFlagsForBlock(pindex, pindex, f); | UpdateFlagsForBlock(pindex, pindex, f); | ||||
// Update the flags from this block and all its descendants. | // Update the flags from this block and all its descendants. | ||||
BlockMap::iterator it = mapBlockIndex.begin(); | BlockMap::iterator it = mapBlockIndex.begin(); | ||||
while (it != mapBlockIndex.end()) { | while (it != mapBlockIndex.end()) { | ||||
Show All 10 Lines | while (pindex != nullptr) { | ||||
if (newStatus.isValid()) { | if (newStatus.isValid()) { | ||||
m_failed_blocks.erase(pindex); | m_failed_blocks.erase(pindex); | ||||
} | } | ||||
} | } | ||||
pindex = pindex->pprev; | pindex = pindex->pprev; | ||||
} | } | ||||
} | } | ||||
template <typename F> void CChainState::UpdateFlags(CBlockIndex *pindex, F f) { | template <typename F> | ||||
void CChainState::UpdateFlags(CBlockIndex *pindex, F f) | |||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
// Handy shorthand. | // Handy shorthand. | ||||
UpdateFlags(pindex, f, f); | UpdateFlags(pindex, f, f); | ||||
} | } | ||||
bool CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) { | bool CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (pindexBestInvalid && | if (pindexBestInvalid && | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool IsBlockFinalized(const CBlockIndex *pindex) { | bool IsBlockFinalized(const CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return pindexFinalized && | return pindexFinalized && | ||||
pindexFinalized->GetAncestor(pindex->nHeight) == pindex; | pindexFinalized->GetAncestor(pindex->nHeight) == pindex; | ||||
} | } | ||||
CBlockIndex *CChainState::AddToBlockIndex(const CBlockHeader &block) { | CBlockIndex *CChainState::AddToBlockIndex(const CBlockHeader &block) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// Check for duplicate | // Check for duplicate | ||||
uint256 hash = block.GetHash(); | uint256 hash = block.GetHash(); | ||||
BlockMap::iterator it = mapBlockIndex.find(hash); | BlockMap::iterator it = mapBlockIndex.find(hash); | ||||
if (it != mapBlockIndex.end()) { | if (it != mapBlockIndex.end()) { | ||||
return it->second; | return it->second; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,457 Lines • Show Last 20 Lines |
This one is from PR13481