Ibft Round to update internal state on reception of NewRound Message (#451)

tmohay 6 years ago committed by GitHub
parent cae7c9011b
commit 6375caf389
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRound.java
  2. 47
      consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRoundTest.java

@ -94,19 +94,19 @@ public class IbftRound {
final RoundChangeCertificate roundChangeCertificate, final long headerTimestamp) { final RoundChangeCertificate roundChangeCertificate, final long headerTimestamp) {
final Optional<PreparedCertificate> latestCertificate = final Optional<PreparedCertificate> latestCertificate =
findLatestPreparedCertificate(roundChangeCertificate.getRoundChangePayloads()); findLatestPreparedCertificate(roundChangeCertificate.getRoundChangePayloads());
SignedData<ProposalPayload> proposal;
if (!latestCertificate.isPresent()) { if (!latestCertificate.isPresent()) {
LOG.info("Multicasting NewRound with new block.");
final Block block = blockCreator.createBlock(headerTimestamp); final Block block = blockCreator.createBlock(headerTimestamp);
transmitter.multicastNewRound( proposal = messageFactory.createSignedProposalPayload(getRoundIdentifier(), block);
getRoundIdentifier(),
roundChangeCertificate,
messageFactory.createSignedProposalPayload(getRoundIdentifier(), block));
} else { } else {
final SignedData<ProposalPayload> proposal = LOG.info("Multicasting NewRound from PreparedCertificate.");
createProposalFromPreparedCertificate(latestCertificate.get()); proposal = createProposalFromPreparedCertificate(latestCertificate.get());
}
transmitter.multicastNewRound(getRoundIdentifier(), roundChangeCertificate, proposal); transmitter.multicastNewRound(getRoundIdentifier(), roundChangeCertificate, proposal);
updateStateWithProposedBlock(proposal); updateStateWithProposedBlock(proposal);
} }
}
private SignedData<ProposalPayload> createProposalFromPreparedCertificate( private SignedData<ProposalPayload> createProposalFromPreparedCertificate(
final PreparedCertificate preparedCertificate) { final PreparedCertificate preparedCertificate) {
@ -134,7 +134,7 @@ public class IbftRound {
} }
public void handleProposalMessage(final SignedData<ProposalPayload> msg) { public void handleProposalMessage(final SignedData<ProposalPayload> msg) {
LOG.info("Received a Proposal message."); LOG.info("Handling a Proposal message.");
final Block block = msg.getPayload().getBlock(); final Block block = msg.getPayload().getBlock();
final boolean wasCommitted = roundState.isCommitted(); final boolean wasCommitted = roundState.isCommitted();

@ -84,7 +84,8 @@ public class IbftRoundTest {
private Block proposedBlock; private Block proposedBlock;
private IbftExtraData proposedExtraData; private IbftExtraData proposedExtraData;
final Signature remoteCommitSeal = Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1); private final Signature remoteCommitSeal =
Signature.create(BigInteger.ONE, BigInteger.ONE, (byte) 1);
@Before @Before
public void setup() { public void setup() {
@ -105,11 +106,11 @@ public class IbftRoundTest {
Optional.empty(), Optional.empty(),
0, 0,
Collections.emptyList()); Collections.emptyList());
BlockHeaderTestFixture headerTestFixture = new BlockHeaderTestFixture(); final BlockHeaderTestFixture headerTestFixture = new BlockHeaderTestFixture();
headerTestFixture.extraData(proposedExtraData.encode()); headerTestFixture.extraData(proposedExtraData.encode());
headerTestFixture.number(1); headerTestFixture.number(1);
BlockHeader header = headerTestFixture.buildHeader(); final BlockHeader header = headerTestFixture.buildHeader();
proposedBlock = proposedBlock =
new Block(header, new BlockBody(Collections.emptyList(), Collections.emptyList())); new Block(header, new BlockBody(Collections.emptyList(), Collections.emptyList()));
@ -281,9 +282,6 @@ public class IbftRoundTest {
@Test @Test
public void aNewRoundMessageWithTheSameBlockIsSentUponReceptionOfARoundChangeWithCertificate() { public void aNewRoundMessageWithTheSameBlockIsSentUponReceptionOfARoundChangeWithCertificate() {
SignedData<ProposalPayload> mockedSentMessage =
messageFactory.createSignedProposalPayload(roundIdentifier, proposedBlock);
final ConsensusRoundIdentifier priorRoundChange = new ConsensusRoundIdentifier(1, 0); final ConsensusRoundIdentifier priorRoundChange = new ConsensusRoundIdentifier(1, 0);
final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator); final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator);
final IbftRound round = final IbftRound round =
@ -319,5 +317,42 @@ public class IbftRoundTest {
IbftExtraData.decode( IbftExtraData.decode(
payloadArgCaptor.getValue().getPayload().getBlock().getHeader().getExtraData()); payloadArgCaptor.getValue().getPayload().getBlock().getHeader().getExtraData());
assertThat(proposedExtraData.getRound()).isEqualTo(roundIdentifier.getRoundNumber()); assertThat(proposedExtraData.getRound()).isEqualTo(roundIdentifier.getRoundNumber());
// Inject a single Prepare message, and confirm the roundState has gone to Prepared (which
// indicates the block has entered the roundState (note: all msgs are deemed valid due to mocks)
round.handlePrepareMessage(
messageFactory.createSignedPreparePayload(roundIdentifier, proposedBlock.getHash()));
assertThat(roundState.isPrepared()).isTrue();
}
@Test
public void creatingNewBlockFromEmptyPreparedCertificateUpdatesInternalState() {
final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator);
final IbftRound round =
new IbftRound(
roundState,
blockCreator,
protocolContext,
blockImporter,
subscribers,
localNodeKeys,
messageFactory,
transmitter);
final RoundChangeCertificate roundChangeCertificate =
new RoundChangeCertificate(
Collections.singletonList(
messageFactory.createSignedRoundChangePayload(roundIdentifier, Optional.empty())));
round.startRoundWith(roundChangeCertificate, 15);
verify(transmitter, times(1))
.multicastNewRound(
eq(roundIdentifier), eq(roundChangeCertificate), payloadArgCaptor.capture());
// Inject a single Prepare message, and confirm the roundState has gone to Prepared (which
// indicates the block has entered the roundState (note: all msgs are deemed valid due to mocks)
round.handlePrepareMessage(
messageFactory.createSignedPreparePayload(roundIdentifier, proposedBlock.getHash()));
assertThat(roundState.isPrepared()).isTrue();
} }
} }

Loading…
Cancel
Save