Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Basic Ibft message validators #314

Merged
merged 4 commits into from
Nov 28, 2018
Merged

Conversation

rain-on
Copy link
Contributor

@rain-on rain-on commented Nov 26, 2018

MessageValidator has been added which is responsible for determining the validity of a given prepare or commit message with respect to an existing Preprepare message.

It is also responsible for ensuring a supplied Preprepare message contains valid content, in line with the context of the validation (i.e. current consensus round, block is valid in the context of the existing blockchain etc).

@rain-on rain-on force-pushed the ibft_msg_validation branch from 722131e to 3948d45 Compare November 26, 2018 22:38
return false;
}

if (preprepareMessage.isPresent()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is already being done on line 70

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

this.parentHeader = parentHeader;
}

public boolean addPreprepareMessage(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the validation part of this should be split out into something validation message to be consistent with the validations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done (I think?).

public boolean addPreprepareMessage(
final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> msg) {

if (preprepareMessage.isPresent()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

be nicer to use ifPresent pass through the preprepareMessage value so that handleSubsequentPreprepareMessage doesn't need to do a preprepareMessage.get() call

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't use ifPresent, as we need to be able to return (ifPresent takes a consumer) - however, can pass the value through to prevent the extraneous get().

final IbftSignedMessageData<IbftUnsignedCommitMessageData> msg) {
final String msgType = "Commit";

if (!isMessageInRoundFromValidatorAndMatchesPreprepareDigest(msg, msgType)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think commit is only meant to validate that round number > current round number and not check the sequence number. Not sure if it matters or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting the impression that the commit message's consensusroundID needs to match the associated Preprepare message - so .... take it up with Roberto.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all good as we are discarding old commit messages

}
IbftUnsignedPrePrepareMessageData that = (IbftUnsignedPrePrepareMessageData) o;
return Objects.equals(block, that.block)
&& Objects.equals(roundIdentifier, that.roundIdentifier);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this equals just check the properties this class added and use super.equals for the parts defined in the superclass?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditched this and made a custom equality function (can be dangerous using 'equals' in a heirarchy of classes.

@rain-on rain-on force-pushed the ibft_msg_validation branch 2 times, most recently from 424f5d9 to d390eb4 Compare November 28, 2018 00:10
Copy link
Contributor

@saltiniroberto saltiniroberto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except for few minor comments

return validateDigestMatchesPreprepareBlock(msg.getUnsignedMessageData().getDigest(), msgType);
}

private boolean isMessageInRoundFromValidatorAndMatchesPreprepareDigest(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name does look correct. The method does not perform any verification on the digest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed - updated.

final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> existingMsg,
final IbftSignedMessageData<IbftUnsignedPrePrepareMessageData> newMsg) {
if (!existingMsg.getSender().equals(newMsg.getSender())) {
LOG.debug("Received subsequent invalid Preprepare message; sender differs from original.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This log message is printed only if a Pre-prepare message from a validator that is not the proposer is received after receiving a valid Pre-prepare message sent by the expected proposer. If the Pre-prepare message send by the non-proposer is received before the Pre-prepare message sent by the proposer then this log message is not displayed.
This does not appear right to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully, if we receive a Preprepare from a Non-proposer, we will show an error indicating the supplied message was not from the expected proposer - and will thus be discarded.

This check can be removed, and the "not-proposer" check can catch subsequent failures.

}

@Test
public void receivingAPrepareMessageBeforePrePrepareFails() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The names of these tests suggest that if we receive a Prepare or Commit message before we receive a Pre-prepare message then the Prepare/Commit message should be rejected. Perhaps there is a better name for these tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the context, this is the expected behaviour - i.e. this class will state that a Prepare message is invalid if insufficient context exists to validate it.

@rain-on rain-on force-pushed the ibft_msg_validation branch from d390eb4 to d87e677 Compare November 28, 2018 01:38
@rain-on rain-on merged commit a8b52e1 into PegaSysEng:master Nov 28, 2018
@rain-on rain-on deleted the ibft_msg_validation branch January 16, 2019 21:35
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants