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

Commit

Permalink
IBFT 2.1 Message rework, piggybacking blocks on msgs. (#769)
Browse files Browse the repository at this point in the history
This change moves blocks out from the signed portion of the IBFT messages (Proposal, RoundChange and NewRound).

This has grossly affected the message validators and message factories - but otherwise does not affect the general behaviour of the system (other than reducing message size of the NewRound messages).
  • Loading branch information
rain-on authored Feb 8, 2019
1 parent 6015643 commit c044749
Show file tree
Hide file tree
Showing 37 changed files with 911 additions and 367 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ public NewRound injectNewRound(
final Proposal proposal) {

final NewRound payload =
messageFactory.createNewRound(rId, roundChangeCertificate, proposal.getSignedPayload());
messageFactory.createNewRound(
rId, roundChangeCertificate, proposal.getSignedPayload(), proposal.getBlock());
injectMessage(NewRoundMessageData.create(payload));
return payload;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void messagesForFutureRoundAreNotActionedUntilRoundIsActive() {
// required remotely received Prepares = quorum-2
// required remote received commits = quorum-1

// Inject 1 too few Commit messages (but sufficient Prepare
// Inject 1 too few Commit messages (but sufficient Prepare)
for (int i = 0; i < quorum - 3; i++) {
futurePeers.getNonProposing(i).injectPrepare(futureRoundId, futureBlock.getHash());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ public void messageWithUnknownValidatorIsNotGossiped() {
final MessageFactory unknownMsgFactory = new MessageFactory(unknownKeyPair);
final Proposal unknownProposal = unknownMsgFactory.createProposal(roundId, block);

sender.injectMessage(
ProposalMessageData.create(new Proposal(unknownProposal.getSignedPayload())));
sender.injectMessage(ProposalMessageData.create(unknownProposal));
peers.verifyNoMessagesReceived();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ public void whenSufficientRoundChangeMessagesAreReceivedForNewRoundLocalNodeCrea
rc4.getSignedPayload())),
localNodeMessageFactory
.createProposal(targetRound, locallyProposedBlock)
.getSignedPayload());
.getSignedPayload(),
locallyProposedBlock);

peers.verifyMessagesReceived(expectedNewRound);
}
Expand Down Expand Up @@ -214,7 +215,8 @@ public void newRoundMessageContainsBlockOnWhichPeerPrepared() {
rc4.getSignedPayload())),
localNodeMessageFactory
.createProposal(targetRound, expectedBlockToPropose)
.getSignedPayload());
.getSignedPayload(),
expectedBlockToPropose);

peers.verifyMessagesReceived(expectedNewRound);
}
Expand All @@ -238,7 +240,8 @@ public void cannotRoundChangeToAnEarlierRound() {
new RoundChangeCertificate(roundChangeMessages),
localNodeMessageFactory
.createProposal(futureRound, locallyProposedBlock)
.getSignedPayload());
.getSignedPayload(),
locallyProposedBlock);

peers.verifyMessagesReceived(expectedNewRound);
}
Expand Down Expand Up @@ -292,7 +295,8 @@ public void subsequentRoundChangeMessagesFromPeerDoNotOverwritePriorMessage() {
new RoundChangeCertificate(Lists.newArrayList(roundChangeMessages)),
localNodeMessageFactory
.createProposal(targetRound, expectedBlockToPropose)
.getSignedPayload());
.getSignedPayload(),
expectedBlockToPropose);

peers.verifyMessagesReceived(expectedNewRound);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package tech.pegasys.pantheon.consensus.ibft.messagewrappers;

import tech.pegasys.pantheon.consensus.ibft.IbftBlockHashing;
import tech.pegasys.pantheon.consensus.ibft.payload.NewRoundPayload;
import tech.pegasys.pantheon.consensus.ibft.payload.ProposalPayload;
import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate;
Expand All @@ -24,8 +25,11 @@

