mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
[net processing] Don't process mutated blocks
We preemptively perform a block mutation check before further processing
a block message (similar to early sanity checks on other messsage
types). The main reasons for this change are as follows:
- `CBlock::GetHash()` is a foot-gun without a prior mutation check, as
the hash returned only commits to the header but not to the actual
transactions (`CBlock::vtx`) contained in the block.
- We have observed attacks that abused mutated blocks in the past, which
could have been prevented by simply not processing mutated blocks
(e.g. https://github.com/bitcoin/bitcoin/pull/27608).
Github-Pull: #29412
Rebased-From: 49257c0304
This commit is contained in:
parent
098f07dc8d
commit
8cc4b24c74
1 changed files with 10 additions and 1 deletions
|
@ -4629,6 +4629,16 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
LogPrint(BCLog::NET, "received block %s peer=%d\n", pblock->GetHash().ToString(), pfrom.GetId());
|
LogPrint(BCLog::NET, "received block %s peer=%d\n", pblock->GetHash().ToString(), pfrom.GetId());
|
||||||
|
|
||||||
|
const CBlockIndex* prev_block{WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.LookupBlockIndex(pblock->hashPrevBlock))};
|
||||||
|
|
||||||
|
if (IsBlockMutated(/*block=*/*pblock,
|
||||||
|
/*check_witness_root=*/DeploymentActiveAfter(prev_block, m_chainman, Consensus::DEPLOYMENT_SEGWIT))) {
|
||||||
|
LogPrint(BCLog::NET, "Received mutated block from peer=%d\n", peer->m_id);
|
||||||
|
Misbehaving(*peer, 100, "mutated block");
|
||||||
|
WITH_LOCK(cs_main, RemoveBlockRequest(pblock->GetHash(), peer->m_id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool forceProcessing = false;
|
bool forceProcessing = false;
|
||||||
const uint256 hash(pblock->GetHash());
|
const uint256 hash(pblock->GetHash());
|
||||||
bool min_pow_checked = false;
|
bool min_pow_checked = false;
|
||||||
|
@ -4644,7 +4654,6 @@ 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 work on this block against our anti-dos thresholds.
|
// Check work on this block against our anti-dos thresholds.
|
||||||
const CBlockIndex* prev_block = m_chainman.m_blockman.LookupBlockIndex(pblock->hashPrevBlock);
|
|
||||||
if (prev_block && prev_block->nChainWork + CalculateHeadersWork({pblock->GetBlockHeader()}) >= GetAntiDoSWorkThreshold()) {
|
if (prev_block && prev_block->nChainWork + CalculateHeadersWork({pblock->GetBlockHeader()}) >= GetAntiDoSWorkThreshold()) {
|
||||||
min_pow_checked = true;
|
min_pow_checked = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue