refactor: Compute work from headers without CBlockIndex
Avoid the need to construct a CBlockIndex object just to compute work for a header, when its nBits value suffices for that. Co-Authored-By: Pieter Wuille <pieter@wuille.net>
This commit is contained in:
1 parent
0bf6139e19
commit
4066bfe561
5 files changed
+16
-9
No files matched your search
+2
-2
@@ -124,12 +124,12 @@ void CBlockIndex::BuildSkip()
|
|||||||
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
|
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
arith_uint256 GetBlockProof(const CBlockIndex& block)
|
arith_uint256 GetBitsProof(uint32_t bits)
|
||||||
{
|
{
|
||||||
arith_uint256 bnTarget;
|
arith_uint256 bnTarget;
|
||||||
bool fNegative;
|
bool fNegative;
|
||||||
bool fOverflow;
|
bool fOverflow;
|
||||||
bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
|
bnTarget.SetCompact(bits, &fNegative, &fOverflow);
|
||||||
if (fNegative || fOverflow || bnTarget == 0)
|
if (fNegative || fOverflow || bnTarget == 0)
|
||||||
return 0;
|
return 0;
|
||||||
// We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
|
// We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
|
||||||
|
|||||||
+9
-1
@@ -348,7 +348,15 @@ protected:
|
|||||||
CBlockIndex& operator=(CBlockIndex&&) = delete;
|
CBlockIndex& operator=(CBlockIndex&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
arith_uint256 GetBlockProof(const CBlockIndex& block);
|
/** Compute how much work an nBits value corresponds to. */
|
||||||
|
arith_uint256 GetBitsProof(uint32_t bits);
|
||||||
|
|
||||||
|
/** Compute how much work a block index entry corresponds to. */
|
||||||
|
inline arith_uint256 GetBlockProof(const CBlockIndex& block) { return GetBitsProof(block.nBits); }
|
||||||
|
|
||||||
|
/** Compute how much work a block header corresponds to. */
|
||||||
|
inline arith_uint256 GetBlockProof(const CBlockHeader& header) { return GetBitsProof(header.nBits); }
|
||||||
|
|
||||||
/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
|
/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
|
||||||
int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
|
int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
|
||||||
/** Find the forking point between two chain tips. */
|
/** Find the forking point between two chain tips. */
|
||||||
|
|||||||
+2
-2
@@ -202,7 +202,7 @@ bool HeadersSyncState::ValidateAndProcessSingleHeader(const CBlockHeader& curren
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_current_chain_work += GetBlockProof(CBlockIndex(current));
|
m_current_chain_work += GetBlockProof(current);
|
||||||
m_last_header_received = current;
|
m_last_header_received = current;
|
||||||
m_current_height = next_height;
|
m_current_height = next_height;
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ bool HeadersSyncState::ValidateAndStoreRedownloadedHeader(const CBlockHeader& he
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Track work on the redownloaded chain
|
// Track work on the redownloaded chain
|
||||||
m_redownload_chain_work += GetBlockProof(CBlockIndex(header));
|
m_redownload_chain_work += GetBlockProof(header);
|
||||||
|
|
||||||
if (m_redownload_chain_work >= m_minimum_required_work) {
|
if (m_redownload_chain_work >= m_minimum_required_work) {
|
||||||
m_process_all_remaining_headers = true;
|
m_process_all_remaining_headers = true;
|
||||||
|
|||||||
@@ -4348,7 +4348,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||||||
MaybeSendGetHeaders(pfrom, GetLocator(m_chainman.m_best_header), *peer);
|
MaybeSendGetHeaders(pfrom, GetLocator(m_chainman.m_best_header), *peer);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (prev_block->nChainWork + CalculateClaimedHeadersWork({{cmpctblock.header}}) < GetAntiDoSWorkThreshold()) {
|
} else if (prev_block->nChainWork + GetBlockProof(cmpctblock.header) < GetAntiDoSWorkThreshold()) {
|
||||||
// If we get a low-work header in a compact block, we can ignore it.
|
// If we get a low-work header in a compact block, we can ignore it.
|
||||||
LogDebug(BCLog::NET, "Ignoring low-work compact block from peer %d\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "Ignoring low-work compact block from peer %d\n", pfrom.GetId());
|
||||||
return;
|
return;
|
||||||
@@ -4666,7 +4666,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
|||||||
mapBlockSource.emplace(hash, std::make_pair(pfrom.GetId(), true));
|
mapBlockSource.emplace(hash, std::make_pair(pfrom.GetId(), true));
|
||||||
|
|
||||||
// Check claimed work on this block against our anti-dos thresholds.
|
// Check claimed work on this block against our anti-dos thresholds.
|
||||||
if (prev_block && prev_block->nChainWork + CalculateClaimedHeadersWork({{pblock->GetBlockHeader()}}) >= GetAntiDoSWorkThreshold()) {
|
if (prev_block && prev_block->nChainWork + GetBlockProof(pblock->GetBlockHeader()) >= GetAntiDoSWorkThreshold()) {
|
||||||
min_pow_checked = true;
|
min_pow_checked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -4171,8 +4171,7 @@ arith_uint256 CalculateClaimedHeadersWork(std::span<const CBlockHeader> headers)
|
|||||||
{
|
{
|
||||||
arith_uint256 total_work{0};
|
arith_uint256 total_work{0};
|
||||||
for (const CBlockHeader& header : headers) {
|
for (const CBlockHeader& header : headers) {
|
||||||
CBlockIndex dummy(header);
|
total_work += GetBlockProof(header);
|
||||||
total_work += GetBlockProof(dummy);
|
|
||||||
}
|
}
|
||||||
return total_work;
|
return total_work;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user