public class NewRound extends IbftMessage<NewRoundPayload> {

public NewRound(final SignedData<NewRoundPayload> payload) {
private final Block proposedBlock;

public NewRound(final SignedData<NewRoundPayload> payload, final Block proposedBlock) {
super(payload);
this.proposedBlock = proposedBlock;
}

public RoundChangeCertificate getRoundChangeCertificate() {
Expand All @@ -37,14 +41,15 @@ public SignedData<ProposalPayload> getProposalPayload() {
}

public Block getBlock() {
return getProposalPayload().getPayload().getBlock();
return proposedBlock;
}

@Override
public BytesValue encode() {
final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput();
rlpOut.startList();
getSignedPayload().writeTo(rlpOut);
proposedBlock.writeTo(rlpOut);
rlpOut.endList();
return rlpOut.encoded();
}
Expand All @@ -53,7 +58,9 @@ public static NewRound decode(final BytesValue data) {
RLPInput rlpIn = RLP.input(data);
rlpIn.enterList();
final SignedData<NewRoundPayload> payload = SignedData.readSignedNewRoundPayloadFrom(rlpIn);
final Block proposedBlock =
Block.readFrom(rlpIn, IbftBlockHashing::calculateDataHashForCommittedSeal);
rlpIn.leaveList();
return new NewRound(payload);
return new NewRound(payload, proposedBlock);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,39 @@
*/
package tech.pegasys.pantheon.consensus.ibft.messagewrappers;

import tech.pegasys.pantheon.consensus.ibft.IbftBlockHashing;
import tech.pegasys.pantheon.consensus.ibft.payload.ProposalPayload;
import tech.pegasys.pantheon.consensus.ibft.payload.SignedData;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPOutput;
import tech.pegasys.pantheon.ethereum.rlp.RLP;
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
import tech.pegasys.pantheon.util.bytes.BytesValue;

public class Proposal extends IbftMessage<ProposalPayload> {

public Proposal(final SignedData<ProposalPayload> payload) {
private final Block proposedBlock;

public Proposal(final SignedData<ProposalPayload> payload, final Block proposedBlock) {
super(payload);
this.proposedBlock = proposedBlock;
}

public Block getBlock() {
return getPayload().getBlock();
return proposedBlock;
}

public Hash getDigest() {
return getPayload().getDigest();
}

@Override
public BytesValue encode() {
final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput();
rlpOut.startList();
getSignedPayload().writeTo(rlpOut);
proposedBlock.writeTo(rlpOut);
rlpOut.endList();
return rlpOut.encoded();
}
Expand All @@ -43,7 +53,9 @@ public static Proposal decode(final BytesValue data) {
RLPInput rlpIn = RLP.input(data);
rlpIn.enterList();
final SignedData<ProposalPayload> payload = SignedData.readSignedProposalPayloadFrom(rlpIn);
final Block proposedBlock =
Block.readFrom(rlpIn, IbftBlockHashing::calculateDataHashForCommittedSeal);
rlpIn.leaveList();
return new Proposal(payload);
return new Proposal(payload, proposedBlock);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
*/
package tech.pegasys.pantheon.consensus.ibft.messagewrappers;

import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;
import tech.pegasys.pantheon.consensus.ibft.IbftBlockHashing;
import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate;
import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangePayload;
import tech.pegasys.pantheon.consensus.ibft.payload.SignedData;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPOutput;
import tech.pegasys.pantheon.ethereum.rlp.RLP;
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
Expand All @@ -24,29 +27,56 @@

public class RoundChange extends IbftMessage<RoundChangePayload> {

public RoundChange(final SignedData<RoundChangePayload> payload) {
private final Optional<Block> proposedBlock;

public RoundChange(
final SignedData<RoundChangePayload> payload, final Optional<Block> proposedBlock) {
super(payload);
this.proposedBlock = proposedBlock;
}

public Optional<Block> getProposedBlock() {
return proposedBlock;
}

public Optional<PreparedCertificate> getPreparedCertificate() {
return getPayload().getPreparedCertificate();
}

public Optional<ConsensusRoundIdentifier> getPreparedCertificateRound() {
return getPreparedCertificate()
.map(prepCert -> prepCert.getProposalPayload().getPayload().getRoundIdentifier());
}

@Override
public BytesValue encode() {
final BytesValueRLPOutput rlpOut = new BytesValueRLPOutput();
rlpOut.startList();
getSignedPayload().writeTo(rlpOut);
if (proposedBlock.isPresent()) {
proposedBlock.get().writeTo(rlpOut);
} else {
rlpOut.writeNull();
}
rlpOut.endList();
return rlpOut.encoded();
}

public static RoundChange decode(final BytesValue data) {
RLPInput rlpIn = RLP.input(data);

final RLPInput rlpIn = RLP.input(data);
rlpIn.enterList();
final SignedData<RoundChangePayload> payload =
SignedData.readSignedRoundChangePayloadFrom(rlpIn);
Optional<Block> block = Optional.empty();
if (!rlpIn.nextIsNull()) {
block =
Optional.of(Block.readFrom(rlpIn, IbftBlockHashing::calculateDataHashForCommittedSeal));
} else {
rlpIn.skipNext();
}
rlpIn.leaveList();
return new RoundChange(payload);

return new RoundChange(payload, block);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ public void multicastRoundChange(
public void multicastNewRound(
final ConsensusRoundIdentifier roundIdentifier,
final RoundChangeCertificate roundChangeCertificate,
final SignedData<ProposalPayload> proposalPayload) {
final SignedData<ProposalPayload> proposalPayload,
final Block block) {

final NewRound signedPayload =
messageFactory.createNewRound(roundIdentifier, roundChangeCertificate, proposalPayload);
messageFactory.createNewRound(
roundIdentifier, roundChangeCertificate, proposalPayload, block);

final NewRoundMessageData message = NewRoundMessageData.create(signedPayload);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ public MessageFactory(final KeyPair validatorKeyPair) {
public Proposal createProposal(
final ConsensusRoundIdentifier roundIdentifier, final Block block) {

final ProposalPayload payload = new ProposalPayload(roundIdentifier, block);
final ProposalPayload payload = new ProposalPayload(roundIdentifier, block.getHash());

return new Proposal(createSignedMessage(payload));
return new Proposal(createSignedMessage(payload), block);
}

public Prepare createPrepare(final ConsensusRoundIdentifier roundIdentifier, final Hash digest) {
Expand Down Expand Up @@ -70,19 +70,20 @@ public RoundChange createRoundChange(
new RoundChangePayload(
roundIdentifier,
preparedRoundArtifacts.map(PreparedRoundArtifacts::getPreparedCertificate));

return new RoundChange(createSignedMessage(payload));
return new RoundChange(
createSignedMessage(payload), preparedRoundArtifacts.map(PreparedRoundArtifacts::getBlock));
}

public NewRound createNewRound(
final ConsensusRoundIdentifier roundIdentifier,
final RoundChangeCertificate roundChangeCertificate,
final SignedData<ProposalPayload> proposalPayload) {
final SignedData<ProposalPayload> proposalPayload,
final Block block) {

final NewRoundPayload payload =
new NewRoundPayload(roundIdentifier, roundChangeCertificate, proposalPayload);

return new NewRound(createSignedMessage(payload));
return new NewRound(createSignedMessage(payload), block);
}

private <M extends Payload> SignedData<M> createSignedMessage(final M payload) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
package tech.pegasys.pantheon.consensus.ibft.payload;

import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;
import tech.pegasys.pantheon.consensus.ibft.IbftBlockHashing;
import tech.pegasys.pantheon.consensus.ibft.messagedata.IbftV2;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;

Expand All @@ -25,33 +24,32 @@
public class ProposalPayload implements Payload {
private static final int TYPE = IbftV2.PROPOSAL;
private final ConsensusRoundIdentifier roundIdentifier;
private final Block block;
private final Hash digest;

public ProposalPayload(final ConsensusRoundIdentifier roundIdentifier, final Block block) {
public ProposalPayload(final ConsensusRoundIdentifier roundIdentifier, final Hash digest) {
this.roundIdentifier = roundIdentifier;
this.block = block;
this.digest = digest;
}

public static ProposalPayload readFrom(final RLPInput rlpInput) {
rlpInput.enterList();
final ConsensusRoundIdentifier roundIdentifier = ConsensusRoundIdentifier.readFrom(rlpInput);
final Block block =
Block.readFrom(rlpInput, IbftBlockHashing::calculateDataHashForCommittedSeal);
final Hash digest = Hash.wrap(rlpInput.readBytes32());
rlpInput.leaveList();

return new ProposalPayload(roundIdentifier, block);
return new ProposalPayload(roundIdentifier, digest);
}

@Override
public void writeTo(final RLPOutput rlpOutput) {
rlpOutput.startList();
roundIdentifier.writeTo(rlpOutput);
block.writeTo(rlpOutput);
rlpOutput.writeBytesValue(digest);
rlpOutput.endList();
}

public Block getBlock() {
return block;
public Hash getDigest() {
return digest;
}

@Override
Expand All @@ -74,19 +72,19 @@ public boolean equals(final Object o) {
}
final ProposalPayload that = (ProposalPayload) o;
return Objects.equals(roundIdentifier, that.roundIdentifier)
&& Objects.equals(block, that.block);
&& Objects.equals(digest, that.digest);
}

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

@Override
public String toString() {
return new StringJoiner(", ", ProposalPayload.class.getSimpleName() + "[", "]")
.add("roundIdentifier=" + roundIdentifier)
.add("block=" + block)
.add("digest=" + digest)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ public void startRoundWith(
transmitter.multicastNewRound(
getRoundIdentifier(),
roundChangeArtifacts.getRoundChangeCertificate(),
proposal.getSignedPayload());
proposal.getSignedPayload(),
proposal.getBlock());
updateStateWithProposedBlock(proposal);
}

Expand Down Expand Up @@ -140,7 +141,7 @@ public void handleProposalFromNewRound(final NewRound msg) {
LOG.error("Illegally received a NewRound message when in Round 0.");
return;
}
actionReceivedProposal(new Proposal(msg.getProposalPayload()));
actionReceivedProposal(new Proposal(msg.getProposalPayload(), msg.getBlock()));
}

private void actionReceivedProposal(final Proposal msg) {
Expand Down
Loading

0 comments on commit c044749

Please sign in to comment.