use of org.hyperledger.besu.consensus.common.bft.events.NewChainHead in project besu by hyperledger.
the class QbftControllerTest method createsNewBlockHeightManagerAndReplaysFutureMessagesOnNewChainHeadEvent.
@Test
public void createsNewBlockHeightManagerAndReplaysFutureMessagesOnNewChainHeadEvent() {
setupPrepare(futureRoundIdentifier, validator);
setupProposal(futureRoundIdentifier, validator);
setupCommit(futureRoundIdentifier, validator);
setupRoundChange(futureRoundIdentifier, validator);
when(futureMessageBuffer.retrieveMessagesForHeight(5L)).thenReturn(ImmutableList.of(prepareMessage, proposalMessage, commitMessage, roundChangeMessage)).thenReturn(Collections.emptyList());
when(blockHeightManager.getChainHeight()).thenReturn(5L);
constructQbftController();
qbftController.start();
final NewChainHead newChainHead = new NewChainHead(nextBlock);
qbftController.handleNewBlockEvent(newChainHead);
verify(blockHeightManagerFactory).create(nextBlock);
verify(blockHeightManager, atLeastOnce()).getChainHeight();
verify(futureMessageBuffer, times(2)).retrieveMessagesForHeight(5L);
verify(blockHeightManager).handleProposalPayload(proposal);
verify(qbftGossip).send(proposalMessage);
verify(blockHeightManager).handlePreparePayload(prepare);
verify(qbftGossip).send(prepareMessage);
verify(blockHeightManager).handleCommitPayload(commit);
verify(qbftGossip).send(commitMessage);
verify(blockHeightManager).handleRoundChangePayload(roundChange);
verify(qbftGossip).send(roundChangeMessage);
}
use of org.hyperledger.besu.consensus.common.bft.events.NewChainHead in project besu by hyperledger.
the class ValidatorContractTest method createNewBlockAsProposer.
private void createNewBlockAsProposer(final TestContext context, final long blockNumber) {
ConsensusRoundIdentifier roundId = new ConsensusRoundIdentifier(blockNumber, 0);
// trigger proposal
context.getController().handleBlockTimerExpiry(new BlockTimerExpiry(roundId));
// peers commit proposed block
Block proposedBlock = context.createBlockForProposalFromChainHead(clock.instant().getEpochSecond());
RoundSpecificPeers peers = context.roundSpecificPeers(roundId);
peers.commitForNonProposing(roundId, proposedBlock);
assertThat(context.getCurrentChainHeight()).isEqualTo(blockNumber);
context.getController().handleNewBlockEvent(new NewChainHead(context.getBlockchain().getChainHeadHeader()));
}
use of org.hyperledger.besu.consensus.common.bft.events.NewChainHead in project besu by hyperledger.
the class ValidatorContractTest method remotePeerProposesNewBlock.
private void remotePeerProposesNewBlock(final TestContext context, final long blockNumber) {
ConsensusRoundIdentifier roundId = new ConsensusRoundIdentifier(blockNumber, 0);
RoundSpecificPeers peers = context.roundSpecificPeers(roundId);
ValidatorPeer remoteProposer = peers.getProposer();
final Block blockToPropose = context.createBlockForProposalFromChainHead(clock.instant().getEpochSecond(), remoteProposer.getNodeAddress());
remoteProposer.injectProposal(roundId, blockToPropose);
remoteProposer.injectCommit(roundId, blockToPropose);
assertThat(context.getCurrentChainHeight()).isEqualTo(blockNumber);
context.getController().handleNewBlockEvent(new NewChainHead(context.getBlockchain().getChainHeadHeader()));
}
use of org.hyperledger.besu.consensus.common.bft.events.NewChainHead in project besu by hyperledger.
the class FutureHeightTest method multipleNewChainHeadEventsDoesNotRestartCurrentHeightManager.
@Test
public void multipleNewChainHeadEventsDoesNotRestartCurrentHeightManager() {
final Block currentHeightBlock = context.createBlockForProposalFromChainHead(30, peers.getProposer().getNodeAddress());
peers.getProposer().injectProposal(roundId, currentHeightBlock);
peers.getProposer().injectPrepare(roundId, currentHeightBlock.getHash());
peers.getNonProposing(0).injectPrepare(roundId, currentHeightBlock.getHash());
peers.clearReceivedMessages();
context.getController().handleNewBlockEvent(new NewChainHead(context.getBlockchain().getChainHeadHeader()));
// Should only require 1 more prepare to close it out
peers.getNonProposing(1).injectPrepare(roundId, currentHeightBlock.getHash());
final Commit expectedCommitMessage = new Commit(createSignedCommitPayload(roundId, currentHeightBlock, context.getLocalNodeParams().getNodeKey()));
peers.verifyMessagesReceived(expectedCommitMessage);
}
use of org.hyperledger.besu.consensus.common.bft.events.NewChainHead in project besu by hyperledger.
the class FutureHeightTest method correctMessagesAreExtractedFromFutureHeightBuffer.
@Test
public void correctMessagesAreExtractedFromFutureHeightBuffer() {
final Block currentHeightBlock = context.createBlockForProposalFromChainHead(30);
final Block signedCurrentHeightBlock = BftHelpers.createSealedBlock(bftExtraDataCodec, currentHeightBlock, 0, peers.sign(currentHeightBlock.getHash()));
final Block nextHeightBlock = context.createBlockForProposal(signedCurrentHeightBlock.getHeader(), 60, peers.getProposer().getNodeAddress());
final Block signedNextHeightBlock = BftHelpers.createSealedBlock(bftExtraDataCodec, nextHeightBlock, 0, peers.sign(nextHeightBlock.getHash()));
final Block futureHeightBlock = context.createBlockForProposal(signedNextHeightBlock.getHeader(), 90, peers.getNonProposing(0).getNodeAddress());
final ConsensusRoundIdentifier nextHeightRoundId = new ConsensusRoundIdentifier(2, 0);
final ConsensusRoundIdentifier futureHeightRoundId = new ConsensusRoundIdentifier(3, 0);
// Inject prepares and commits from all peers into FutureHeight (2 height time)
peers.prepareForNonProposing(futureHeightRoundId, futureHeightBlock.getHash());
peers.commitForNonProposing(futureHeightRoundId, futureHeightBlock);
// Add the "interim" block to chain, and notify system of its arrival.
context.getBlockchain().appendBlock(signedCurrentHeightBlock, emptyList());
assertThat(context.getCurrentChainHeight()).isEqualTo(1);
context.getController().handleNewBlockEvent(new NewChainHead(signedCurrentHeightBlock.getHeader()));
peers.verifyNoMessagesReceived();
peers.getProposer().injectProposal(nextHeightRoundId, nextHeightBlock);
final Prepare expectedPrepareMessage = localNodeMessageFactory.createPrepare(nextHeightRoundId, nextHeightBlock.getHash());
// Assert ONLY a prepare message was received, not any commits (i.e. futureHeightRoundId
// messages have not been used.
peers.verifyMessagesReceived(expectedPrepareMessage);
// Future height proposal needs to come from the NEXT nonProposer.
peers.getNonProposing(0).injectProposal(futureHeightRoundId, futureHeightBlock);
// Change to the FutureRound, and confirm prepare and commit msgs are sent
context.getBlockchain().appendBlock(signedNextHeightBlock, emptyList());
assertThat(context.getCurrentChainHeight()).isEqualTo(2);
context.getController().handleNewBlockEvent(new NewChainHead(signedNextHeightBlock.getHeader()));
final Prepare expectedFuturePrepareMessage = localNodeMessageFactory.createPrepare(futureHeightRoundId, futureHeightBlock.getHash());
final Commit expectedCommitMessage = new Commit(createSignedCommitPayload(futureHeightRoundId, futureHeightBlock, context.getLocalNodeParams().getNodeKey()));
// Assert ONLY a prepare message was received, not any commits (i.e. futureHeightRoundId
// messages have not been used.
peers.verifyMessagesReceived(expectedCommitMessage, expectedFuturePrepareMessage);
}
Aggregations