Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static CBlock FindDevNetGenesisBlock(const CBlock &prevBlock, const CAmount& rew
for (uint32_t nNonce = 0; nNonce < UINT32_MAX; nNonce++) {
block.nNonce = nNonce;

uint256 hash = block.GetHash();
uint256 hash = block.GetHash(/*use_cache=*/false);
if (UintToArith256(hash) <= bnTarget)
return block;
}
Expand Down
13 changes: 8 additions & 5 deletions src/primitives/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
#include <streams.h>
#include <tinyformat.h>

uint256 CBlockHeader::GetHash() const
uint256 CBlockHeader::GetHash(bool use_cache) const
{
std::vector<unsigned char> vch(80);
CVectorWriter ss(SER_GETHASH, PROTOCOL_VERSION, vch, 0);
ss << *this;
return HashX11((const char *)vch.data(), (const char *)vch.data() + vch.size());
if (!use_cache || cached_hash.IsNull()) {
std::vector<unsigned char> vch(80);
CVectorWriter ss(SER_GETHASH, PROTOCOL_VERSION, vch, 0);
ss << *this;
cached_hash = HashX11((const char *)vch.data(), (const char *)vch.data() + vch.size());
}
return cached_hash;
}

std::string CBlock::ToString() const
Expand Down
12 changes: 10 additions & 2 deletions src/primitives/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@ class CBlockHeader
uint32_t nBits;
uint32_t nNonce;

// Memory only cached hash as x11 is more expensive than sha256
mutable uint256 cached_hash;

CBlockHeader()
{
SetNull();
}

SERIALIZE_METHODS(CBlockHeader, obj) { READWRITE(obj.nVersion, obj.hashPrevBlock, obj.hashMerkleRoot, obj.nTime, obj.nBits, obj.nNonce); }
SERIALIZE_METHODS(CBlockHeader, obj) {
READWRITE(obj.nVersion, obj.hashPrevBlock, obj.hashMerkleRoot, obj.nTime, obj.nBits, obj.nNonce);
obj.cached_hash.SetNull();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may reset only in case of read event

}

void SetNull()
{
Expand All @@ -46,14 +52,15 @@ class CBlockHeader
nTime = 0;
nBits = 0;
nNonce = 0;
cached_hash.SetNull();
}

bool IsNull() const
{
return (nBits == 0);
}

uint256 GetHash() const;
uint256 GetHash(bool use_cache = true) const;

int64_t GetBlockTime() const
{
Expand Down Expand Up @@ -225,6 +232,7 @@ class CBlock : public CBlockHeader
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.cached_hash = cached_hash;
return block;
}

Expand Down
2 changes: 1 addition & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&

CChainParams chainparams(Params());

while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus()) && !ShutdownRequested()) {
while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(/*use_cache=*/false), block.nBits, chainparams.GetConsensus()) && !ShutdownRequested()) {
++block.nNonce;
--max_tries;
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/blockencodings_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static CBlock BuildBlockTestCase() {
bool mutated;
block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
assert(!mutated);
while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
while (!CheckProofOfWork(block.GetHash(/*use_cache=*/false), block.nBits, Params().GetConsensus())) ++block.nNonce;
return block;
}

Expand Down Expand Up @@ -275,7 +275,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
bool mutated;
block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
assert(!mutated);
while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
while (!CheckProofOfWork(block.GetHash(/*use_cache=*/false), block.nBits, Params().GetConsensus())) ++block.nNonce;

// Test simple header round-trip with only coinbase
{
Expand Down
2 changes: 1 addition & 1 deletion src/test/blockfilter_index_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
unsigned int extraNonce = 0;
IncrementExtraNonce(&block, prev, extraNonce);

while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
while (!CheckProofOfWork(block.GetHash(/*use_cache=*/false), block.nBits, chainparams.GetConsensus())) ++block.nNonce;

return block;
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/miner_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)

// This will usually succeed in the first round as we take the nonce from BLOCKINFO
// It's however useful when adding new blocks with unknown nonces (you should add the found block to BLOCKINFO)
while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, chainparams.GetConsensus())) {
while (!CheckProofOfWork(pblock->GetHash(/*use_cache=*/false), pblock->nBits, chainparams.GetConsensus())) {
pblock->nNonce++;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/util/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const
block.nBits = params.GenesisBlock().nBits;
block.nNonce = 0;

while (!CheckProofOfWork(block.GetHash(), block.nBits, params.GetConsensus())) {
while (!CheckProofOfWork(block.GetHash(/*use_cache=*/false), block.nBits, params.GetConsensus())) {
++block.nNonce;
assert(block.nNonce);
}
Expand All @@ -62,7 +62,7 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{
auto block = PrepareBlock(node, coinbase_scriptPubKey);

while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
while (!CheckProofOfWork(block->GetHash(/*use_cache=*/false), block->nBits, Params().GetConsensus())) {
++block->nNonce;
assert(block->nNonce);
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ CBlock TestChainSetup::CreateBlock(
IncrementExtraNonce(&block, chainstate.m_chain.Tip(), extraNonce);
}

while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
while (!CheckProofOfWork(block.GetHash(/*use_cache=*/false), block.nBits, chainparams.GetConsensus())) ++block.nNonce;

CBlock result = block;
return result;
Expand Down
2 changes: 1 addition & 1 deletion src/test/validation_block_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock>
{
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);

while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
while (!CheckProofOfWork(pblock->GetHash(/*use_cache=*/false), pblock->nBits, Params().GetConsensus())) {
++(pblock->nNonce);
}

Expand Down
2 changes: 2 additions & 0 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4973,6 +4973,8 @@ void CChainState::LoadExternalBlockFile(
blkdat.SetPos(nBlockPos);
std::shared_ptr<CBlock> pblock{std::make_shared<CBlock>()};
blkdat >> *pblock;
// We calculated the hash of the header earlier, no need to recalculate it.
pblock->cached_hash = hash;
nRewind = blkdat.GetPos();

BlockValidationState state;
Expand Down
Loading