I think CDiskBlockIndex::ToString is only used in the fuzz test; and renaming GetBlockHash to CalculateBlockHash would help avoid the “virtual” concerns:
0 uint256 GetBlockHash() const = delete;
1 uint256 CalculateBlockHash() const
2 {
3 CBlockHeader block;
4 block.nVersion = nVersion;
5 ...
6 }
7
8 std::string ToString() const = delete;
9};
Another alternative might be:
0class CDiskBlockIndex
1{
2private:
3 CBlockIndex m_cbi;
4public:
5 uint256 hashPrev;
6 CDiskBlockIndex(const CBlockIndex* pindex)
7 {
8 m_cbi.pprev = pindex->pprev;
9 m_cbi.nHeight = pindex->nHeight;
10 ...
11 }
12 void SetCBlockIndex(CBlockIndex* pindex) const
13 {
14 pindex->nHeight = m_cbi.nHeight;
15 ...
16 }
17 uint256 CalculateBlockHash() const;
18 SERIALIZE_METHODS(...) { ... }
19};
ie, defining the “copy” code explicitly, which would let you move the explicit copy code in CBlockTreeDB::LoadBlockIndexGuts() into diskindex.Set(pindexNew);. At least they’re in one place, that way, and you can prevent any implicit copies of CBlockIndex?
I’m not seeing any other ways of improving on this though – you can’t have CDiskBlockIndex use a reference to a CBlockIndex, because the ref has to be non-const for deserialization, and const for serialization, and it can’t simultaneously be both; and you can’t move de/serialization into CBlockIndex because it needs to store hashPrev on deser, and doesn’t have anywhere to do so…