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

Commit

Permalink
Ibft Consensus Round Classes (#405)
Browse files Browse the repository at this point in the history
The IbftRound is responsible for sequencing the transmission of
network packets based on received data.
  • Loading branch information
rain-on authored Dec 13, 2018
1 parent 24aac90 commit f99457b
Show file tree
Hide file tree
Showing 10 changed files with 679 additions and 26 deletions.
1 change: 1 addition & 0 deletions consensus/ibft/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ dependencies {
implementation 'com.google.guava:guava'

testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')
testImplementation project(path: ':config:', configuration:'testSupportArtifacts')

testImplementation 'junit:junit'
testImplementation 'org.awaitility:awaitility'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import tech.pegasys.pantheon.ethereum.rlp.RLPInput;
import tech.pegasys.pantheon.util.bytes.BytesValue;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

Expand All @@ -34,14 +35,14 @@ public class IbftExtraData {
public static final int EXTRA_VANITY_LENGTH = 32;

private final BytesValue vanityData;
private final List<Signature> seals;
private final Collection<Signature> seals;
private final Optional<Vote> vote;
private final int round;
private final List<Address> validators;

public IbftExtraData(
final BytesValue vanityData,
final List<Signature> seals,
final Collection<Signature> seals,
final Optional<Vote> vote,
final int round,
final List<Address> validators) {
Expand Down Expand Up @@ -127,7 +128,7 @@ public BytesValue getVanityData() {
return vanityData;
}

public List<Signature> getSeals() {
public Collection<Signature> getSeals() {
return seals;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
*/
package tech.pegasys.pantheon.consensus.ibft;

import tech.pegasys.pantheon.crypto.SECP256K1.Signature;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.BlockHeaderBuilder;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.core.Util;

import java.util.Collection;

public class IbftHelpers {

public static final Hash EXPECTED_MIX_HASH =
Expand All @@ -23,4 +29,26 @@ public class IbftHelpers {
public static int calculateRequiredValidatorQuorum(final int validatorCount) {
return Util.fastDivCeiling(2 * validatorCount, 3);
}

public static Block createSealedBlock(
final Block block, final Collection<Signature> commitSeals) {
final BlockHeader initialHeader = block.getHeader();
final IbftExtraData initialExtraData = IbftExtraData.decode(initialHeader.getExtraData());

final IbftExtraData sealedExtraData =
new IbftExtraData(
initialExtraData.getVanityData(),
commitSeals,
initialExtraData.getVote(),
initialExtraData.getRound(),
initialExtraData.getValidators());

final BlockHeader sealedHeader =
BlockHeaderBuilder.fromHeader(initialHeader)
.extraData(sealedExtraData.encode())
.blockHashFunction(IbftBlockHashing::calculateHashOfIbftBlockOnChain)
.buildBlockHeader();

return new Block(sealedHeader, block.getBody());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class IbftFinalState {
private final IbftBlockCreatorFactory blockCreatorFactory;
private final MessageFactory messageFactory;
private final BlockHeaderValidator<IbftContext> ibftContextBlockHeaderValidator;
private final IbftMessageTransmitter messageTransmitter;

public IbftFinalState(
final ValidatorProvider validatorProvider,
Expand All @@ -63,6 +64,7 @@ public IbftFinalState(
this.blockCreatorFactory = blockCreatorFactory;
this.messageFactory = messageFactory;
this.ibftContextBlockHeaderValidator = ibftContextBlockHeaderValidator;
this.messageTransmitter = new IbftMessageTransmitter(messageFactory, peers);
}

public int getQuorumSize() {
Expand Down Expand Up @@ -116,4 +118,8 @@ public Address getProposerForRound(final ConsensusRoundIdentifier roundIdentifie
public BlockHeaderValidator<IbftContext> getBlockHeaderValidator() {
return ibftContextBlockHeaderValidator;
}

public IbftMessageTransmitter getTransmitter() {
return messageTransmitter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2018 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.consensus.ibft.statemachine;

import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;
import tech.pegasys.pantheon.consensus.ibft.ibftmessage.CommitMessage;
import tech.pegasys.pantheon.consensus.ibft.ibftmessage.NewRoundMessage;
import tech.pegasys.pantheon.consensus.ibft.ibftmessage.PrepareMessage;
import tech.pegasys.pantheon.consensus.ibft.ibftmessage.ProposalMessage;
import tech.pegasys.pantheon.consensus.ibft.ibftmessage.RoundChangeMessage;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.CommitPayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.MessageFactory;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.NewRoundPayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.PreparePayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.PreparedCertificate;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.ProposalPayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.RoundChangeCertificate;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.RoundChangePayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.SignedData;
import tech.pegasys.pantheon.consensus.ibft.network.IbftNetworkPeers;
import tech.pegasys.pantheon.crypto.SECP256K1.Signature;
import tech.pegasys.pantheon.ethereum.core.Block;
import tech.pegasys.pantheon.ethereum.core.Hash;

import java.util.Optional;

public class IbftMessageTransmitter {

private final MessageFactory messageFactory;
private final IbftNetworkPeers networkPeers;

public IbftMessageTransmitter(
final MessageFactory messageFactory, final IbftNetworkPeers networkPeers) {
this.messageFactory = messageFactory;
this.networkPeers = networkPeers;
}

public void multicastProposal(final ConsensusRoundIdentifier roundIdentifier, final Block block) {
final SignedData<ProposalPayload> signedPayload =
messageFactory.createSignedProposalPayload(roundIdentifier, block);

final ProposalMessage message = ProposalMessage.create(signedPayload);

networkPeers.multicastToValidators(message);
}

public void multicastPrepare(final ConsensusRoundIdentifier roundIdentifier, final Hash digest) {
final SignedData<PreparePayload> signedPayload =
messageFactory.createSignedPreparePayload(roundIdentifier, digest);

final PrepareMessage message = PrepareMessage.create(signedPayload);

networkPeers.multicastToValidators(message);
}

public void multicastCommit(
final ConsensusRoundIdentifier roundIdentifier,
final Hash digest,
final Signature commitSeal) {
final SignedData<CommitPayload> signedPayload =
messageFactory.createSignedCommitPayload(roundIdentifier, digest, commitSeal);

final CommitMessage message = CommitMessage.create(signedPayload);

networkPeers.multicastToValidators(message);
}

public void multicastRoundChange(
final ConsensusRoundIdentifier roundIdentifier,
final Optional<PreparedCertificate> preparedCertificate) {

final SignedData<RoundChangePayload> signedPayload =
messageFactory.createSignedRoundChangePayload(roundIdentifier, preparedCertificate);

final RoundChangeMessage message = RoundChangeMessage.create(signedPayload);

networkPeers.multicastToValidators(message);
}

public void multicastNewRound(
final ConsensusRoundIdentifier roundIdentifier,
final RoundChangeCertificate roundChangeCertificate,
final SignedData<ProposalPayload> proposalPayload) {

final SignedData<NewRoundPayload> signedPayload =
messageFactory.createSignedNewRoundPayload(
roundIdentifier, roundChangeCertificate, proposalPayload);

final NewRoundMessage message = NewRoundMessage.create(signedPayload);

networkPeers.multicastToValidators(message);
}
}
Loading

0 comments on commit f99457b

Please sign in to comment.