diff --git a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/RoundSpecificPeers.java b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/RoundSpecificPeers.java index de4eb80e3d..62b3be958d 100644 --- a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/RoundSpecificPeers.java +++ b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/RoundSpecificPeers.java @@ -27,9 +27,9 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.IbftMessage; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.payload.Payload; import tech.pegasys.pantheon.consensus.ibft.payload.PreparePayload; -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.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.ethereum.p2p.api.MessageData; @@ -113,13 +113,14 @@ public class RoundSpecificPeers { } public List> createSignedRoundChangePayload( - final ConsensusRoundIdentifier roundId, final PreparedCertificate preparedCertificate) { + final ConsensusRoundIdentifier roundId, + final TerminatedRoundArtefacts terminatedRoundArtefacts) { return peers .stream() .map( p -> p.getMessageFactory() - .createSignedRoundChangePayload(roundId, Optional.of(preparedCertificate)) + .createSignedRoundChangePayload(roundId, Optional.of(terminatedRoundArtefacts)) .getSignedPayload()) .collect(Collectors.toList()); } diff --git a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestHelpers.java b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestHelpers.java index cb70099d23..d4fccc23f8 100644 --- a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestHelpers.java +++ b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestHelpers.java @@ -16,19 +16,21 @@ import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; import tech.pegasys.pantheon.consensus.ibft.IbftBlockHashing; import tech.pegasys.pantheon.consensus.ibft.IbftExtraData; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.NewRound; +import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.payload.CommitPayload; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangePayload; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.crypto.SECP256K1; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Block; import java.util.List; +import java.util.stream.Collectors; public class TestHelpers { @@ -49,17 +51,17 @@ public class TestHelpers { .getSignedPayload(); } - public static PreparedCertificate createValidPreparedCertificate( + public static TerminatedRoundArtefacts createValidTerminatedRoundArtefacts( final TestContext context, final ConsensusRoundIdentifier preparedRound, final Block block) { final RoundSpecificPeers peers = context.roundSpecificPeers(preparedRound); - return new PreparedCertificate( + return new TerminatedRoundArtefacts( + peers.getProposer().getMessageFactory().createSignedProposalPayload(preparedRound, block), peers - .getProposer() - .getMessageFactory() - .createSignedProposalPayload(preparedRound, block) - .getSignedPayload(), - peers.createSignedPreparePayloadOfNonProposing(preparedRound, block.getHash())); + .createSignedPreparePayloadOfNonProposing(preparedRound, block.getHash()) + .stream() + .map(Prepare::new) + .collect(Collectors.toList())); } public static NewRound injectEmptyNewRound( diff --git a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/ValidatorPeer.java b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/ValidatorPeer.java index ae96f64c87..6c1c29ab03 100644 --- a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/ValidatorPeer.java +++ b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/ValidatorPeer.java @@ -26,10 +26,10 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.ProposalPayload; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.crypto.SECP256K1; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; @@ -120,9 +120,10 @@ public class ValidatorPeer { } public RoundChange injectRoundChange( - final ConsensusRoundIdentifier rId, final Optional preparedCertificate) { + final ConsensusRoundIdentifier rId, + final Optional terminatedRoundArtefacts) { final RoundChange payload = - messageFactory.createSignedRoundChangePayload(rId, preparedCertificate); + messageFactory.createSignedRoundChangePayload(rId, terminatedRoundArtefacts); injectMessage(RoundChangeMessageData.create(payload)); return payload; } diff --git a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/ReceivedNewRoundTest.java b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/ReceivedNewRoundTest.java index aeb8109af5..731ee1570d 100644 --- a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/ReceivedNewRoundTest.java +++ b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/ReceivedNewRoundTest.java @@ -12,17 +12,17 @@ */ package tech.pegasys.pantheon.consensus.ibft.tests; -import static tech.pegasys.pantheon.consensus.ibft.support.TestHelpers.createValidPreparedCertificate; +import static tech.pegasys.pantheon.consensus.ibft.support.TestHelpers.createValidTerminatedRoundArtefacts; import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Commit; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangePayload; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.consensus.ibft.support.RoundSpecificPeers; import tech.pegasys.pantheon.consensus.ibft.support.TestContext; import tech.pegasys.pantheon.consensus.ibft.support.TestContextBuilder; @@ -111,11 +111,11 @@ public class ReceivedNewRoundTest { final Block reproposedBlock = context.createBlockForProposalFromChainHead(1, 15); final ConsensusRoundIdentifier nextRoundId = new ConsensusRoundIdentifier(1, 1); - final PreparedCertificate preparedCertificate = - createValidPreparedCertificate(context, roundId, initialBlock); + final TerminatedRoundArtefacts terminatedRoundArtefacts = + createValidTerminatedRoundArtefacts(context, roundId, initialBlock); final List> roundChanges = - peers.createSignedRoundChangePayload(nextRoundId, preparedCertificate); + peers.createSignedRoundChangePayload(nextRoundId, terminatedRoundArtefacts); final ValidatorPeer nextProposer = context.roundSpecificPeers(nextRoundId).getProposer(); @@ -164,11 +164,11 @@ public class ReceivedNewRoundTest { final Block reproposedBlock = context.createBlockForProposalFromChainHead(1, 15); final ConsensusRoundIdentifier nextRoundId = new ConsensusRoundIdentifier(1, 1); - final PreparedCertificate preparedCertificate = - createValidPreparedCertificate(context, roundId, initialBlock); + final TerminatedRoundArtefacts terminatedRoundArtefacts = + createValidTerminatedRoundArtefacts(context, roundId, initialBlock); final List> roundChanges = - peers.createSignedRoundChangePayload(nextRoundId, preparedCertificate); + peers.createSignedRoundChangePayload(nextRoundId, terminatedRoundArtefacts); final RoundSpecificPeers nextRoles = context.roundSpecificPeers(nextRoundId); final ValidatorPeer nextProposer = nextRoles.getProposer(); diff --git a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/RoundChangeTest.java b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/RoundChangeTest.java index c5aa557755..8c44b7b04a 100644 --- a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/RoundChangeTest.java +++ b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/tests/RoundChangeTest.java @@ -14,7 +14,7 @@ package tech.pegasys.pantheon.consensus.ibft.tests; import static java.util.Collections.emptyList; import static java.util.Optional.empty; -import static tech.pegasys.pantheon.consensus.ibft.support.TestHelpers.createValidPreparedCertificate; +import static tech.pegasys.pantheon.consensus.ibft.support.TestHelpers.createValidTerminatedRoundArtefacts; import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; import tech.pegasys.pantheon.consensus.ibft.IbftHelpers; @@ -24,10 +24,10 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangePayload; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.consensus.ibft.support.RoundSpecificPeers; import tech.pegasys.pantheon.consensus.ibft.support.TestContext; import tech.pegasys.pantheon.consensus.ibft.support.TestContextBuilder; @@ -130,12 +130,8 @@ public class RoundChangeTest { localNodeMessageFactory.createSignedRoundChangePayload( targetRound, Optional.of( - new PreparedCertificate( - proposal.getSignedPayload(), - Lists.newArrayList( - localPrepareMessage.getSignedPayload(), - p1.getSignedPayload(), - p2.getSignedPayload())))); + new TerminatedRoundArtefacts( + proposal, Lists.newArrayList(localPrepareMessage, p1, p2)))); context.getController().handleRoundExpiry(new RoundExpiry(roundId)); peers.verifyMessagesReceived(expectedTxRoundChange); @@ -173,14 +169,14 @@ public class RoundChangeTest { public void newRoundMessageContainsBlockOnWhichPeerPrepared() { final long ARBITRARY_BLOCKTIME = 1500; - final PreparedCertificate earlierPrepCert = - createValidPreparedCertificate( + final TerminatedRoundArtefacts earlierPrepCert = + createValidTerminatedRoundArtefacts( context, new ConsensusRoundIdentifier(1, 1), context.createBlockForProposalFromChainHead(1, ARBITRARY_BLOCKTIME / 2)); - final PreparedCertificate bestPrepCert = - createValidPreparedCertificate( + final TerminatedRoundArtefacts bestPrepCert = + createValidTerminatedRoundArtefacts( context, new ConsensusRoundIdentifier(1, 2), context.createBlockForProposalFromChainHead(2, ARBITRARY_BLOCKTIME)); @@ -267,8 +263,8 @@ public class RoundChangeTest { final ConsensusRoundIdentifier targetRound = new ConsensusRoundIdentifier(1, 4); - final PreparedCertificate prepCert = - createValidPreparedCertificate( + final TerminatedRoundArtefacts prepCert = + createValidTerminatedRoundArtefacts( context, new ConsensusRoundIdentifier(1, 2), context.createBlockForProposalFromChainHead(2, ARBITRARY_BLOCKTIME)); @@ -333,18 +329,17 @@ public class RoundChangeTest { final RoundChange rc3 = peers.getNonProposing(2).injectRoundChange(targetRound, empty()); // create illegal RoundChangeMessage - final PreparedCertificate illegalPreparedCertificate = - new PreparedCertificate( + final TerminatedRoundArtefacts illegalTerminatedRoundArtefacts = + new TerminatedRoundArtefacts( peers .getNonProposing(0) .getMessageFactory() - .createSignedProposalPayload(roundId, blockToPropose) - .getSignedPayload(), + .createSignedProposalPayload(roundId, blockToPropose), emptyList()); peers .getNonProposing(2) - .injectRoundChange(targetRound, Optional.of(illegalPreparedCertificate)); + .injectRoundChange(targetRound, Optional.of(illegalTerminatedRoundArtefacts)); // Ensure no NewRound message is sent. peers.verifyNoMessagesReceived(); diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/messagewrappers/Proposal.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/messagewrappers/Proposal.java index db9568d2ea..480ef36be0 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/messagewrappers/Proposal.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/messagewrappers/Proposal.java @@ -14,10 +14,15 @@ package tech.pegasys.pantheon.consensus.ibft.messagewrappers; import tech.pegasys.pantheon.consensus.ibft.payload.ProposalPayload; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; +import tech.pegasys.pantheon.ethereum.core.Block; public class Proposal extends IbftMessage { public Proposal(final SignedData payload) { super(payload); } + + public Block getBlock() { + return getSignedPayload().getPayload().getBlock(); + } } diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/network/IbftMessageTransmitter.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/network/IbftMessageTransmitter.java index e6f35b8579..624bbb0178 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/network/IbftMessageTransmitter.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/network/IbftMessageTransmitter.java @@ -24,10 +24,10 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.ProposalPayload; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Block; import tech.pegasys.pantheon.ethereum.core.Hash; @@ -75,10 +75,10 @@ public class IbftMessageTransmitter { public void multicastRoundChange( final ConsensusRoundIdentifier roundIdentifier, - final Optional preparedCertificate) { + final Optional terminatedRoundArtefacts) { final RoundChange data = - messageFactory.createSignedRoundChangePayload(roundIdentifier, preparedCertificate); + messageFactory.createSignedRoundChangePayload(roundIdentifier, terminatedRoundArtefacts); final RoundChangeMessageData message = RoundChangeMessageData.create(data); diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/payload/MessageFactory.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/payload/MessageFactory.java index 6b5559c1db..293d295355 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/payload/MessageFactory.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/payload/MessageFactory.java @@ -18,6 +18,7 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.NewRound; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.crypto.SECP256K1; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; @@ -64,9 +65,12 @@ public class MessageFactory { public RoundChange createSignedRoundChangePayload( final ConsensusRoundIdentifier roundIdentifier, - final Optional preparedCertificate) { + final Optional terminatedRoundArtefacts) { - final RoundChangePayload payload = new RoundChangePayload(roundIdentifier, preparedCertificate); + final RoundChangePayload payload = + new RoundChangePayload( + roundIdentifier, + terminatedRoundArtefacts.map(TerminatedRoundArtefacts::getPreparedCertificate)); return new RoundChange(createSignedMessage(payload)); } diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManager.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManager.java index 0693a15c66..eca0ab94d7 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManager.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManager.java @@ -29,7 +29,6 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.network.IbftMessageTransmitter; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; import tech.pegasys.pantheon.consensus.ibft.payload.Payload; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.validation.MessageValidatorFactory; import tech.pegasys.pantheon.consensus.ibft.validation.NewRoundMessageValidator; @@ -70,7 +69,7 @@ public class IbftBlockHeightManager implements BlockHeightManager { private final Function roundStateCreator; private final IbftFinalState finalState; - private Optional latestPreparedCertificate = Optional.empty(); + private Optional latesteTerminatedRoundArtefacts = Optional.empty(); private IbftRound currentRound; @@ -134,19 +133,20 @@ public class IbftBlockHeightManager implements BlockHeightManager { LOG.info( "Round has expired, creating PreparedCertificate and notifying peers. round={}", currentRound.getRoundIdentifier()); - final Optional preparedCertificate = - currentRound.createPrepareCertificate(); + final Optional terminatedRoundArtefats = + currentRound.constructTerminatedRoundArtefacts(); - if (preparedCertificate.isPresent()) { - latestPreparedCertificate = preparedCertificate; + if (terminatedRoundArtefats.isPresent()) { + latesteTerminatedRoundArtefacts = terminatedRoundArtefats; } startNewRound(currentRound.getRoundIdentifier().getRoundNumber() + 1); final RoundChange localRoundChange = messageFactory.createSignedRoundChangePayload( - currentRound.getRoundIdentifier(), latestPreparedCertificate); - transmitter.multicastRoundChange(currentRound.getRoundIdentifier(), latestPreparedCertificate); + currentRound.getRoundIdentifier(), latesteTerminatedRoundArtefacts); + transmitter.multicastRoundChange( + currentRound.getRoundIdentifier(), latesteTerminatedRoundArtefacts); // Its possible the locally created RoundChange triggers the transmission of a NewRound // message - so it must be handled accordingly. diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRound.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRound.java index c6a288dbe3..23e91ab466 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRound.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRound.java @@ -189,8 +189,8 @@ public class IbftRound { peerIsCommitted(msg); } - public Optional createPrepareCertificate() { - return roundState.constructPreparedCertificate(); + public Optional constructTerminatedRoundArtefacts() { + return roundState.constructTerminatedRoundArtefacts(); } private boolean updateStateWithProposedBlock(final Proposal msg) { diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundState.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundState.java index 7846384b9d..076093467a 100644 --- a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundState.java +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundState.java @@ -18,7 +18,6 @@ import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Commit; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.validation.MessageValidator; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Block; @@ -44,8 +43,8 @@ public class RoundState { // Must track the actual Prepare message, not just the sender, as these may need to be reused // to send out in a PrepareCertificate. - private final Set preparePayloads = Sets.newLinkedHashSet(); - private final Set commitPayloads = Sets.newLinkedHashSet(); + private final Set prepareMessages = Sets.newLinkedHashSet(); + private final Set commitMessages = Sets.newLinkedHashSet(); private boolean prepared = false; private boolean committed = false; @@ -68,8 +67,8 @@ public class RoundState { if (!proposalMessage.isPresent()) { if (validator.addSignedProposalPayload(msg)) { proposalMessage = Optional.of(msg); - preparePayloads.removeIf(p -> !validator.validatePrepareMessage(p)); - commitPayloads.removeIf(p -> !validator.validateCommitMessage(p)); + prepareMessages.removeIf(p -> !validator.validatePrepareMessage(p)); + commitMessages.removeIf(p -> !validator.validateCommitMessage(p)); updateState(); return true; } @@ -80,7 +79,7 @@ public class RoundState { public void addPrepareMessage(final Prepare msg) { if (!proposalMessage.isPresent() || validator.validatePrepareMessage(msg)) { - preparePayloads.add(msg); + prepareMessages.add(msg); LOG.debug("Round state added prepare message prepare={}", msg); } updateState(); @@ -88,7 +87,7 @@ public class RoundState { public void addCommitMessage(final Commit msg) { if (!proposalMessage.isPresent() || validator.validateCommitMessage(msg)) { - commitPayloads.add(msg); + commitMessages.add(msg); LOG.debug("Round state added commit message commit={}", msg); } @@ -99,8 +98,8 @@ public class RoundState { // NOTE: The quorum for Prepare messages is 1 less than the quorum size as the proposer // does not supply a prepare message final long prepareQuorum = prepareMessageCountForQuorum(quorum); - prepared = (preparePayloads.size() >= prepareQuorum) && proposalMessage.isPresent(); - committed = (commitPayloads.size() >= quorum) && proposalMessage.isPresent(); + prepared = (prepareMessages.size() >= prepareQuorum) && proposalMessage.isPresent(); + committed = (commitMessages.size() >= quorum) && proposalMessage.isPresent(); LOG.debug( "Round state updated prepared={} committed={} prepareQuorum={} quorum={}", prepared, @@ -122,21 +121,15 @@ public class RoundState { } public Collection getCommitSeals() { - return commitPayloads + return commitMessages .stream() .map(cp -> cp.getSignedPayload().getPayload().getCommitSeal()) .collect(Collectors.toList()); } - public Optional constructPreparedCertificate() { + public Optional constructTerminatedRoundArtefacts() { if (isPrepared()) { - return Optional.of( - new PreparedCertificate( - proposalMessage.get().getSignedPayload(), - preparePayloads - .stream() - .map(Prepare::getSignedPayload) - .collect(Collectors.toList()))); + return Optional.of(new TerminatedRoundArtefacts(proposalMessage.get(), prepareMessages)); } return Optional.empty(); } diff --git a/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/TerminatedRoundArtefacts.java b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/TerminatedRoundArtefacts.java new file mode 100644 index 0000000000..d1e1e9d06f --- /dev/null +++ b/consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/TerminatedRoundArtefacts.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 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.messagewrappers.Prepare; +import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; +import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; +import tech.pegasys.pantheon.ethereum.core.Block; + +import java.util.Collection; +import java.util.stream.Collectors; + +public class TerminatedRoundArtefacts { + + private Proposal proposal; + private Collection prepares; + + public TerminatedRoundArtefacts(final Proposal proposal, final Collection prepares) { + this.proposal = proposal; + this.prepares = prepares; + } + + public Block getBlock() { + return proposal.getBlock(); + } + + public PreparedCertificate getPreparedCertificate() { + return new PreparedCertificate( + proposal.getSignedPayload(), + prepares.stream().map(Prepare::getSignedPayload).collect(Collectors.toList())); + } +} diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftHelpersTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftHelpersTest.java index 388493290b..0f7a9cb488 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftHelpersTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftHelpersTest.java @@ -20,6 +20,7 @@ import static tech.pegasys.pantheon.consensus.ibft.IbftHelpers.calculateRequired import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.ethereum.core.Block; import tech.pegasys.pantheon.ethereum.core.Hash; @@ -92,17 +93,15 @@ public class IbftHelpersTest { final Proposal differentProposal = proposerMessageFactory.createSignedProposalPayload(preparedRound, proposedBlock); - final Optional latterPreparedCert = + final Optional latterTerminatedRoundArtefacts = Optional.of( - new PreparedCertificate( - differentProposal.getSignedPayload(), + new TerminatedRoundArtefacts( + differentProposal, Lists.newArrayList( - proposerMessageFactory - .createSignedPreparePayload(roundIdentifier, proposedBlock.getHash()) - .getSignedPayload(), - proposerMessageFactory - .createSignedPreparePayload(roundIdentifier, proposedBlock.getHash()) - .getSignedPayload()))); + proposerMessageFactory.createSignedPreparePayload( + roundIdentifier, proposedBlock.getHash()), + proposerMessageFactory.createSignedPreparePayload( + roundIdentifier, proposedBlock.getHash())))); // An earlier PrepareCert is added to ensure the path to find the latest PrepareCert // is correctly followed. @@ -110,29 +109,29 @@ public class IbftHelpersTest { TestHelpers.createFrom(roundIdentifier, 0, -2); final Proposal earlierProposal = proposerMessageFactory.createSignedProposalPayload(earlierPreparedRound, proposedBlock); - final Optional earlierPreparedCert = + final Optional earlierTerminatedRoundArtefacts = Optional.of( - new PreparedCertificate( - earlierProposal.getSignedPayload(), + new TerminatedRoundArtefacts( + earlierProposal, Lists.newArrayList( - proposerMessageFactory - .createSignedPreparePayload(earlierPreparedRound, proposedBlock.getHash()) - .getSignedPayload(), - proposerMessageFactory - .createSignedPreparePayload(earlierPreparedRound, proposedBlock.getHash()) - .getSignedPayload()))); + proposerMessageFactory.createSignedPreparePayload( + earlierPreparedRound, proposedBlock.getHash()), + proposerMessageFactory.createSignedPreparePayload( + earlierPreparedRound, proposedBlock.getHash())))); final Optional newestCert = IbftHelpers.findLatestPreparedCertificate( Lists.newArrayList( proposerMessageFactory - .createSignedRoundChangePayload(roundIdentifier, earlierPreparedCert) + .createSignedRoundChangePayload( + roundIdentifier, earlierTerminatedRoundArtefacts) .getSignedPayload(), proposerMessageFactory - .createSignedRoundChangePayload(roundIdentifier, latterPreparedCert) + .createSignedRoundChangePayload(roundIdentifier, latterTerminatedRoundArtefacts) .getSignedPayload())); - assertThat(newestCert).isEqualTo(latterPreparedCert); + assertThat(newestCert.get()) + .isEqualTo(latterTerminatedRoundArtefacts.get().getPreparedCertificate()); } @Test diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java index 5cd12cab8d..ab09022ac2 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftBlockHeightManagerTest.java @@ -40,7 +40,6 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.network.IbftMessageTransmitter; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.validation.MessageValidator; import tech.pegasys.pantheon.consensus.ibft.validation.MessageValidatorFactory; @@ -93,7 +92,7 @@ public class IbftBlockHeightManagerTest { @Mock private RoundTimer roundTimer; @Mock private NewRoundMessageValidator newRoundMessageValidator; - @Captor private ArgumentCaptor> preparedCaptor; + @Captor private ArgumentCaptor> terminatedRoundArtefactsCaptor; private final List validatorKeys = Lists.newArrayList(); private final List
validators = Lists.newArrayList(); @@ -360,12 +359,13 @@ public class IbftBlockHeightManagerTest { final ConsensusRoundIdentifier nextRound = createFrom(roundIdentifier, 0, +1); verify(messageTransmitter, times(1)) - .multicastRoundChange(eq(nextRound), preparedCaptor.capture()); - final Optional preparedCert = preparedCaptor.getValue(); + .multicastRoundChange(eq(nextRound), terminatedRoundArtefactsCaptor.capture()); + final Optional preparedCert = + terminatedRoundArtefactsCaptor.getValue(); assertThat(preparedCert).isNotEmpty(); - assertThat(preparedCert.get().getPreparePayloads()) + assertThat(preparedCert.get().getPreparedCertificate().getPreparePayloads()) .containsOnly(firstPrepare.getSignedPayload(), secondPrepare.getSignedPayload()); } } diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRoundTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRoundTest.java index dc00243d6e..340b12759a 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRoundTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftRoundTest.java @@ -30,7 +30,6 @@ import tech.pegasys.pantheon.consensus.ibft.IbftExtraData; import tech.pegasys.pantheon.consensus.ibft.blockcreation.IbftBlockCreator; import tech.pegasys.pantheon.consensus.ibft.network.IbftMessageTransmitter; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.ProposalPayload; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; @@ -305,10 +304,9 @@ public class IbftRoundTest { .createSignedRoundChangePayload( roundIdentifier, Optional.of( - new PreparedCertificate( - messageFactory - .createSignedProposalPayload(priorRoundChange, proposedBlock) - .getSignedPayload(), + new TerminatedRoundArtefacts( + messageFactory.createSignedProposalPayload( + priorRoundChange, proposedBlock), Collections.emptyList()))) .getSignedPayload())); // NOTE: IbftRound assumes the prepare's are valid diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManagerTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManagerTest.java index d67cb7954c..b2e5a5e68d 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManagerTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundChangeManagerTest.java @@ -21,12 +21,10 @@ 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.TestHelpers; +import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparePayload; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; -import tech.pegasys.pantheon.consensus.ibft.payload.SignedData; import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator; import tech.pegasys.pantheon.consensus.ibft.validation.SignedDataValidator; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; @@ -142,22 +140,21 @@ public class RoundChangeManagerTest { // Proposal must come from an earlier round. final Proposal proposal = messageFactory.createSignedProposalPayload(proposalRound, block); - final List> preparePayloads = + final List preparePayloads = prepareProviders .stream() .map( k -> { final MessageFactory prepareFactory = new MessageFactory(k); - return prepareFactory - .createSignedPreparePayload(proposalRound, block.getHash()) - .getSignedPayload(); + return prepareFactory.createSignedPreparePayload(proposalRound, block.getHash()); }) .collect(Collectors.toList()); - final PreparedCertificate cert = - new PreparedCertificate(proposal.getSignedPayload(), preparePayloads); + final TerminatedRoundArtefacts terminatedRoundArtects = + new TerminatedRoundArtefacts(proposal, preparePayloads); - return messageFactory.createSignedRoundChangePayload(round, Optional.of(cert)); + return messageFactory.createSignedRoundChangePayload( + round, Optional.of(terminatedRoundArtects)); } @Test diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundStateTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundStateTest.java index 25faa298fc..726fb9e20c 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundStateTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/statemachine/RoundStateTest.java @@ -71,7 +71,7 @@ public class RoundStateTest { assertThat(roundState.isPrepared()).isFalse(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isEmpty(); } @Test @@ -85,7 +85,7 @@ public class RoundStateTest { assertThat(roundState.setProposedBlock(proposal)).isFalse(); assertThat(roundState.isPrepared()).isFalse(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isEmpty(); } @Test @@ -99,8 +99,13 @@ public class RoundStateTest { assertThat(roundState.setProposedBlock(proposal)).isTrue(); assertThat(roundState.isPrepared()).isTrue(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isNotEmpty(); - assertThat(roundState.constructPreparedCertificate().get().getProposalPayload()) + assertThat(roundState.constructTerminatedRoundArtefacts()).isNotEmpty(); + assertThat( + roundState + .constructTerminatedRoundArtefacts() + .get() + .getPreparedCertificate() + .getProposalPayload()) .isEqualTo(proposal.getSignedPayload()); } @@ -129,7 +134,7 @@ public class RoundStateTest { roundState.addCommitMessage(commit); assertThat(roundState.isPrepared()).isTrue(); assertThat(roundState.isCommitted()).isTrue(); - assertThat(roundState.constructPreparedCertificate()).isNotEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isNotEmpty(); } @Test @@ -152,19 +157,19 @@ public class RoundStateTest { roundState.addPrepareMessage(firstPrepare); assertThat(roundState.isPrepared()).isFalse(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isEmpty(); roundState.addPrepareMessage(secondPrepare); assertThat(roundState.isPrepared()).isFalse(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isEmpty(); final Proposal proposal = validatorMessageFactories.get(0).createSignedProposalPayload(roundIdentifier, block); assertThat(roundState.setProposedBlock(proposal)).isTrue(); assertThat(roundState.isPrepared()).isTrue(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isNotEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isNotEmpty(); } @Test @@ -197,7 +202,7 @@ public class RoundStateTest { assertThat(roundState.setProposedBlock(proposal)).isTrue(); assertThat(roundState.isPrepared()).isFalse(); assertThat(roundState.isCommitted()).isFalse(); - assertThat(roundState.constructPreparedCertificate()).isEmpty(); + assertThat(roundState.constructTerminatedRoundArtefacts()).isEmpty(); } @Test diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundSignedDataValidatorTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundSignedDataValidatorTest.java index d5f02bf04a..8de87c97ca 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundSignedDataValidatorTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/NewRoundSignedDataValidatorTest.java @@ -25,8 +25,8 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.NewRound; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Proposal; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; import tech.pegasys.pantheon.consensus.ibft.payload.NewRoundPayload; -import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; import tech.pegasys.pantheon.consensus.ibft.payload.RoundChangeCertificate; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorForHeightFactory; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.ethereum.core.Address; @@ -165,22 +165,19 @@ public class NewRoundSignedDataValidatorTest { final Block prevProposedBlock = TestHelpers.createProposalBlock(validators.subList(0, 1), roundIdentifier.getRoundNumber()); - final PreparedCertificate misMatchedPreparedCertificate = - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(preparedRound, prevProposedBlock) - .getSignedPayload(), + final TerminatedRoundArtefacts mismatchedRoundArtefacts = + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(preparedRound, prevProposedBlock), singletonList( - validatorMessageFactory - .createSignedPreparePayload(preparedRound, prevProposedBlock.getHash()) - .getSignedPayload())); + validatorMessageFactory.createSignedPreparePayload( + preparedRound, prevProposedBlock.getHash()))); msgBuilder.setRoundChangeCertificate( new RoundChangeCertificate( singletonList( validatorMessageFactory .createSignedRoundChangePayload( - roundIdentifier, Optional.of(misMatchedPreparedCertificate)) + roundIdentifier, Optional.of(mismatchedRoundArtefacts)) .getSignedPayload()))); final NewRound invalidMsg = signPayload(msgBuilder.build(), proposerKey); @@ -214,14 +211,11 @@ public class NewRoundSignedDataValidatorTest { proposerMessageFactory.createSignedRoundChangePayload( roundIdentifier, Optional.of( - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(prevRound, proposedBlock) - .getSignedPayload(), + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(prevRound, proposedBlock), Lists.newArrayList( - validatorMessageFactory - .createSignedPreparePayload(prevRound, proposedBlock.getHash()) - .getSignedPayload()))))); + validatorMessageFactory.createSignedPreparePayload( + prevRound, proposedBlock.getHash())))))); msgBuilder.setRoundChangeCertificate(roundChangeBuilder.buildCertificate()); @@ -240,14 +234,13 @@ public class NewRoundSignedDataValidatorTest { roundIdentifier.getSequenceNumber(), roundIdentifier.getRoundNumber() - 1); final Proposal latterProposal = proposerMessageFactory.createSignedProposalPayload(latterPrepareRound, proposedBlock); - final Optional preparedCert = + final Optional preparedCert = Optional.of( - new PreparedCertificate( - latterProposal.getSignedPayload(), + new TerminatedRoundArtefacts( + latterProposal, Lists.newArrayList( - validatorMessageFactory - .createSignedPreparePayload(roundIdentifier, proposedBlock.getHash()) - .getSignedPayload()))); + validatorMessageFactory.createSignedPreparePayload( + roundIdentifier, proposedBlock.getHash())))); // An earlier PrepareCert is added to ensure the path to find the latest PrepareCert // is correctly followed. @@ -258,14 +251,13 @@ public class NewRoundSignedDataValidatorTest { roundIdentifier.getSequenceNumber(), roundIdentifier.getRoundNumber() - 2); final Proposal earlierProposal = proposerMessageFactory.createSignedProposalPayload(earlierPreparedRound, earlierBlock); - final Optional earlierPreparedCert = + final Optional earlierPreparedCert = Optional.of( - new PreparedCertificate( - earlierProposal.getSignedPayload(), + new TerminatedRoundArtefacts( + earlierProposal, Lists.newArrayList( - validatorMessageFactory - .createSignedPreparePayload(earlierPreparedRound, earlierBlock.getHash()) - .getSignedPayload()))); + validatorMessageFactory.createSignedPreparePayload( + earlierPreparedRound, earlierBlock.getHash())))); final RoundChangeCertificate roundChangeCert = new RoundChangeCertificate( diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeSignedDataValidatorTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeSignedDataValidatorTest.java index 3560e1d956..ba8411a162 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeSignedDataValidatorTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/validation/RoundChangeSignedDataValidatorTest.java @@ -25,6 +25,7 @@ import tech.pegasys.pantheon.consensus.ibft.messagewrappers.Prepare; import tech.pegasys.pantheon.consensus.ibft.messagewrappers.RoundChange; import tech.pegasys.pantheon.consensus.ibft.payload.MessageFactory; import tech.pegasys.pantheon.consensus.ibft.payload.PreparedCertificate; +import tech.pegasys.pantheon.consensus.ibft.statemachine.TerminatedRoundArtefacts; import tech.pegasys.pantheon.consensus.ibft.validation.RoundChangeMessageValidator.MessageValidatorForHeightFactory; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.ethereum.core.Address; @@ -95,16 +96,17 @@ public class RoundChangeSignedDataValidatorTest { @Test public void roundChangeContainingInvalidProposalFails() { - final PreparedCertificate prepareCertificate = - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(currentRound, block) - .getSignedPayload(), + final TerminatedRoundArtefacts terminatedRoundArtefacts = + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(currentRound, block), Collections.emptyList()); + final PreparedCertificate prepareCertificate = + terminatedRoundArtefacts.getPreparedCertificate(); + final RoundChange msg = proposerMessageFactory.createSignedRoundChangePayload( - targetRound, Optional.of(prepareCertificate)); + targetRound, Optional.of(terminatedRoundArtefacts)); when(basicValidator.addSignedProposalPayload(any())).thenReturn(false); @@ -119,16 +121,14 @@ public class RoundChangeSignedDataValidatorTest { @Test public void roundChangeContainingValidProposalButNoPrepareMessagesFails() { - final PreparedCertificate prepareCertificate = - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(currentRound, block) - .getSignedPayload(), + final TerminatedRoundArtefacts terminatedRoundArtefacts = + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(currentRound, block), Collections.emptyList()); final RoundChange msg = proposerMessageFactory.createSignedRoundChangePayload( - targetRound, Optional.of(prepareCertificate)); + targetRound, Optional.of(terminatedRoundArtefacts)); when(basicValidator.addSignedProposalPayload(any())).thenReturn(true); assertThat(validator.validateMessage(msg.getSignedPayload())).isFalse(); @@ -138,19 +138,17 @@ public class RoundChangeSignedDataValidatorTest { public void roundChangeInvalidPrepareMessageFromProposerFails() { final Prepare prepareMsg = validatorMessageFactory.createSignedPreparePayload(currentRound, block.getHash()); - final PreparedCertificate prepareCertificate = - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(currentRound, block) - .getSignedPayload(), - Lists.newArrayList(prepareMsg.getSignedPayload())); + final TerminatedRoundArtefacts terminatedRoundArtefacts = + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(currentRound, block), + Lists.newArrayList(prepareMsg)); when(basicValidator.addSignedProposalPayload(any())).thenReturn(true); when(basicValidator.validatePrepareMessage(any())).thenReturn(false); final RoundChange msg = proposerMessageFactory.createSignedRoundChangePayload( - targetRound, Optional.of(prepareCertificate)); + targetRound, Optional.of(terminatedRoundArtefacts)); assertThat(validator.validateMessage(msg.getSignedPayload())).isFalse(); @@ -179,16 +177,14 @@ public class RoundChangeSignedDataValidatorTest { final Prepare prepareMsg = validatorMessageFactory.createSignedPreparePayload(futureRound, block.getHash()); - final PreparedCertificate prepareCertificate = - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(futureRound, block) - .getSignedPayload(), - Lists.newArrayList(prepareMsg.getSignedPayload())); + final TerminatedRoundArtefacts terminatedRoundArtefacts = + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(futureRound, block), + Lists.newArrayList(prepareMsg)); final RoundChange msg = proposerMessageFactory.createSignedRoundChangePayload( - targetRound, Optional.of(prepareCertificate)); + targetRound, Optional.of(terminatedRoundArtefacts)); assertThat(validator.validateMessage(msg.getSignedPayload())).isFalse(); verify(validatorFactory, never()).createAt(any()); @@ -200,16 +196,17 @@ public class RoundChangeSignedDataValidatorTest { public void roundChangeWithPastProposalForCurrentHeightIsSuccessful() { final Prepare prepareMsg = validatorMessageFactory.createSignedPreparePayload(currentRound, block.getHash()); + final TerminatedRoundArtefacts terminatedRoundArtefacts = + new TerminatedRoundArtefacts( + proposerMessageFactory.createSignedProposalPayload(currentRound, block), + Lists.newArrayList(prepareMsg)); + final PreparedCertificate prepareCertificate = - new PreparedCertificate( - proposerMessageFactory - .createSignedProposalPayload(currentRound, block) - .getSignedPayload(), - Lists.newArrayList(prepareMsg.getSignedPayload())); + terminatedRoundArtefacts.getPreparedCertificate(); final RoundChange msg = proposerMessageFactory.createSignedRoundChangePayload( - targetRound, Optional.of(prepareCertificate)); + targetRound, Optional.of(terminatedRoundArtefacts)); when(basicValidator.addSignedProposalPayload(prepareCertificate.getProposalPayload())) .thenReturn(true);