diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManager.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManager.java
index 11a1d7a139..a8f7530024 100644
--- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManager.java
+++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManager.java
@@ -18,7 +18,7 @@ import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.RoundChangeCertifica
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.RoundChangePayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.SignedData;
import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator;
-import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorFactory;
+import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorForHeightFactory;
import tech.pegasys.pantheon.ethereum.core.Address;
import java.util.Collection;
@@ -85,7 +85,7 @@ public class RoundChangeManager {
public RoundChangeManager(
final long sequenceNumber,
final Collection
validators,
- final MessageValidatorFactory messageValidityFactory) {
+ final MessageValidatorForHeightFactory messageValidityFactory) {
this.quorumSize = IbftHelpers.calculateRequiredValidatorQuorum(validators.size());
this.roundChangeMessageValidator =
new RoundChangeMessageValidator(
diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/MessageValidatorFactory.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/MessageValidatorFactory.java
new file mode 100644
index 0000000000..bf30c22ab9
--- /dev/null
+++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/MessageValidatorFactory.java
@@ -0,0 +1,73 @@
+/*
+ * 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.validation;
+
+import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier;
+import tech.pegasys.pantheon.consensus.ibft.IbftContext;
+import tech.pegasys.pantheon.consensus.ibft.IbftHelpers;
+import tech.pegasys.pantheon.consensus.ibft.blockcreation.ProposerSelector;
+import tech.pegasys.pantheon.ethereum.ProtocolContext;
+import tech.pegasys.pantheon.ethereum.core.Address;
+import tech.pegasys.pantheon.ethereum.core.BlockHeader;
+import tech.pegasys.pantheon.ethereum.mainnet.BlockHeaderValidator;
+
+import java.util.Collection;
+
+public class MessageValidatorFactory {
+
+ private final ProposerSelector proposerSelector;
+ private final BlockHeaderValidator blockHeaderValidator;
+ private final ProtocolContext protocolContext;
+
+ public MessageValidatorFactory(
+ final ProposerSelector proposerSelector,
+ final BlockHeaderValidator blockHeaderValidator,
+ final ProtocolContext protocolContext) {
+ this.proposerSelector = proposerSelector;
+ this.blockHeaderValidator = blockHeaderValidator;
+ this.protocolContext = protocolContext;
+ }
+
+ public MessageValidator createMessageValidator(
+ final ConsensusRoundIdentifier roundIdentifier, final BlockHeader parentHeader) {
+ return new MessageValidator(
+ protocolContext.getConsensusState().getVoteTally().getValidators(),
+ proposerSelector.selectProposerForRound(roundIdentifier),
+ roundIdentifier,
+ blockHeaderValidator,
+ protocolContext,
+ parentHeader);
+ }
+
+ public RoundChangeMessageValidator createRoundChangeMessageValidator(
+ final BlockHeader parentHeader) {
+ final Collection validators =
+ protocolContext.getConsensusState().getVoteTally().getValidators();
+ return new RoundChangeMessageValidator(
+ roundIdentifier -> createMessageValidator(roundIdentifier, parentHeader),
+ validators,
+ IbftHelpers.calculateRequiredValidatorQuorum(validators.size()),
+ parentHeader.getNumber() + 1);
+ }
+
+ public NewRoundMessageValidator createNewRoundValidator(final BlockHeader parentHeader) {
+ final Collection validators =
+ protocolContext.getConsensusState().getVoteTally().getValidators();
+ return new NewRoundMessageValidator(
+ validators,
+ proposerSelector,
+ roundIdentifier -> createMessageValidator(roundIdentifier, parentHeader),
+ IbftHelpers.calculateRequiredValidatorQuorum(validators.size()),
+ parentHeader.getNumber() + 1);
+ }
+}
diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidator.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidator.java
index 3635231a74..ff35f2135b 100644
--- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidator.java
+++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidator.java
@@ -20,7 +20,7 @@ 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.validation.RoundChangeMessageValidator.MessageValidatorFactory;
+import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorForHeightFactory;
import tech.pegasys.pantheon.ethereum.core.Address;
import java.util.Collection;
@@ -35,14 +35,14 @@ public class NewRoundMessageValidator {
private final Collection validators;
private final ProposerSelector proposerSelector;
- private final MessageValidatorFactory messageValidatorFactory;
+ private final MessageValidatorForHeightFactory messageValidatorFactory;
private final long quorumSize;
private final long chainHeight;
public NewRoundMessageValidator(
final Collection validators,
final ProposerSelector proposerSelector,
- final MessageValidatorFactory messageValidatorFactory,
+ final MessageValidatorForHeightFactory messageValidatorFactory,
final long quorumSize,
final long chainHeight) {
this.validators = validators;
diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidator.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidator.java
index b6d33a33f2..7c5cbd1dd3 100644
--- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidator.java
+++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidator.java
@@ -29,13 +29,13 @@ public class RoundChangeMessageValidator {
private static final Logger LOG = LogManager.getLogger();
- private final MessageValidatorFactory messageValidatorFactory;
+ private final MessageValidatorForHeightFactory messageValidatorFactory;
private final Collection validators;
private final long minimumPrepareMessages;
private final long chainHeight;
public RoundChangeMessageValidator(
- final MessageValidatorFactory messageValidatorFactory,
+ final MessageValidatorForHeightFactory messageValidatorFactory,
final Collection validators,
final long minimumPrepareMessages,
final long chainHeight) {
@@ -129,8 +129,7 @@ public class RoundChangeMessageValidator {
}
@FunctionalInterface
- public interface MessageValidatorFactory {
-
+ public interface MessageValidatorForHeightFactory {
MessageValidator createAt(final ConsensusRoundIdentifier roundIdentifier);
}
}
diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidatorTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidatorTest.java
index 969e79f9ab..99b3efaf18 100644
--- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidatorTest.java
+++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundMessageValidatorTest.java
@@ -27,7 +27,7 @@ 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.SignedData;
-import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorFactory;
+import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorForHeightFactory;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.Block;
@@ -59,7 +59,8 @@ public class NewRoundMessageValidatorTest {
private final Block proposedBlock = mock(Block.class);
private final ProposerSelector proposerSelector = mock(ProposerSelector.class);
- private final MessageValidatorFactory validatorFactory = mock(MessageValidatorFactory.class);
+ private final MessageValidatorForHeightFactory validatorFactory =
+ mock(MessageValidatorForHeightFactory.class);
private final MessageValidator messageValidator = mock(MessageValidator.class);
private final SignedData validMsg =
diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidatorTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidatorTest.java
index c9503a02ff..968b72ec49 100644
--- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidatorTest.java
+++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeMessageValidatorTest.java
@@ -26,7 +26,7 @@ import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.PreparePayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.PreparedCertificate;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.RoundChangePayload;
import tech.pegasys.pantheon.consensus.ibft.ibftmessagedata.SignedData;
-import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorFactory;
+import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorForHeightFactory;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.Block;
@@ -60,7 +60,8 @@ public class RoundChangeMessageValidatorTest {
private final MessageValidator basicValidator = mock(MessageValidator.class);
private final List validators = Lists.newArrayList();
- private final MessageValidatorFactory validatorFactory = mock(MessageValidatorFactory.class);
+ private final MessageValidatorForHeightFactory validatorFactory =
+ mock(MessageValidatorForHeightFactory.class);
private final RoundChangeMessageValidator validator =
new RoundChangeMessageValidator(validatorFactory, validators, 1, chainHeight);