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

IBFT message payload tests #404

Merged
merged 11 commits into from
Dec 12, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,28 @@
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;

public class CommitPayload extends InRoundPayload {
import java.util.Objects;
import java.util.StringJoiner;

public class CommitPayload implements InRoundPayload {
private static final int TYPE = IbftV2.COMMIT;
private final ConsensusRoundIdentifier roundIdentifier;
private final Hash digest;
private final Signature commitSeal;

public CommitPayload(
final ConsensusRoundIdentifier roundIdentifier,
final Hash digest,
final Signature commitSeal) {
super(roundIdentifier);
this.roundIdentifier = roundIdentifier;
this.digest = digest;
this.commitSeal = commitSeal;
}

public static CommitPayload readFrom(final RLPInput rlpInput) {

rlpInput.enterList();
final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundIdentifier.readFrom(rlpInput);
final Hash digest = readDigest(rlpInput);
final Hash digest = Payload.readDigest(rlpInput);
final Signature commitSeal = rlpInput.readBytesValue(Signature::decode);
rlpInput.leaveList();

Expand All @@ -46,7 +49,6 @@ public static CommitPayload readFrom(final RLPInput rlpInput) {

@Override
public void writeTo(final RLPOutput rlpOutput) {

rlpOutput.startList();
roundIdentifier.writeTo(rlpOutput);
rlpOutput.writeBytesValue(digest);
Expand All @@ -66,4 +68,37 @@ public Hash getDigest() {
public Signature getCommitSeal() {
return commitSeal;
}

@Override
public ConsensusRoundIdentifier getRoundIdentifier() {
return roundIdentifier;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final CommitPayload that = (CommitPayload) o;
Copy link
Contributor

Choose a reason for hiding this comment

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

has missed the RoundIdentifier, needed for the hashCode and toString (and I assume the other classes?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just checked the other classes, looks like this was the unfortunate one that I forgot

return Objects.equals(roundIdentifier, that.roundIdentifier)
&& Objects.equals(digest, that.digest)
&& Objects.equals(commitSeal, that.commitSeal);
}

@Override
public int hashCode() {
return Objects.hash(roundIdentifier, digest, commitSeal);
}

@Override
public String toString() {
Copy link
Contributor

Choose a reason for hiding this comment

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

what about the roundIdentifier stored in the baseclass?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's stored in the this class now as using an interface. But yes I forgot that.
Fixed.

return new StringJoiner(", ", CommitPayload.class.getSimpleName() + "[", "]")
.add("roundIdentifier=" + roundIdentifier)
.add("digest=" + digest)
.add("commitSeal=" + commitSeal)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,6 @@

import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;

import java.util.Objects;

public abstract class InRoundPayload extends AbstractPayload {
protected final ConsensusRoundIdentifier roundIdentifier;

protected InRoundPayload(final ConsensusRoundIdentifier roundIdentifier) {
this.roundIdentifier = roundIdentifier;
}

public ConsensusRoundIdentifier getRoundIdentifier() {
return roundIdentifier;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final InRoundPayload that = (InRoundPayload) o;
return Objects.equals(roundIdentifier, that.roundIdentifier);
}

@Override
public int hashCode() {
return Objects.hash(roundIdentifier);
}
public interface InRoundPayload extends Payload {
ConsensusRoundIdentifier getRoundIdentifier();
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,21 @@ public SignedData<NewRoundPayload> createSignedNewRoundPayload(
return createSignedMessage(payload);
}

private <M extends AbstractPayload> SignedData<M> createSignedMessage(final M payload) {
private <M extends Payload> SignedData<M> createSignedMessage(final M payload) {
final Signature signature = sign(payload, validatorKeyPair);

return new SignedData<>(
payload, Util.publicKeyToAddress(validatorKeyPair.getPublicKey()), signature);
}

public static Hash hashForSignature(final AbstractPayload unsignedMessageData) {
public static Hash hashForSignature(final Payload unsignedMessageData) {
return Hash.hash(
BytesValues.concatenate(
BytesValues.ofUnsignedByte(unsignedMessageData.getMessageType()),
unsignedMessageData.encoded()));
}

private static Signature sign(final AbstractPayload unsignedMessageData, final KeyPair nodeKeys) {
private static Signature sign(final Payload unsignedMessageData, final KeyPair nodeKeys) {
return SECP256K1.sign(hashForSignature(unsignedMessageData), nodeKeys);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;

import java.util.Collections;
import java.util.Objects;
import java.util.StringJoiner;

public class NewRoundPayload extends AbstractPayload {

public class NewRoundPayload implements Payload {
private static final int TYPE = IbftV2.NEW_ROUND;

private final ConsensusRoundIdentifier roundChangeIdentifier;

private final RoundChangeCertificate roundChangeCertificate;

private final SignedData<ProposalPayload> proposalPayload;

public NewRoundPayload(
Expand Down Expand Up @@ -72,6 +70,34 @@ public static NewRoundPayload readFrom(final RLPInput rlpInput) {
return new NewRoundPayload(roundIdentifier, roundChangeCertificate, proposalPayload);
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final NewRoundPayload that = (NewRoundPayload) o;
return Objects.equals(roundChangeIdentifier, that.roundChangeIdentifier)
&& Objects.equals(roundChangeCertificate, that.roundChangeCertificate)
&& Objects.equals(proposalPayload, that.proposalPayload);
}

@Override
public int hashCode() {
return Objects.hash(roundChangeIdentifier, roundChangeCertificate, proposalPayload);
}

@Override
public String toString() {
return new StringJoiner(", ", NewRoundPayload.class.getSimpleName() + "[", "]")
.add("roundChangeIdentifier=" + roundChangeIdentifier)
.add("roundChangeCertificate=" + roundChangeCertificate)
.add("proposalPayload=" + proposalPayload)
.toString();
}

@Override
public int getMessageType() {
return TYPE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;
import tech.pegasys.pantheon.util.bytes.BytesValue;

public abstract class AbstractPayload {
public interface Payload {

public abstract void writeTo(final RLPOutput rlpOutput);
void writeTo(final RLPOutput rlpOutput);

public BytesValue encoded() {
default BytesValue encoded() {
BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
writeTo(rlpOutput);

return rlpOutput.encoded();
}

public abstract int getMessageType();
int getMessageType();

protected static Hash readDigest(final RLPInput ibftMessageData) {
static Hash readDigest(final RLPInput ibftMessageData) {
return Hash.wrap(ibftMessageData.readBytes32());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,29 @@
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;

public class PreparePayload extends InRoundPayload {
import java.util.Objects;
import java.util.StringJoiner;

public class PreparePayload implements InRoundPayload {
private static final int TYPE = IbftV2.PREPARE;
private final ConsensusRoundIdentifier roundIdentifier;
private final Hash digest;

public PreparePayload(final ConsensusRoundIdentifier roundIdentifier, final Hash digest) {
super(roundIdentifier);
this.roundIdentifier = roundIdentifier;
this.digest = digest;
}

public static PreparePayload readFrom(final RLPInput rlpInput) {

rlpInput.enterList();
final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundIdentifier.readFrom(rlpInput);
final Hash digest = readDigest(rlpInput);
final Hash digest = Payload.readDigest(rlpInput);
rlpInput.leaveList();

return new PreparePayload(roundIdentifier, digest);
}

@Override
public void writeTo(final RLPOutput rlpOutput) {

rlpOutput.startList();
roundIdentifier.writeTo(rlpOutput);
rlpOutput.writeBytesValue(digest);
Expand All @@ -54,4 +55,35 @@ public int getMessageType() {
public Hash getDigest() {
return digest;
}

@Override
public ConsensusRoundIdentifier getRoundIdentifier() {
return roundIdentifier;
}

@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PreparePayload that = (PreparePayload) o;
return Objects.equals(roundIdentifier, that.roundIdentifier)
&& Objects.equals(digest, that.digest);
}

@Override
public int hashCode() {
return Objects.hash(roundIdentifier, digest);
}

@Override
public String toString() {
return new StringJoiner(", ", PreparePayload.class.getSimpleName() + "[", "]")
.add("roundIdentifier=" + roundIdentifier)
.add("digest=" + digest)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;

import java.util.Collection;
import java.util.Objects;
import java.util.StringJoiner;

public class PreparedCertificate {

private final SignedData<ProposalPayload> proposalPayload;
private final Collection<SignedData<PreparePayload>> preparePayloads;

Expand Down Expand Up @@ -55,4 +56,30 @@ public SignedData<ProposalPayload> getProposalPayload() {
public Collection<SignedData<PreparePayload>> getPreparePayloads() {
return preparePayloads;
}

@Override
public boolean equals(final Object o) {
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure we will ever do equality on these items in the real world code, could custom static functions be written in either test or testsupport.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could but I think it's cleaner from the consumers point of view to be able to rely on equals if needed.

if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PreparedCertificate that = (PreparedCertificate) o;
return Objects.equals(proposalPayload, that.proposalPayload)
&& Objects.equals(preparePayloads, that.preparePayloads);
}

@Override
public int hashCode() {
return Objects.hash(proposalPayload, preparePayloads);
}

@Override
public String toString() {
return new StringJoiner(", ", PreparedCertificate.class.getSimpleName() + "[", "]")
.add("proposalPayload=" + proposalPayload)
.add("preparePayloads=" + preparePayloads)
.toString();
}
}
Loading