We do not mark any blocks that fail CheckBlock()
as BLOCK_FAILED_VALID
since they could have been mutated and marking a valid-but-mutated block
as invalid would prevent us from ever syncing to that chain. See
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-February/016697.html
for full details.
The current guard against marking CheckBlock()
failed blocks as invalid
is by calling CheckBlock()
prior to AcceptBlock()
in ProcessNewBlock()
.
That is brittle since AcceptBlock()
has an implicit assumption that any
block submitted has been checked for mutation. A future change to
ProcessNewBlock()
could overlook that implicit assumption and introduce
a consensus failure.
Move the mutation guard logic into AcceptBlock()
and
add comments to explain why we never mark CheckBlock()
failed blocks as
invalid.