Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,347 Lines • ▼ Show 20 Lines | |||||
static int64_t nTimeConnectTotal = 0; | static int64_t nTimeConnectTotal = 0; | ||||
static int64_t nTimeFlush = 0; | static int64_t nTimeFlush = 0; | ||||
static int64_t nTimeChainState = 0; | static int64_t nTimeChainState = 0; | ||||
static int64_t nTimePostConnect = 0; | static int64_t nTimePostConnect = 0; | ||||
struct PerBlockConnectTrace { | struct PerBlockConnectTrace { | ||||
CBlockIndex *pindex = nullptr; | CBlockIndex *pindex = nullptr; | ||||
std::shared_ptr<const CBlock> pblock; | std::shared_ptr<const CBlock> pblock; | ||||
std::shared_ptr<std::vector<CTransactionRef>> conflictedTxs; | PerBlockConnectTrace() {} | ||||
PerBlockConnectTrace() | |||||
: conflictedTxs(std::make_shared<std::vector<CTransactionRef>>()) {} | |||||
}; | }; | ||||
/** | /** | ||||
* Used to track blocks whose transactions were applied to the UTXO state as a | * Used to track blocks whose transactions were applied to the UTXO state as a | ||||
* part of a single ActivateBestChainStep call. | * part of a single ActivateBestChainStep call. | ||||
* | * | ||||
* This class also tracks transactions that are removed from the mempool as | |||||
* conflicts (per block) and can be used to pass all those transactions through | |||||
* SyncTransaction. | |||||
* | |||||
* This class assumes (and asserts) that the conflicted transactions for a given | |||||
* block are added via mempool callbacks prior to the BlockConnected() | |||||
* associated with those transactions. If any transactions are marked | |||||
* conflicted, it is assumed that an associated block will always be added. | |||||
* | |||||
* 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; | CTxMemPool &pool; | ||||
boost::signals2::scoped_connection m_connNotifyEntryRemoved; | boost::signals2::scoped_connection m_connNotifyEntryRemoved; | ||||
Show All 17 Lines | public: | ||||
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); | ||||
assert(blocksConnected.back().conflictedTxs->empty()); | |||||
blocksConnected.pop_back(); | blocksConnected.pop_back(); | ||||
return blocksConnected; | return blocksConnected; | ||||
} | } | ||||
void NotifyEntryRemoved(CTransactionRef txRemoved, | void NotifyEntryRemoved(CTransactionRef txRemoved, | ||||
MemPoolRemovalReason reason) { | MemPoolRemovalReason reason) { | ||||
assert(!blocksConnected.back().pindex); | assert(!blocksConnected.back().pindex); | ||||
if (reason == MemPoolRemovalReason::CONFLICT) { | |||||
blocksConnected.back().conflictedTxs->emplace_back( | |||||
std::move(txRemoved)); | |||||
} | |||||
} | } | ||||
}; | }; | ||||
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. | ||||
▲ Show 20 Lines • Show All 3,612 Lines • Show Last 20 Lines |