mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-09 15:28:09 -05:00
Stop adding bad proposed block to bad block manager (#5082)
* Add flag to distinguish when bad block is a proposed block Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Add flag to distinguish when bad block is a proposed block Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * javadoc Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Add shouldRecordBadBlock flag to stop adding proposed bad blocks to the bad block manager Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Add overload to validateAndProcessBlock with shouldRecordBadBlock flag Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Add unit test to ensure flag is being used to add blocks to bad block manager Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Add unit test to ensure we don't add our own proposed bad block to the bad block manager Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Add debug log when badBlock is not added Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Undo change done in the first approach Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Improve log Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Improve test names Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Improve javadoc of validateProposedBlock method Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Remove method from interface Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> * Change validateProposedBlock access modifier to private Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com> --------- Signed-off-by: Gabriel Fukushima <gabrielfukushima@gmail.com>
This commit is contained in:
committed by
GitHub
parent
32583f467e
commit
66521cb3f2
@@ -270,7 +270,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
.createBlock(Optional.of(Collections.emptyList()), prevRandao, timestamp, withdrawals)
|
||||
.getBlock();
|
||||
|
||||
BlockProcessingResult result = validateBlock(emptyBlock);
|
||||
BlockProcessingResult result = validateProposedBlock(emptyBlock);
|
||||
if (result.isSuccessful()) {
|
||||
mergeContext.putPayloadById(
|
||||
payloadIdentifier, new BlockWithReceipts(emptyBlock, result.getReceipts()));
|
||||
@@ -401,7 +401,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
|
||||
if (isBlockCreationCancelled(payloadIdentifier)) return;
|
||||
|
||||
final var resultBest = validateBlock(bestBlock);
|
||||
final var resultBest = validateProposedBlock(bestBlock);
|
||||
if (resultBest.isSuccessful()) {
|
||||
|
||||
if (isBlockCreationCancelled(payloadIdentifier)) return;
|
||||
@@ -494,6 +494,22 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
private BlockProcessingResult validateProposedBlock(final Block block) {
|
||||
final var validationResult =
|
||||
protocolSchedule
|
||||
.getByBlockHeader(block.getHeader())
|
||||
.getBlockValidator()
|
||||
.validateAndProcessBlock(
|
||||
protocolContext,
|
||||
block,
|
||||
HeaderValidationMode.FULL,
|
||||
HeaderValidationMode.NONE,
|
||||
false,
|
||||
false);
|
||||
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockProcessingResult rememberBlock(final Block block) {
|
||||
debugLambda(LOG, "Remember block {}", block::toLogString);
|
||||
|
||||
@@ -317,6 +317,26 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
|
||||
verify(willThrow, never()).addBadBlock(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotRecordProposedBadBlockToBadBlockManager()
|
||||
throws ExecutionException, InterruptedException {
|
||||
// set up invalid parent to simulate one of the many conditions that can cause a block
|
||||
// validation to fail
|
||||
final BlockHeader invalidParentHeader = new BlockHeaderTestFixture().buildHeader();
|
||||
|
||||
blockCreationTask.get();
|
||||
|
||||
coordinator.preparePayload(
|
||||
invalidParentHeader,
|
||||
System.currentTimeMillis() / 1000,
|
||||
Bytes32.ZERO,
|
||||
suggestedFeeRecipient,
|
||||
Optional.empty());
|
||||
|
||||
verify(badBlockManager, never()).addBadBlock(any(), any());
|
||||
assertThat(badBlockManager.getBadBlocks().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldContinueBuildingBlocksUntilFinalizeIsCalled()
|
||||
throws InterruptedException, ExecutionException {
|
||||
|
||||
@@ -35,6 +35,14 @@ public interface BlockValidator {
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final boolean shouldPersist);
|
||||
|
||||
BlockProcessingResult validateAndProcessBlock(
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final HeaderValidationMode headerValidationMode,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final boolean shouldPersist,
|
||||
final boolean shouldRecordBadBlock);
|
||||
|
||||
boolean fastBlockValidation(
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
|
||||
@@ -71,7 +71,8 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
final Block block,
|
||||
final HeaderValidationMode headerValidationMode,
|
||||
final HeaderValidationMode ommerValidationMode) {
|
||||
return validateAndProcessBlock(context, block, headerValidationMode, ommerValidationMode, true);
|
||||
return validateAndProcessBlock(
|
||||
context, block, headerValidationMode, ommerValidationMode, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,6 +82,18 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
final HeaderValidationMode headerValidationMode,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final boolean shouldPersist) {
|
||||
return validateAndProcessBlock(
|
||||
context, block, headerValidationMode, ommerValidationMode, shouldPersist, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockProcessingResult validateAndProcessBlock(
|
||||
final ProtocolContext context,
|
||||
final Block block,
|
||||
final HeaderValidationMode headerValidationMode,
|
||||
final HeaderValidationMode ommerValidationMode,
|
||||
final boolean shouldPersist,
|
||||
final boolean shouldRecordBadBlock) {
|
||||
|
||||
final BlockHeader header = block.getHeader();
|
||||
final BlockHeader parentHeader;
|
||||
@@ -93,7 +106,7 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
var retval =
|
||||
new BlockProcessingResult(
|
||||
"Parent block with hash " + header.getParentHash() + " not present");
|
||||
handleAndLogImportFailure(block, retval);
|
||||
handleAndLogImportFailure(block, retval, shouldRecordBadBlock);
|
||||
return retval;
|
||||
}
|
||||
parentHeader = maybeParentHeader.get();
|
||||
@@ -101,12 +114,12 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
if (!blockHeaderValidator.validateHeader(
|
||||
header, parentHeader, context, headerValidationMode)) {
|
||||
var retval = new BlockProcessingResult("header validation rule violated, see logs");
|
||||
handleAndLogImportFailure(block, retval);
|
||||
handleAndLogImportFailure(block, retval, shouldRecordBadBlock);
|
||||
return retval;
|
||||
}
|
||||
} catch (StorageException ex) {
|
||||
var retval = new BlockProcessingResult(Optional.empty(), ex);
|
||||
handleAndLogImportFailure(block, retval);
|
||||
handleAndLogImportFailure(block, retval, shouldRecordBadBlock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -129,19 +142,19 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
"Unable to process block because parent world state "
|
||||
+ parentHeader.getStateRoot()
|
||||
+ " is not available");
|
||||
handleAndLogImportFailure(block, retval);
|
||||
handleAndLogImportFailure(block, retval, shouldRecordBadBlock);
|
||||
return retval;
|
||||
}
|
||||
var result = processBlock(context, worldState, block);
|
||||
if (result.isFailed()) {
|
||||
handleAndLogImportFailure(block, result);
|
||||
handleAndLogImportFailure(block, result, shouldRecordBadBlock);
|
||||
return result;
|
||||
} else {
|
||||
List<TransactionReceipt> receipts =
|
||||
result.getYield().map(BlockProcessingOutputs::getReceipts).orElse(new ArrayList<>());
|
||||
if (!blockBodyValidator.validateBody(
|
||||
context, block, receipts, worldState.rootHash(), ommerValidationMode)) {
|
||||
handleAndLogImportFailure(block, result);
|
||||
handleAndLogImportFailure(block, result, shouldRecordBadBlock);
|
||||
return new BlockProcessingResult("failed to validate output of imported block");
|
||||
}
|
||||
if (result instanceof GoQuorumBlockProcessingResult) {
|
||||
@@ -174,11 +187,13 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
synchronizer -> synchronizer.healWorldState(ex.getMaybeAddress(), ex.getLocation()),
|
||||
() ->
|
||||
handleAndLogImportFailure(
|
||||
block, new BlockProcessingResult(Optional.empty(), ex)));
|
||||
block,
|
||||
new BlockProcessingResult(Optional.empty(), ex),
|
||||
shouldRecordBadBlock));
|
||||
return new BlockProcessingResult(Optional.empty(), ex);
|
||||
} catch (StorageException ex) {
|
||||
var retval = new BlockProcessingResult(Optional.empty(), ex);
|
||||
handleAndLogImportFailure(block, retval);
|
||||
handleAndLogImportFailure(block, retval, shouldRecordBadBlock);
|
||||
return retval;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
@@ -186,7 +201,9 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
}
|
||||
|
||||
private void handleAndLogImportFailure(
|
||||
final Block invalidBlock, final BlockValidationResult result) {
|
||||
final Block invalidBlock,
|
||||
final BlockValidationResult result,
|
||||
final boolean shouldRecordBadBlock) {
|
||||
if (result.causedBy().isPresent()) {
|
||||
LOG.info(
|
||||
"Invalid block {}: {}, caused by {}",
|
||||
@@ -201,7 +218,11 @@ public class MainnetBlockValidator implements BlockValidator {
|
||||
LOG.info("Invalid block {}", invalidBlock.toLogString());
|
||||
}
|
||||
}
|
||||
badBlockManager.addBadBlock(invalidBlock, result.causedBy());
|
||||
if (shouldRecordBadBlock) {
|
||||
badBlockManager.addBadBlock(invalidBlock, result.causedBy());
|
||||
} else {
|
||||
LOG.debug("Invalid block {} not added to badBlockManager ", invalidBlock.toLogString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -223,4 +223,48 @@ public class MainnetBlockValidatorTest {
|
||||
HeaderValidationMode.DETACHED_ONLY);
|
||||
assertThat(badBlockManager.getBadBlock(badBlock.getHash())).containsSame(badBlock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_shouldRecordBadBlockIsFalse_Expect_BlockNotAddedToBadBlockManager() {
|
||||
when(blockchain.getBlockHeader(any(Hash.class)))
|
||||
.thenReturn(Optional.of(new BlockHeaderTestFixture().buildHeader()));
|
||||
mainnetBlockValidator.validateAndProcessBlock(
|
||||
protocolContext,
|
||||
badBlock,
|
||||
HeaderValidationMode.DETACHED_ONLY,
|
||||
HeaderValidationMode.DETACHED_ONLY,
|
||||
false,
|
||||
false);
|
||||
|
||||
assertThat(badBlockManager.getBadBlocks().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_shouldRecordBadBlockIsTrue_Expect_BlockAddedToBadBlockManager() {
|
||||
when(blockchain.getBlockHeader(any(Hash.class)))
|
||||
.thenReturn(Optional.of(new BlockHeaderTestFixture().buildHeader()));
|
||||
mainnetBlockValidator.validateAndProcessBlock(
|
||||
protocolContext,
|
||||
badBlock,
|
||||
HeaderValidationMode.DETACHED_ONLY,
|
||||
HeaderValidationMode.DETACHED_ONLY,
|
||||
false,
|
||||
true);
|
||||
|
||||
assertThat(badBlockManager.getBadBlocks().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_shouldRecordBadBlockIsNotSet_Expect_BlockAddedToBadBlockManager() {
|
||||
when(blockchain.getBlockHeader(any(Hash.class)))
|
||||
.thenReturn(Optional.of(new BlockHeaderTestFixture().buildHeader()));
|
||||
mainnetBlockValidator.validateAndProcessBlock(
|
||||
protocolContext,
|
||||
badBlock,
|
||||
HeaderValidationMode.DETACHED_ONLY,
|
||||
HeaderValidationMode.DETACHED_ONLY,
|
||||
false);
|
||||
|
||||
assertThat(badBlockManager.getBadBlocks().size()).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user