Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,360 Lines • ▼ Show 20 Lines | |||||
* part of a single ActivateBestChainStep call. | * part of a single ActivateBestChainStep call. | ||||
* | * | ||||
* This class is single-use, once you call GetBlocksConnected() you have to | * This class is single-use, once you call GetBlocksConnected() you have to | ||||
* throw it away and make a new one. | * throw it away and make a new one. | ||||
*/ | */ | ||||
class ConnectTrace { | class ConnectTrace { | ||||
private: | private: | ||||
std::vector<PerBlockConnectTrace> blocksConnected; | std::vector<PerBlockConnectTrace> blocksConnected; | ||||
CTxMemPool &pool; | |||||
boost::signals2::scoped_connection m_connNotifyEntryRemoved; | |||||
public: | public: | ||||
explicit ConnectTrace(CTxMemPool &_pool) : blocksConnected(1), pool(_pool) { | explicit ConnectTrace() : blocksConnected(1) {} | ||||
m_connNotifyEntryRemoved = pool.NotifyEntryRemoved.connect( | |||||
std::bind(&ConnectTrace::NotifyEntryRemoved, this, | |||||
std::placeholders::_1, std::placeholders::_2)); | |||||
} | |||||
void BlockConnected(CBlockIndex *pindex, | void BlockConnected(CBlockIndex *pindex, | ||||
std::shared_ptr<const CBlock> pblock) { | std::shared_ptr<const CBlock> pblock) { | ||||
assert(!blocksConnected.back().pindex); | assert(!blocksConnected.back().pindex); | ||||
assert(pindex); | assert(pindex); | ||||
assert(pblock); | assert(pblock); | ||||
blocksConnected.back().pindex = pindex; | blocksConnected.back().pindex = pindex; | ||||
blocksConnected.back().pblock = std::move(pblock); | blocksConnected.back().pblock = std::move(pblock); | ||||
blocksConnected.emplace_back(); | blocksConnected.emplace_back(); | ||||
} | } | ||||
std::vector<PerBlockConnectTrace> &GetBlocksConnected() { | std::vector<PerBlockConnectTrace> &GetBlocksConnected() { | ||||
// We always keep one extra block at the end of our list because blocks | // We always keep one extra block at the end of our list because blocks | ||||
// are added after all the conflicted transactions have been filled in. | // are added after all the conflicted transactions have been filled in. | ||||
// Thus, the last entry should always be an empty one waiting for the | // Thus, the last entry should always be an empty one waiting for the | ||||
// transactions from the next block. We pop the last entry here to make | // transactions from the next block. We pop the last entry here to make | ||||
// sure the list we return is sane. | // sure the list we return is sane. | ||||
assert(!blocksConnected.back().pindex); | assert(!blocksConnected.back().pindex); | ||||
blocksConnected.pop_back(); | blocksConnected.pop_back(); | ||||
return blocksConnected; | return blocksConnected; | ||||
} | } | ||||
void NotifyEntryRemoved(CTransactionRef txRemoved, | |||||
MemPoolRemovalReason reason) { | |||||
assert(!blocksConnected.back().pindex); | |||||
} | |||||
}; | }; | ||||
bool CChainState::MarkBlockAsFinal(BlockValidationState &state, | bool CChainState::MarkBlockAsFinal(BlockValidationState &state, | ||||
const CBlockIndex *pindex) { | const CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (pindex->nStatus.isInvalid()) { | if (pindex->nStatus.isInvalid()) { | ||||
// We try to finalize an invalid block. | // We try to finalize an invalid block. | ||||
LogPrintf("ERROR: %s: Trying to finalize invalid block %s\n", __func__, | LogPrintf("ERROR: %s: Trying to finalize invalid block %s\n", __func__, | ||||
▲ Show 20 Lines • Show All 578 Lines • ▼ Show 20 Lines | do { | ||||
CBlockIndex *starting_tip = m_chain.Tip(); | CBlockIndex *starting_tip = m_chain.Tip(); | ||||
bool blocks_connected = false; | bool blocks_connected = false; | ||||
do { | do { | ||||
// We absolutely may not unlock cs_main until we've made forward | // We absolutely may not unlock cs_main until we've made forward | ||||
// progress (with the exception of shutdown due to hardware | // progress (with the exception of shutdown due to hardware | ||||
// issues, low disk space, etc). | // issues, low disk space, etc). | ||||
// Destructed before cs_main is unlocked | // Destructed before cs_main is unlocked | ||||
ConnectTrace connectTrace(g_mempool); | ConnectTrace connectTrace; | ||||
if (pindexMostWork == nullptr) { | if (pindexMostWork == nullptr) { | ||||
pindexMostWork = FindMostWorkChain(); | pindexMostWork = FindMostWorkChain(); | ||||
} | } | ||||
// Whether we have anything to do at all. | // Whether we have anything to do at all. | ||||
if (pindexMostWork == nullptr || | if (pindexMostWork == nullptr || | ||||
pindexMostWork == m_chain.Tip()) { | pindexMostWork == m_chain.Tip()) { | ||||
▲ Show 20 Lines • Show All 3,016 Lines • Show Last 20 Lines |