Since this map is a superset of candidate_blocks_by_work
, I think we could just have one, and instead check for IsValid(BLOCK_VALID_TRANSACTIONS) && HaveNumChainTxs()
further down when we update setBlockIndexCandidates
? I suspect the memory impllications should be negligible either way, but I think it would clean up the code a bit?
E.g. something like:
0diff --git a/src/validation.cpp b/src/validation.cpp
1index f9c900ef27..ead0454f7b 100644
2--- a/src/validation.cpp
3+++ b/src/validation.cpp
4@@ -3689,12 +3689,10 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
5 // To avoid walking the block index repeatedly in search of candidates,
6 // build a map once so that we can look up candidate blocks by chain
7 // work as we go.
8- std::multimap<const arith_uint256, CBlockIndex *> candidate_blocks_by_work;
9+ std::multimap<const arith_uint256, CBlockIndex *> highpow_outofchain_headers;
10 // Map to cache candidates not in the main chain that might need invalidating.
11 // Maps fork block in chain to the candidates for invalidation.
12 std::multimap<const CBlockIndex*, CBlockIndex*> cand_invalid_descendants;
13- // Map to cache candidates for m_best_header
14- std::multimap<const arith_uint256, CBlockIndex*> best_header_blocks_by_work;
15
16 {
17 LOCK(cs_main);
18@@ -3706,16 +3704,9 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
19 // Instead, consider only non-active-chain blocks that have at
20 // least as much work as where we expect the new tip to end up.
21 if (!m_chain.Contains(candidate) &&
22- !CBlockIndexWorkComparator()(candidate, pindex->pprev) &&
23- candidate->IsValid(BLOCK_VALID_TRANSACTIONS) &&
24- candidate->HaveNumChainTxs()) {
25- candidate_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate));
26- }
27- // Similarly, populate cache for blocks not in main chain to invalidate
28- if (!m_chain.Contains(candidate) &&
29- !CBlockIndexWorkComparator()(candidate, pindex->pprev)) {
30+ !CBlockIndexWorkComparator()(candidate, pindex->pprev)) {
31+ highpow_outofchain_headers.insert(std::make_pair(candidate->nChainWork, candidate));
32 cand_invalid_descendants.insert(std::make_pair(m_chain.FindFork(candidate), candidate));
33- best_header_blocks_by_work.insert(std::make_pair(candidate->nChainWork, candidate));
34 }
35 }
36 }
37@@ -3774,11 +3765,9 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
38 // Determine new best header
39 if (m_chainman.m_best_header->nStatus & BLOCK_FAILED_MASK) {
40 m_chainman.m_best_header = invalid_walk_tip->pprev;
41- auto best_header_it = best_header_blocks_by_work.lower_bound(m_chainman.m_best_header->nChainWork);
42- while (best_header_it != best_header_blocks_by_work.end()) {
43- if (best_header_it->second->nStatus & BLOCK_FAILED_MASK) {
44- best_header_it = best_header_blocks_by_work.erase(best_header_it);
45- } else {
46+ auto best_header_it = highpow_outofchain_headers.lower_bound(m_chainman.m_best_header->nChainWork);
47+ while (best_header_it != highpow_outofchain_headers.end()) {
48+ if (!(best_header_it->second->nStatus & BLOCK_FAILED_MASK)) {
49 if (!CBlockIndexWorkComparator()(best_header_it->second, m_chainman.m_best_header)) {
50 m_chainman.m_best_header = best_header_it->second;
51 }
52@@ -3788,11 +3777,12 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
53 }
54
55 // Add any equal or more work headers to setBlockIndexCandidates
56- auto candidate_it = candidate_blocks_by_work.lower_bound(invalid_walk_tip->pprev->nChainWork);
57- while (candidate_it != candidate_blocks_by_work.end()) {
58- if (!CBlockIndexWorkComparator()(candidate_it->second, invalid_walk_tip->pprev)) {
59- setBlockIndexCandidates.insert(candidate_it->second);
60- candidate_it = candidate_blocks_by_work.erase(candidate_it);
61+ auto candidate_it = highpow_outofchain_headers.lower_bound(invalid_walk_tip->pprev->nChainWork);
62+ while (candidate_it != highpow_outofchain_headers.end()) {
63+ if (!CBlockIndexWorkComparator()(candidate_it->second, invalid_walk_tip->pprev) &&
64+ candidate_it->second->IsValid(BLOCK_VALID_TRANSACTIONS) &&
65+ candidate_it->second->HaveNumChainTxs()) {
66+ setBlockIndexCandidates.insert(candidate_it->second);
67 } else {
68 ++candidate_it;
69 }