Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@ public void handleNewBlockEvent(final QbftNewChainHead newChainHead) {
@Override
public void handleBlockTimerExpiry(final BlockTimerExpiry blockTimerExpiry) {
final ConsensusRoundIdentifier roundIdentifier = blockTimerExpiry.getRoundIdentifier();
// Discard block timer events that target a height already on the blockchain (e.g., block
// was imported via peer sync while the timer was pending). Same guard as handleRoundExpiry.
if (roundIdentifier.getSequenceNumber() <= blockchain.getChainHeadBlockNumber()) {
LOG.debug("Discarding a block-timer which targets a height not above current chain height.");
return;
}
if (isMsgForCurrentHeight(roundIdentifier, getCurrentChainHeight())) {
getCurrentHeightManager().handleBlockTimerExpiry(roundIdentifier);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,28 @@ public void blockTimerForPastHeightIsDiscarded() {
verify(blockHeightManager, never()).handleBlockTimerExpiry(any());
}

@Test
public void blockTimerForAlreadyImportedHeightIsDiscarded() {
Comment thread
Qian-Cheng-nju marked this conversation as resolved.
// Simulate peer sync: blockchain head advances to current height while block timer is pending
when(blockChain.getChainHeadBlockNumber()).thenReturn(4L);
final BlockTimerExpiry blockTimerExpiry = new BlockTimerExpiry(roundIdentifier);
constructQbftController();
qbftController.start();
qbftController.handleBlockTimerExpiry(blockTimerExpiry);
verify(blockHeightManager, never()).handleBlockTimerExpiry(any());
}

@Test
public void blockTimerForHeightBelowChainHeadIsDiscarded() {
// Blockchain head has advanced beyond the timer's target height
when(blockChain.getChainHeadBlockNumber()).thenReturn(5L);
final BlockTimerExpiry blockTimerExpiry = new BlockTimerExpiry(roundIdentifier);
constructQbftController();
qbftController.start();
qbftController.handleBlockTimerExpiry(blockTimerExpiry);
verify(blockHeightManager, never()).handleBlockTimerExpiry(any());
}

@Test
public void proposalForUnknownValidatorIsDiscarded() {
setupProposal(roundIdentifier, unknownValidator);
Expand Down
Loading