This repository has been archived by the owner on Sep 26, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 130
[MINOR] Eliminate redundant header validation #943
Merged
smatthewenglish
merged 10 commits into
PegaSysEng:master
from
smatthewenglish:eliminate-redundant-header-validation
Feb 26, 2019
Merged
Changes from 8 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
84553d9
Remove start functionality from IbftController and IbftBlockHeightMan…
rain-on 6909886
Merge remote-tracking branch 'upstream/master' into eliminate-redunda…
smatthewenglish 9924c33
update
smatthewenglish 06cceab
update II
smatthewenglish 4b3c554
update x
smatthewenglish bba49b6
threading
smatthewenglish d6ed372
return value
smatthewenglish 4e95cca
nxt-update
smatthewenglish 9c8804f
update update
smatthewenglish dac5a76
Merge remote-tracking branch 'upstream/master' into eliminate-redunda…
smatthewenglish File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,32 +109,6 @@ private void setupListeners() { | |
.subscribe(EthPV62.NEW_BLOCK_HASHES, this::handleNewBlockHashesFromNetwork); | ||
} | ||
|
||
private void validateAndBroadcastBlock(final Block block) { | ||
final ProtocolSpec<C> protocolSpec = | ||
protocolSchedule.getByBlockNumber(block.getHeader().getNumber()); | ||
final BlockHeaderValidator<C> blockHeaderValidator = protocolSpec.getBlockHeaderValidator(); | ||
final BlockHeader parent = | ||
protocolContext | ||
.getBlockchain() | ||
.getBlockHeader(block.getHeader().getParentHash()) | ||
.orElseThrow( | ||
() -> | ||
new IllegalArgumentException( | ||
"Incapable of retrieving header from non-existent parent of " | ||
+ block.getHeader().getNumber() | ||
+ ".")); | ||
if (blockHeaderValidator.validateHeader( | ||
block.getHeader(), parent, protocolContext, HeaderValidationMode.FULL)) { | ||
final UInt256 totalDifficulty = | ||
protocolContext | ||
.getBlockchain() | ||
.getTotalDifficultyByHash(parent.getHash()) | ||
.get() | ||
.plus(block.getHeader().getDifficulty()); | ||
blockBroadcaster.propagate(block, totalDifficulty); | ||
} | ||
} | ||
|
||
private void onBlockAdded(final BlockAddedEvent blockAddedEvent, final Blockchain blockchain) { | ||
// Check to see if any of our pending blocks are now ready for import | ||
final Block newBlock = blockAddedEvent.getBlock(); | ||
|
@@ -263,6 +237,16 @@ private CompletableFuture<Block> processAnnouncedBlock( | |
return getBlockTask.run().thenCompose((r) -> importOrSavePendingBlock(r.getResult())); | ||
} | ||
|
||
private void broadcastBlock(final Block block, final BlockHeader parent) { | ||
final UInt256 totalDifficulty = | ||
protocolContext | ||
.getBlockchain() | ||
.getTotalDifficultyByHash(parent.getHash()) | ||
.get() | ||
.plus(block.getHeader().getDifficulty()); | ||
blockBroadcaster.propagate(block, totalDifficulty); | ||
} | ||
|
||
@VisibleForTesting | ||
CompletableFuture<Block> importOrSavePendingBlock(final Block block) { | ||
// Synchronize to avoid race condition where block import event fires after the | ||
|
@@ -292,19 +276,54 @@ CompletableFuture<Block> importOrSavePendingBlock(final Block block) { | |
return CompletableFuture.completedFuture(block); | ||
} | ||
|
||
ethContext.getScheduler().scheduleSyncWorkerTask(() -> validateAndBroadcastBlock(block)); | ||
final BlockHeader parent = | ||
protocolContext | ||
.getBlockchain() | ||
.getBlockHeader(block.getHeader().getParentHash()) | ||
.orElseThrow( | ||
() -> | ||
new IllegalArgumentException( | ||
"Incapable of retrieving header from non-existent parent of " | ||
+ block.getHeader().getNumber() | ||
+ ".")); | ||
|
||
// Import block | ||
final PersistBlockTask<C> importTask = | ||
PersistBlockTask.create( | ||
protocolSchedule, protocolContext, block, HeaderValidationMode.FULL, metricsSystem); | ||
final ProtocolSpec<C> protocolSpec = | ||
protocolSchedule.getByBlockNumber(block.getHeader().getNumber()); | ||
final BlockHeaderValidator<C> blockHeaderValidator = protocolSpec.getBlockHeaderValidator(); | ||
return ethContext | ||
.getScheduler() | ||
.scheduleSyncWorkerTask(importTask::run) | ||
.scheduleSyncWorkerTask( | ||
() -> validateAndProcessPendingBlock(blockHeaderValidator, block, parent)); | ||
} | ||
|
||
private CompletableFuture<Block> validateAndProcessPendingBlock( | ||
final BlockHeaderValidator<C> blockHeaderValidator, | ||
final Block block, | ||
final BlockHeader parent) { | ||
if (blockHeaderValidator.validateHeader( | ||
block.getHeader(), parent, protocolContext, HeaderValidationMode.FULL)) { | ||
ethContext.getScheduler().scheduleSyncWorkerTask(() -> broadcastBlock(block, parent)); | ||
return ethContext.getScheduler().scheduleSyncWorkerTask(() -> runImportTask(block)); | ||
} else { | ||
importingBlocks.remove(block.getHash()); | ||
LOG.warn( | ||
"Failed to import announced block {} ({}).", | ||
block.getHeader().getNumber(), | ||
block.getHash()); | ||
return CompletableFuture.completedFuture(block); | ||
} | ||
} | ||
|
||
private CompletableFuture<Block> runImportTask(final Block block) { | ||
final PersistBlockTask<C> importTask = | ||
PersistBlockTask.create( | ||
protocolSchedule, protocolContext, block, HeaderValidationMode.NONE, metricsSystem); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we create this inside the if(validate) block so it's only created if it will actually be used? Mostly just so that the first thing you come across isn't |
||
return importTask | ||
.run() | ||
.whenComplete( | ||
(r, t) -> { | ||
(result, throwable) -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to the better naming here. :) |
||
importingBlocks.remove(block.getHash()); | ||
if (t != null) { | ||
if (throwable != null) { | ||
LOG.warn( | ||
"Failed to import announced block {} ({}).", | ||
block.getHeader().getNumber(), | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to defer this to a separate worker task since you're already in a worker thread.