Reduce memory usage of CBlockIndex
Ported code from https://github.com/zcash/zcash/pull/6192 with various changes needed for the Hush codebase.
This commit is contained in:
79
src/chain.h
79
src/chain.h
@@ -27,6 +27,7 @@ class CChainPower;
|
||||
#include "pow.h"
|
||||
#include "tinyformat.h"
|
||||
#include "uint256.h"
|
||||
#include "util/strencodings.h"
|
||||
#include <vector>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
@@ -384,8 +385,14 @@ public:
|
||||
unsigned int nTime;
|
||||
unsigned int nBits;
|
||||
uint256 nNonce;
|
||||
protected:
|
||||
// The Equihash solution, if it is stored. Once we know that the block index
|
||||
// entry is present in leveldb, this field can be cleared via the TrimSolution
|
||||
// method to save memory.
|
||||
std::vector<unsigned char> nSolution;
|
||||
|
||||
public:
|
||||
|
||||
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
|
||||
uint32_t nSequenceId;
|
||||
|
||||
@@ -497,23 +504,15 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
CBlockHeader GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashFinalSaplingRoot = hashFinalSaplingRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
block.nSolution = nSolution;
|
||||
return block;
|
||||
}
|
||||
//! Get the block header for this block index. Requires cs_main.
|
||||
CBlockHeader GetBlockHeader() const;
|
||||
|
||||
//! Clear the Equihash solution to save memory. Requires cs_main.
|
||||
void TrimSolution();
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
{
|
||||
assert(phashBlock);
|
||||
return *phashBlock;
|
||||
}
|
||||
|
||||
@@ -540,10 +539,11 @@ public:
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s, HasSolution=%s)",
|
||||
pprev, this->chainPower.nHeight,
|
||||
hashMerkleRoot.ToString(),
|
||||
GetBlockHash().ToString());
|
||||
phashBlock ? GetBlockHash().ToString() : "(nil)",
|
||||
HasSolution());
|
||||
}
|
||||
|
||||
//! Check whether this block index entry is valid up to the passed validity level.
|
||||
@@ -555,6 +555,12 @@ public:
|
||||
return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
|
||||
}
|
||||
|
||||
//! Is the Equihash solution stored?
|
||||
bool HasSolution() const
|
||||
{
|
||||
return !nSolution.empty();
|
||||
}
|
||||
|
||||
//! Raise the validity level of this block index entry.
|
||||
//! Returns true if the validity was changed.
|
||||
bool RaiseValidity(enum BlockStatus nUpTo)
|
||||
@@ -588,8 +594,11 @@ public:
|
||||
hashPrev = uint256();
|
||||
}
|
||||
|
||||
explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
|
||||
explicit CDiskBlockIndex(const CBlockIndex* pindex, std::function<std::vector<unsigned char>()> getSolution) : CBlockIndex(*pindex) {
|
||||
hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
|
||||
if (!HasSolution()) {
|
||||
nSolution = getSolution();
|
||||
}
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
@@ -668,20 +677,27 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
//! Get the block header for this block index.
|
||||
CBlockHeader GetBlockHeader() const
|
||||
{
|
||||
CBlockHeader block;
|
||||
block.nVersion = nVersion;
|
||||
block.hashPrevBlock = hashPrev;
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.hashFinalSaplingRoot = hashFinalSaplingRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
block.nSolution = nSolution;
|
||||
return block.GetHash();
|
||||
CBlockHeader header;
|
||||
header.nVersion = nVersion;
|
||||
header.hashPrevBlock = hashPrev;
|
||||
header.hashMerkleRoot = hashMerkleRoot;
|
||||
// Hush does not have this, maybe some day
|
||||
// header.hashBlockCommitments = hashBlockCommitments;
|
||||
header.nTime = nTime;
|
||||
header.nBits = nBits;
|
||||
header.nNonce = nNonce;
|
||||
header.nSolution = nSolution;
|
||||
return header;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> GetSolution() const
|
||||
{
|
||||
assert(HasSolution());
|
||||
return nSolution;
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
@@ -692,6 +708,13 @@ public:
|
||||
hashPrev.ToString());
|
||||
return str;
|
||||
}
|
||||
|
||||
private:
|
||||
//! This method should not be called on a CDiskBlockIndex.
|
||||
void TrimSolution()
|
||||
{
|
||||
assert(!"called CDiskBlockIndex::TrimSolution");
|
||||
}
|
||||
};
|
||||
|
||||
/** An in-memory indexed chain of blocks. */
|
||||
|
||||
Reference in New Issue
Block a user