diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-10-21 11:13:46 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-10-21 11:14:31 +0200 |
commit | c0e51394139822137ca090f23e60cfe0cad4d123 (patch) | |
tree | 7554494f0f074eefb4dcd92aeefb6d3c6e5010a8 /src | |
parent | e668a6e61d4fc4e4453f80f11eacdf808e786b59 (diff) | |
parent | 01b52cedd42f50a93b40981c91af7c12de6e45ce (diff) | |
download | bitcoin-c0e51394139822137ca090f23e60cfe0cad4d123.tar.xz |
Merge #11458: Don't process unrequested, low-work blocks
01b52ce Add comment explaining forced processing of compact blocks (Suhas Daftuar)
08fd822 qa: add test for minchainwork use in acceptblock (Suhas Daftuar)
ce8cd7a Don't process unrequested, low-work blocks (Suhas Daftuar)
Pull request description:
A peer could try to waste our resources by sending us unrequested blocks with
low work (eg to fill up our disk). Since e265200 we no longer request blocks until we
know we're on a chain with more than nMinimumChainWork (our anti-DoS
threshold), but we would still process unrequested blocks that had more work
than our tip (which generally has low-work during IBD), even though we may not
yet have found a headers chain with sufficient work.
Fix this and add a test.
Tree-SHA512: 1a4fb0bbd78054b84683f995c8c3194dd44fa914dc351ae4379c7c1a6f83224f609f8b9c2d9dde28741426c6af008ffffea836d21aa31a5ebaa00f8e0f81229e
Diffstat (limited to 'src')
-rw-r--r-- | src/net_processing.cpp | 17 | ||||
-rw-r--r-- | src/validation.cpp | 6 |
2 files changed, 21 insertions, 2 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 6c26cd4cee..61f98ca747 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2146,7 +2146,16 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr mapBlockSource.emplace(pblock->GetHash(), std::make_pair(pfrom->GetId(), false)); } bool fNewBlock = false; - ProcessNewBlock(chainparams, pblock, true, &fNewBlock); + // Setting fForceProcessing to true means that we bypass some of + // our anti-DoS protections in AcceptBlock, which filters + // unrequested blocks that might be trying to waste our resources + // (eg disk space). Because we only try to reconstruct blocks when + // we're close to caught up (via the CanDirectFetch() requirement + // above, combined with the behavior of not requesting blocks until + // we have a chain with at least nMinimumChainWork), and we ignore + // compact blocks with less work than our tip, it is safe to treat + // reconstructed compact blocks as having been requested. + ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock); if (fNewBlock) { pfrom->nLastBlockTime = GetTime(); } else { @@ -2226,7 +2235,11 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr bool fNewBlock = false; // Since we requested this block (it was in mapBlocksInFlight), force it to be processed, // even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc) - ProcessNewBlock(chainparams, pblock, true, &fNewBlock); + // This bypasses some anti-DoS logic in AcceptBlock (eg to prevent + // disk-space attacks), but this should be safe due to the + // protections in the compact block handler -- see related comment + // in compact block optimistic reconstruction handling. + ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock); if (fNewBlock) { pfrom->nLastBlockTime = GetTime(); } else { diff --git a/src/validation.cpp b/src/validation.cpp index d19521bd3c..866e0c9fba 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3135,6 +3135,12 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned if (!fHasMoreWork) return true; // Don't process less-work chains if (fTooFarAhead) return true; // Block height is too high + + // Protect against DoS attacks from low-work chains. + // If our tip is behind, a peer could try to send us + // low-work blocks on a fake chain that we would never + // request; don't process these. + if (pindex->nChainWork < nMinimumChainWork) return true; } if (fNewBlock) *fNewBlock = true; |