Ibft Preprepare to validate round matches block (#329)

tmohay 6 years ago committed by GitHub
parent 9f432ce7ab
commit 22498da50c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/MessageValidator.java
  2. 46
      consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/MessageValidatorTest.java

@ -16,6 +16,7 @@ import static tech.pegasys.pantheon.ethereum.mainnet.HeaderValidationMode.FULL;
import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;
import tech.pegasys.pantheon.consensus.ibft.IbftContext; import tech.pegasys.pantheon.consensus.ibft.IbftContext;
import tech.pegasys.pantheon.consensus.ibft.IbftExtraData;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.AbstractIbftUnsignedInRoundMessageData; import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.AbstractIbftUnsignedInRoundMessageData;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftSignedMessageData; import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftSignedMessageData;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftUnsignedCommitMessageData; import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftUnsignedCommitMessageData;
@ -75,6 +76,10 @@ public class MessageValidator {
return false; return false;
} }
if (!validateBlocKMatchesPrepareMessageRound(msg.getUnsignedMessageData())) {
return false;
}
preprepareMessage = Optional.of(msg); preprepareMessage = Optional.of(msg);
return true; return true;
} }
@ -201,4 +206,16 @@ public class MessageValidator {
return right.getBlock().getHash().equals(left.getBlock().getHash()) return right.getBlock().getHash().equals(left.getBlock().getHash())
&& right.getRoundIdentifier().equals(left.getRoundIdentifier()); && right.getRoundIdentifier().equals(left.getRoundIdentifier());
} }
private boolean validateBlocKMatchesPrepareMessageRound(
final IbftUnsignedPrePrepareMessageData msgData) {
final ConsensusRoundIdentifier msgRound = msgData.getRoundIdentifier();
final IbftExtraData extraData =
IbftExtraData.decode(msgData.getBlock().getHeader().getExtraData());
if (extraData.getRound() != msgRound.getRoundNumber()) {
LOG.info("Invalid Preprepare message, round number in block does not match that in message.");
return false;
}
return true;
}
} }

@ -19,6 +19,7 @@ import static org.mockito.Mockito.when;
import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;
import tech.pegasys.pantheon.consensus.ibft.IbftContext; import tech.pegasys.pantheon.consensus.ibft.IbftContext;
import tech.pegasys.pantheon.consensus.ibft.IbftExtraData;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftMessageFactory; import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftMessageFactory;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftSignedMessageData; import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftSignedMessageData;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftUnsignedCommitMessageData; import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.IbftUnsignedCommitMessageData;
@ -35,8 +36,11 @@ import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.ethereum.core.Util;
import tech.pegasys.pantheon.ethereum.db.WorldStateArchive; import tech.pegasys.pantheon.ethereum.db.WorldStateArchive;
import tech.pegasys.pantheon.ethereum.mainnet.BlockHeaderValidator; import tech.pegasys.pantheon.ethereum.mainnet.BlockHeaderValidator;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.junit.Before; import org.junit.Before;
@ -84,6 +88,21 @@ public class MessageValidatorTest {
parentHeader); parentHeader);
when(block.getHash()).thenReturn(Hash.fromHexStringLenient("1")); when(block.getHash()).thenReturn(Hash.fromHexStringLenient("1"));
when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true);
insertRoundToBlockHeader(0);
}
private void insertRoundToBlockHeader(final int round) {
final IbftExtraData extraData =
new IbftExtraData(
BytesValue.wrap(new byte[32]),
Collections.emptyList(),
Optional.empty(),
round,
validators);
final BlockHeader header = mock(BlockHeader.class);
when(header.getExtraData()).thenReturn(extraData.encode());
when(block.getHeader()).thenReturn(header);
} }
@Test @Test
@ -139,17 +158,12 @@ public class MessageValidatorTest {
@Test @Test
public void receivingPrepareFromNonValidatorFails() { public void receivingPrepareFromNonValidatorFails() {
when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true); when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true);
final Block block = mock(Block.class);
final BlockHeader header = mock(BlockHeader.class);
when(header.getHash()).thenReturn(Hash.fromHexStringLenient("1")); // arbitrary hash value.
when(block.getHeader()).thenReturn(header);
final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg = final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg =
proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block); proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block);
final IbftSignedMessageData<IbftUnsignedPrepareMessageData> prepareMsg = final IbftSignedMessageData<IbftUnsignedPrepareMessageData> prepareMsg =
nonValidatorMessageFactory.createIbftSignedPrepareMessageData( nonValidatorMessageFactory.createIbftSignedPrepareMessageData(
roundIdentifier, header.getHash()); roundIdentifier, block.getHash());
assertThat(validator.addPreprepareMessage(preprepareMsg)).isTrue(); assertThat(validator.addPreprepareMessage(preprepareMsg)).isTrue();
assertThat(validator.validatePrepareMessage(prepareMsg)).isFalse(); assertThat(validator.validatePrepareMessage(prepareMsg)).isFalse();
@ -180,18 +194,12 @@ public class MessageValidatorTest {
@Test @Test
public void receivingPrepareNonProposerValidatorWithCorrectRoundIsSuccessful() { public void receivingPrepareNonProposerValidatorWithCorrectRoundIsSuccessful() {
when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true); when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true);
final Block block = mock(Block.class);
final BlockHeader header = mock(BlockHeader.class);
final Hash blockHash = Hash.fromHexStringLenient("1");
when(header.getHash()).thenReturn(blockHash); // arbitrary hash value.
when(block.getHeader()).thenReturn(header);
when(block.getHash()).thenReturn(blockHash);
final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg = final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg =
proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block); proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block);
final IbftSignedMessageData<IbftUnsignedPrepareMessageData> prepareMsg = final IbftSignedMessageData<IbftUnsignedPrepareMessageData> prepareMsg =
validatorMessageFactory.createIbftSignedPrepareMessageData( validatorMessageFactory.createIbftSignedPrepareMessageData(
roundIdentifier, header.getHash()); roundIdentifier, block.getHash());
assertThat(validator.addPreprepareMessage(preprepareMsg)).isTrue(); assertThat(validator.addPreprepareMessage(preprepareMsg)).isTrue();
assertThat(validator.validatePrepareMessage(prepareMsg)).isTrue(); assertThat(validator.validatePrepareMessage(prepareMsg)).isTrue();
@ -247,7 +255,6 @@ public class MessageValidatorTest {
@Test @Test
public void subsequentPreprepareHasDifferentContentFails() { public void subsequentPreprepareHasDifferentContentFails() {
when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true);
final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg = final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg =
proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block); proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block);
@ -271,4 +278,15 @@ public class MessageValidatorTest {
proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block); proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block);
assertThat(validator.addPreprepareMessage(secondPreprepareMsg)).isTrue(); assertThat(validator.addPreprepareMessage(secondPreprepareMsg)).isTrue();
} }
@Test
public void blockRoundMisMatchWithMessageRoundFails() {
insertRoundToBlockHeader(roundIdentifier.getRoundNumber() + 1);
when(headerValidator.validateHeader(any(), any(), any(), any())).thenReturn(true);
final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> preprepareMsg =
proposerMessageFactory.createIbftSignedPrePrepareMessageData(roundIdentifier, block);
assertThat(validator.addPreprepareMessage(preprepareMsg)).isFalse();
}
} }

Loading…
Cancel
Save