mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge pull request #4554 from UdjinM6/bp15402_16849_15971
backport 15402, 16849, 15971
This commit is contained in:
commit
12c399b3f0
@ -1972,11 +1972,11 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||
|
||||
uiInterface.InitMessage(_("Loading block index..."));
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
do {
|
||||
const int64_t load_block_index_start_time = GetTimeMillis();
|
||||
bool is_coinsview_empty;
|
||||
try {
|
||||
LOCK(cs_main);
|
||||
// This statement makes ::ChainstateActive() usable.
|
||||
g_chainstate = MakeUnique<CChainState>();
|
||||
UnloadBlockIndex();
|
||||
@ -2099,7 +2099,7 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_coinsview_empty = fReset || fReindexChainState ||
|
||||
is_coinsview_empty = fReset || fReindexChainState ||
|
||||
::ChainstateActive().CoinsTip().GetBestBlock().IsNull();
|
||||
if (!is_coinsview_empty) {
|
||||
// LoadChainTip initializes the chain based on CoinsTip()'s best block
|
||||
|
@ -509,43 +509,16 @@ void CChainLocksHandler::EnforceBestChainLock()
|
||||
}
|
||||
}
|
||||
|
||||
bool activateNeeded;
|
||||
CValidationState state;
|
||||
const auto ¶ms = Params();
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
// Go backwards through the chain referenced by clsig until we find a block that is part of the main chain.
|
||||
// For each of these blocks, check if there are children that are NOT part of the chain referenced by clsig
|
||||
// and mark all of them as conflicting.
|
||||
while (pindex && !::ChainActive().Contains(pindex)) {
|
||||
// Mark all blocks that have the same prevBlockHash but are not equal to blockHash as conflicting
|
||||
auto itp = ::PrevBlockIndex().equal_range(pindex->pprev->GetBlockHash());
|
||||
for (auto jt = itp.first; jt != itp.second; ++jt) {
|
||||
if (jt->second == pindex) {
|
||||
continue;
|
||||
}
|
||||
if (!MarkConflictingBlock(state, params, jt->second)) {
|
||||
LogPrintf("CChainLocksHandler::%s -- MarkConflictingBlock failed: %s\n", __func__, FormatStateMessage(state));
|
||||
// This should not have happened and we are in a state were it's not safe to continue anymore
|
||||
assert(false);
|
||||
}
|
||||
LogPrintf("CChainLocksHandler::%s -- CLSIG (%s) marked block %s as conflicting\n",
|
||||
__func__, clsig->ToString(), jt->second->GetBlockHash().ToString());
|
||||
}
|
||||
// Go backwards through the chain referenced by clsig until we find a block that is part of the main chain.
|
||||
// For each of these blocks, check if there are children that are NOT part of the chain referenced by clsig
|
||||
// and mark all of them as conflicting.
|
||||
LogPrint(BCLog::CHAINLOCKS, "CChainLocksHandler::%s -- enforcing block %s via CLSIG (%s)\n", __func__, pindex->GetBlockHash().ToString(), clsig->ToString());
|
||||
EnforceBlock(state, params, pindex);
|
||||
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
// In case blocks from the correct chain are invalid at the moment, reconsider them. The only case where this
|
||||
// can happen right now is when missing superblock triggers caused the main chain to be dismissed first. When
|
||||
// the trigger later appears, this should bring us to the correct chain eventually. Please note that this does
|
||||
// NOT enforce invalid blocks in any way, it just causes re-validation.
|
||||
if (!currentBestChainLockBlockIndex->IsValid()) {
|
||||
ResetBlockFailureFlags(LookupBlockIndex(currentBestChainLockBlockIndex->GetBlockHash()));
|
||||
}
|
||||
|
||||
activateNeeded = ::ChainActive().Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight) != currentBestChainLockBlockIndex;
|
||||
}
|
||||
bool activateNeeded = WITH_LOCK(::cs_main, return ::ChainActive().Tip()->GetAncestor(currentBestChainLockBlockIndex->nHeight)) != currentBestChainLockBlockIndex;
|
||||
|
||||
if (activateNeeded) {
|
||||
if(!ActivateBestChain(state, params)) {
|
||||
|
@ -1430,10 +1430,9 @@ void CInstantSendManager::ResolveBlockConflicts(const uint256& islockHash, const
|
||||
|
||||
LogPrintf("CInstantSendManager::%s -- invalidating block %s\n", __func__, pindex->GetBlockHash().ToString());
|
||||
|
||||
LOCK(cs_main);
|
||||
CValidationState state;
|
||||
// need non-const pointer
|
||||
auto pindex2 = LookupBlockIndex(pindex->GetBlockHash());
|
||||
auto pindex2 = WITH_LOCK(::cs_main, return LookupBlockIndex(pindex->GetBlockHash()));
|
||||
if (!InvalidateBlock(state, Params(), pindex2)) {
|
||||
LogPrintf("CInstantSendManager::%s -- InvalidateBlock failed: %s\n", __func__, FormatStateMessage(state));
|
||||
// This should not have happened and we are in a state were it's not safe to continue anymore
|
||||
|
@ -1778,15 +1778,15 @@ static UniValue invalidateblock(const JSONRPCRequest& request)
|
||||
uint256 hash(uint256S(strHash));
|
||||
CValidationState state;
|
||||
|
||||
CBlockIndex* pblockindex;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CBlockIndex* pblockindex = LookupBlockIndex(hash);
|
||||
pblockindex = LookupBlockIndex(hash);
|
||||
if (!pblockindex) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||
}
|
||||
|
||||
InvalidateBlock(state, Params(), pblockindex);
|
||||
}
|
||||
InvalidateBlock(state, Params(), pblockindex);
|
||||
|
||||
if (state.IsValid()) {
|
||||
ActivateBestChain(state, Params());
|
||||
|
@ -518,20 +518,22 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
// Mine an empty block
|
||||
createAndProcessEmptyBlock();
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1);
|
||||
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U);
|
||||
} // unlock cs_main while calling InvalidateBlock
|
||||
|
||||
CValidationState state;
|
||||
InvalidateBlock(state, chainparams, ::ChainActive().Tip());
|
||||
InvalidateBlock(state, chainparams, WITH_LOCK(cs_main, return ::ChainActive().Tip()));
|
||||
|
||||
SetMockTime(0);
|
||||
mempool.clear();
|
||||
|
||||
LOCK(::mempool.cs);
|
||||
LOCK2(cs_main, ::mempool.cs);
|
||||
TestPackageSelection(chainparams, scriptPubKey, txFirst);
|
||||
|
||||
fCheckpointsEnabled = true;
|
||||
|
@ -3034,6 +3034,14 @@ static void NotifyHeaderTip() LOCKS_EXCLUDED(cs_main) {
|
||||
}
|
||||
}
|
||||
|
||||
static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main) {
|
||||
AssertLockNotHeld(cs_main);
|
||||
|
||||
if (GetMainSignals().CallbacksPending() > 10) {
|
||||
SyncWithValidationInterfaceQueue();
|
||||
}
|
||||
}
|
||||
|
||||
bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
|
||||
// Note that while we're often called here from ProcessNewBlock, this is
|
||||
// far from a guarantee. Things in the P2P/RPC will often end up calling
|
||||
@ -3055,15 +3063,13 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
|
||||
do {
|
||||
boost::this_thread::interruption_point();
|
||||
|
||||
if (GetMainSignals().CallbacksPending() > 10) {
|
||||
// Block until the validation queue drains. This should largely
|
||||
// never happen in normal operation, however may happen during
|
||||
// reindex, causing memory blowup if we run too far ahead.
|
||||
// Note that if a validationinterface callback ends up calling
|
||||
// ActivateBestChain this may lead to a deadlock! We should
|
||||
// probably have a DEBUG_LOCKORDER test for this in the future.
|
||||
SyncWithValidationInterfaceQueue();
|
||||
}
|
||||
// Block until the validation queue drains. This should largely
|
||||
// never happen in normal operation, however may happen during
|
||||
// reindex, causing memory blowup if we run too far ahead.
|
||||
// Note that if a validationinterface callback ends up calling
|
||||
// ActivateBestChain this may lead to a deadlock! We should
|
||||
// probably have a DEBUG_LOCKORDER test for this in the future.
|
||||
LimitValidationInterfaceQueue();
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
@ -3181,76 +3187,148 @@ bool PreciousBlock(CValidationState& state, const CChainParams& params, CBlockIn
|
||||
|
||||
bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
// We first disconnect backwards and then mark the blocks as invalid.
|
||||
// This prevents a case where pruned nodes may fail to invalidateblock
|
||||
// and be left unable to start as they have no tip candidates (as there
|
||||
// are no blocks that meet the "have data and are not invalid per
|
||||
// nStatus" criteria for inclusion in setBlockIndexCandidates).
|
||||
|
||||
CBlockIndex* to_mark_failed = pindex;
|
||||
bool pindex_was_in_chain = false;
|
||||
CBlockIndex *invalid_walk_tip = m_chain.Tip();
|
||||
int disconnected = 0;
|
||||
|
||||
if (pindex == pindexBestHeader) {
|
||||
pindexBestInvalid = pindexBestHeader;
|
||||
pindexBestHeader = pindexBestHeader->pprev;
|
||||
// We do not allow ActivateBestChain() to run while InvalidateBlock() is
|
||||
// running, as that could cause the tip to change while we disconnect
|
||||
// blocks.
|
||||
LOCK(m_cs_chainstate);
|
||||
|
||||
// We'll be acquiring and releasing cs_main below, to allow the validation
|
||||
// callbacks to run. However, we should keep the block index in a
|
||||
// consistent state as we disconnect blocks -- in particular we need to
|
||||
// add equal-work blocks to setBlockIndexCandidates as we disconnect.
|
||||
// To avoid walking the block index repeatedly in search of candidates,
|
||||
// build a map once so that we can look up candidate blocks by chain
|
||||
// work as we go.
|
||||
std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
for (const auto& entry : m_blockman.m_block_index) {
|
||||
CBlockIndex *candidate = entry.second;
|
||||
// We don't need to put anything in our active chain into the
|
||||
// multimap, because those candidates will be found and considered
|
||||
// as we disconnect.
|
||||
// Instead, consider only non-active-chain blocks that have at
|
||||
// least as much work as where we expect the new tip to end up.
|
||||
if (!m_chain.Contains(candidate) &&
|
||||
!CBlockIndexWorkComparator()(candidate, pindex->pprev) &&
|
||||
candidate->IsValid(BLOCK_VALID_TRANSACTIONS) &&
|
||||
candidate->HaveTxsDownloaded()) {
|
||||
candidate_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisconnectedBlockTransactions disconnectpool;
|
||||
while (m_chain.Contains(pindex)) {
|
||||
const CBlockIndex* pindexOldTip = m_chain.Tip();
|
||||
// Disconnect (descendants of) pindex, and mark them invalid.
|
||||
while (true) {
|
||||
if (ShutdownRequested()) break;
|
||||
|
||||
// Make sure the queue of validation callbacks doesn't grow unboundedly.
|
||||
LimitValidationInterfaceQueue();
|
||||
|
||||
LOCK(cs_main);
|
||||
if (!m_chain.Contains(pindex)) break;
|
||||
pindex_was_in_chain = true;
|
||||
CBlockIndex *invalid_walk_tip = m_chain.Tip();
|
||||
const CBlockIndex* pindexOldTip = m_chain.Tip();
|
||||
|
||||
if (pindex == pindexBestHeader) {
|
||||
pindexBestInvalid = pindexBestHeader;
|
||||
pindexBestHeader = pindexBestHeader->pprev;
|
||||
}
|
||||
|
||||
// ActivateBestChain considers blocks already in m_chain
|
||||
// unconditionally valid already, so force disconnect away from it.
|
||||
if (!DisconnectTip(state, chainparams, &disconnectpool)) {
|
||||
// It's probably hopeless to try to make the mempool consistent
|
||||
// here if DisconnectTip failed, but we can try.
|
||||
UpdateMempoolForReorg(disconnectpool, false);
|
||||
return false;
|
||||
}
|
||||
DisconnectedBlockTransactions disconnectpool;
|
||||
bool ret = DisconnectTip(state, chainparams, &disconnectpool);
|
||||
// DisconnectTip will add transactions to disconnectpool.
|
||||
// Adjust the mempool to be consistent with the new tip, adding
|
||||
// transactions back to the mempool if disconnecting was succesful,
|
||||
// and we're not doing a very deep invalidation (in which case
|
||||
// keeping the mempool up to date is probably futile anyway).
|
||||
UpdateMempoolForReorg(disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
|
||||
if (!ret) return false;
|
||||
assert(invalid_walk_tip->pprev == m_chain.Tip());
|
||||
|
||||
if (pindexOldTip == pindexBestHeader) {
|
||||
pindexBestInvalid = pindexBestHeader;
|
||||
pindexBestHeader = pindexBestHeader->pprev;
|
||||
}
|
||||
}
|
||||
|
||||
// Now mark the blocks we just disconnected as descendants invalid
|
||||
// (note this may not be all descendants).
|
||||
while (pindex_was_in_chain && invalid_walk_tip != pindex) {
|
||||
invalid_walk_tip->nStatus |= BLOCK_FAILED_CHILD;
|
||||
// We immediately mark the disconnected blocks as invalid.
|
||||
// This prevents a case where pruned nodes may fail to invalidateblock
|
||||
// and be left unable to start as they have no tip candidates (as there
|
||||
// are no blocks that meet the "have data and are not invalid per
|
||||
// nStatus" criteria for inclusion in setBlockIndexCandidates).
|
||||
invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(invalid_walk_tip);
|
||||
setBlockIndexCandidates.erase(invalid_walk_tip);
|
||||
invalid_walk_tip = invalid_walk_tip->pprev;
|
||||
}
|
||||
|
||||
// Mark the block itself as invalid.
|
||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(pindex);
|
||||
setBlockIndexCandidates.erase(pindex);
|
||||
m_blockman.m_failed_blocks.insert(pindex);
|
||||
|
||||
// DisconnectTip will add transactions to disconnectpool; try to add these
|
||||
// back to the mempool.
|
||||
UpdateMempoolForReorg(disconnectpool, true);
|
||||
|
||||
// The resulting new best tip may not be in setBlockIndexCandidates anymore, so
|
||||
// add it again.
|
||||
BlockMap::iterator it = g_blockman.m_block_index.begin();
|
||||
while (it != g_blockman.m_block_index.end()) {
|
||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && !(it->second->nStatus & BLOCK_CONFLICT_CHAINLOCK) && it->second->HaveTxsDownloaded() && !setBlockIndexCandidates.value_comp()(it->second, m_chain.Tip())) {
|
||||
setBlockIndexCandidates.insert(it->second);
|
||||
setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
|
||||
if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
|
||||
// We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children
|
||||
// need to be BLOCK_FAILED_CHILD instead.
|
||||
to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;
|
||||
setDirtyBlockIndex.insert(to_mark_failed);
|
||||
}
|
||||
it++;
|
||||
|
||||
// Add any equal or more work headers to setBlockIndexCandidates
|
||||
auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->pprev->nChainWork);
|
||||
while (candidate_it != candidate_blocks_by_work.end()) {
|
||||
if (!CBlockIndexWorkComparator()(candidate_it->second, invalid_walk_tip->pprev)) {
|
||||
setBlockIndexCandidates.insert(candidate_it->second);
|
||||
candidate_it = candidate_blocks_by_work.erase(candidate_it);
|
||||
} else {
|
||||
++candidate_it;
|
||||
}
|
||||
}
|
||||
|
||||
// Track the last disconnected block, so we can correct its BLOCK_FAILED_CHILD status in future
|
||||
// iterations, or, if it's the last one, call InvalidChainFound on it.
|
||||
to_mark_failed = invalid_walk_tip;
|
||||
}
|
||||
|
||||
InvalidChainFound(pindex);
|
||||
GetMainSignals().SynchronousUpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
|
||||
GetMainSignals().UpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
|
||||
CheckBlockIndex(chainparams.GetConsensus());
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (m_chain.Contains(to_mark_failed)) {
|
||||
// If the to-be-marked invalid block is in the active chain, something is interfering and we can't proceed.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
|
||||
to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(to_mark_failed);
|
||||
setBlockIndexCandidates.erase(to_mark_failed);
|
||||
m_blockman.m_failed_blocks.insert(to_mark_failed);
|
||||
|
||||
// If any new blocks somehow arrived while we were disconnecting
|
||||
// (above), then the pre-calculation of what should go into
|
||||
// setBlockIndexCandidates may have missed entries. This would
|
||||
// technically be an inconsistency in the block index, but if we clean
|
||||
// it up here, this should be an essentially unobservable error.
|
||||
// Loop back over all block index entries and add any missing entries
|
||||
// to setBlockIndexCandidates.
|
||||
BlockMap::iterator it = g_blockman.m_block_index.begin();
|
||||
while (it != g_blockman.m_block_index.end()) {
|
||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && !(it->second->nStatus & BLOCK_CONFLICT_CHAINLOCK) && it->second->HaveTxsDownloaded() && !setBlockIndexCandidates.value_comp()(it->second, m_chain.Tip())) {
|
||||
setBlockIndexCandidates.insert(it->second);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
InvalidChainFound(to_mark_failed);
|
||||
GetMainSignals().SynchronousUpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
|
||||
GetMainSignals().UpdatedBlockTip(m_chain.Tip(), nullptr, IsInitialBlockDownload());
|
||||
}
|
||||
|
||||
// Only notify about a new block tip if the active chain was modified.
|
||||
if (pindex_was_in_chain) {
|
||||
uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev);
|
||||
uiInterface.NotifyBlockTip(IsInitialBlockDownload(), to_mark_failed->pprev);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3259,6 +3337,41 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C
|
||||
return ::ChainstateActive().InvalidateBlock(state, chainparams, pindex);
|
||||
}
|
||||
|
||||
void CChainState::EnforceBlock(CValidationState& state, const CChainParams& chainparams, const CBlockIndex *pindex)
|
||||
{
|
||||
AssertLockNotHeld(::cs_main);
|
||||
|
||||
LOCK2(m_cs_chainstate, ::cs_main);
|
||||
|
||||
const CBlockIndex* pindex_walk = pindex;
|
||||
|
||||
while (pindex_walk && !::ChainActive().Contains(pindex_walk)) {
|
||||
// Mark all blocks that have the same prevBlockHash but are not equal to blockHash as conflicting
|
||||
auto itp = ::PrevBlockIndex().equal_range(pindex_walk->pprev->GetBlockHash());
|
||||
for (auto jt = itp.first; jt != itp.second; ++jt) {
|
||||
if (jt->second == pindex_walk) {
|
||||
continue;
|
||||
}
|
||||
if (!MarkConflictingBlock(state, chainparams, jt->second)) {
|
||||
LogPrintf("CChainState::%s -- MarkConflictingBlock failed: %s\n", __func__, FormatStateMessage(state));
|
||||
// This should not have happened and we are in a state were it's not safe to continue anymore
|
||||
assert(false);
|
||||
}
|
||||
LogPrintf("CChainState::%s -- marked block %s as conflicting\n",
|
||||
__func__, jt->second->GetBlockHash().ToString());
|
||||
}
|
||||
pindex_walk = pindex_walk->pprev;
|
||||
}
|
||||
// In case blocks from the enforced chain are invalid at the moment, reconsider them.
|
||||
if (!pindex->IsValid()) {
|
||||
ResetBlockFailureFlags(LookupBlockIndex(pindex->GetBlockHash()));
|
||||
}
|
||||
}
|
||||
|
||||
void EnforceBlock(CValidationState& state, const CChainParams& chainparams, const CBlockIndex *pindex) {
|
||||
return ::ChainstateActive().EnforceBlock(state, chainparams, pindex);
|
||||
}
|
||||
|
||||
bool CChainState::MarkConflictingBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
@ -3326,10 +3439,6 @@ bool CChainState::MarkConflictingBlock(CValidationState& state, const CChainPara
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MarkConflictingBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex) {
|
||||
return ::ChainstateActive().MarkConflictingBlock(state, chainparams, pindex);
|
||||
}
|
||||
|
||||
void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
|
@ -240,7 +240,7 @@ bool GetTransaction(const uint256& hash, CTransactionRef& tx, const Consensus::P
|
||||
* May not be called with cs_main held. May not be called in a
|
||||
* validationinterface callback.
|
||||
*/
|
||||
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>());
|
||||
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>()) LOCKS_EXCLUDED(cs_main);
|
||||
|
||||
double ConvertBitsToDouble(unsigned int nBits);
|
||||
CAmount GetBlockSubsidy(int nBits, int nHeight, const Consensus::Params& consensusParams, bool fSuperblockPartOnly = false);
|
||||
@ -463,7 +463,6 @@ public:
|
||||
CBlockTreeDB& blocktree,
|
||||
std::set<CBlockIndex*, CBlockIndexWorkComparator>& block_index_candidates)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/** Clear all data members. */
|
||||
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
@ -679,7 +678,7 @@ public:
|
||||
bool ActivateBestChain(
|
||||
CValidationState& state,
|
||||
const CChainParams& chainparams,
|
||||
std::shared_ptr<const CBlock> pblock);
|
||||
std::shared_ptr<const CBlock> pblock) LOCKS_EXCLUDED(cs_main);
|
||||
|
||||
bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
@ -692,8 +691,8 @@ public:
|
||||
|
||||
// Manual block validity manipulation:
|
||||
bool PreciousBlock(CValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
|
||||
bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool MarkConflictingBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
|
||||
void EnforceBlock(CValidationState& state, const CChainParams& chainparams, const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
|
||||
void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/** Replay blocks that aren't fully applied to the database. */
|
||||
@ -739,6 +738,12 @@ private:
|
||||
|
||||
|
||||
bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
//! Mark a block as conflicting
|
||||
bool MarkConflictingBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
//! Mark a block as not having block data
|
||||
void EraseBlockData(CBlockIndex* index) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
};
|
||||
|
||||
/** Mark a block as precious and reorganize.
|
||||
@ -749,10 +754,10 @@ private:
|
||||
bool PreciousBlock(CValidationState& state, const CChainParams& params, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main);
|
||||
|
||||
/** Mark a block as invalid. */
|
||||
bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
|
||||
|
||||
/** Mark a block as conflicting. */
|
||||
bool MarkConflictingBlock(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
/** Enforce a block marking all the other chains as conflicting. */
|
||||
void EnforceBlock(CValidationState& state, const CChainParams& chainparams, const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
|
||||
|
||||
/** Remove invalidity status from a block and its descendants. */
|
||||
void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
Loading…
Reference in New Issue
Block a user