forked from PegaSysEng/pantheon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring for more readable IBFT IT (PegaSysEng#614)
* Refactoring for more readable IBFT IT * Renaming Roles to peers * Moving the assert behaviour into the RoundChangePeers * Renmaing prefix of assert to verify, grammar * Reducing usage of getAllPeers() * Dropping the getter for the peer list * Dropping peer from method names, as it's now in the class name * Spotless
- Loading branch information
Showing
13 changed files
with
484 additions
and
538 deletions.
There are no files selected for viewing
86 changes: 0 additions & 86 deletions
86
...ation-test/java/tech/pegasys/pantheon/consensus/ibft/support/MessageReceptionHelpers.java
This file was deleted.
Oops, something went wrong.
49 changes: 0 additions & 49 deletions
49
...ration-test/java/tech/pegasys/pantheon/consensus/ibft/support/RoundSpecificNodeRoles.java
This file was deleted.
Oops, something went wrong.
219 changes: 219 additions & 0 deletions
219
...ntegration-test/java/tech/pegasys/pantheon/consensus/ibft/support/RoundSpecificPeers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
/* | ||
* 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.support; | ||
|
||
import static java.util.Optional.empty; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Fail.fail; | ||
|
||
import tech.pegasys.pantheon.consensus.ibft.ConsensusRoundIdentifier; | ||
import tech.pegasys.pantheon.consensus.ibft.messagedata.CommitMessageData; | ||
import tech.pegasys.pantheon.consensus.ibft.messagedata.IbftV2; | ||
import tech.pegasys.pantheon.consensus.ibft.messagedata.NewRoundMessageData; | ||
import tech.pegasys.pantheon.consensus.ibft.messagedata.PrepareMessageData; | ||
import tech.pegasys.pantheon.consensus.ibft.messagedata.ProposalMessageData; | ||
import tech.pegasys.pantheon.consensus.ibft.messagedata.RoundChangeMessageData; | ||
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.crypto.SECP256K1.Signature; | ||
import tech.pegasys.pantheon.ethereum.core.Hash; | ||
import tech.pegasys.pantheon.ethereum.p2p.api.MessageData; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.collect.Lists; | ||
|
||
public class RoundSpecificPeers { | ||
|
||
private final ValidatorPeer proposer; | ||
private final Collection<ValidatorPeer> peers; | ||
private final List<ValidatorPeer> nonProposingPeers; | ||
|
||
public RoundSpecificPeers( | ||
final ValidatorPeer proposer, | ||
final Collection<ValidatorPeer> peers, | ||
final List<ValidatorPeer> nonProposingPeers) { | ||
this.proposer = proposer; | ||
this.peers = peers; | ||
this.nonProposingPeers = nonProposingPeers; | ||
} | ||
|
||
public ValidatorPeer getProposer() { | ||
return proposer; | ||
} | ||
|
||
public ValidatorPeer getFirstNonProposer() { | ||
return nonProposingPeers.get(0); | ||
} | ||
|
||
public void clearReceivedMessages() { | ||
peers.forEach(ValidatorPeer::clearReceivedMessages); | ||
} | ||
|
||
public List<Signature> sign(final Hash digest) { | ||
return peers.stream().map(peer -> peer.getBlockSignature(digest)).collect(Collectors.toList()); | ||
} | ||
|
||
public ValidatorPeer getNonProposing(final int index) { | ||
return nonProposingPeers.get(index); | ||
} | ||
|
||
public List<SignedData<RoundChangePayload>> roundChangeForNonProposing( | ||
final ConsensusRoundIdentifier targetRound) { | ||
return nonProposingPeers | ||
.stream() | ||
.map(peer -> peer.injectRoundChange(targetRound, empty())) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public void commit(final ConsensusRoundIdentifier roundId, final Hash hash) { | ||
peers.forEach(peer -> peer.injectCommit(roundId, hash)); | ||
} | ||
|
||
public List<SignedData<RoundChangePayload>> roundChange(final ConsensusRoundIdentifier roundId) { | ||
final List<SignedData<RoundChangePayload>> changes = Lists.newArrayList(); | ||
|
||
for (final ValidatorPeer peer : peers) { | ||
changes.add(peer.injectRoundChange(roundId, empty())); | ||
} | ||
|
||
return changes; | ||
} | ||
|
||
public List<SignedData<RoundChangePayload>> createSignedRoundChangePayload( | ||
final ConsensusRoundIdentifier roundId) { | ||
return peers | ||
.stream() | ||
.map(p -> p.getMessageFactory().createSignedRoundChangePayload(roundId, empty())) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public List<SignedData<RoundChangePayload>> createSignedRoundChangePayload( | ||
final ConsensusRoundIdentifier roundId, final PreparedCertificate preparedCertificate) { | ||
return peers | ||
.stream() | ||
.map( | ||
p -> | ||
p.getMessageFactory() | ||
.createSignedRoundChangePayload(roundId, Optional.of(preparedCertificate))) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public void prepareForNonProposing(final ConsensusRoundIdentifier roundId, final Hash hash) { | ||
nonProposingPeers.forEach(peer -> peer.injectPrepare(roundId, hash)); | ||
} | ||
|
||
public void commitForNonProposing(final ConsensusRoundIdentifier roundId, final Hash hash) { | ||
nonProposingPeers.forEach(peer -> peer.injectCommit(roundId, hash)); | ||
} | ||
|
||
Collection<SignedData<PreparePayload>> createSignedPreparePayloadOfNonProposing( | ||
final ConsensusRoundIdentifier preparedRound, final Hash hash) { | ||
return nonProposingPeers | ||
.stream() | ||
.map(role -> role.getMessageFactory().createSignedPreparePayload(preparedRound, hash)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public void verifyNoMessagesReceived() { | ||
peers.forEach(n -> assertThat(n.getReceivedMessages()).isEmpty()); | ||
} | ||
|
||
public void verifyNoMessagesReceivedNonProposing() { | ||
nonProposingPeers.forEach(n -> assertThat(n.getReceivedMessages()).isEmpty()); | ||
} | ||
|
||
public void verifyNoMessagesReceivedProposer() { | ||
assertThat(proposer.getReceivedMessages()).isEmpty(); | ||
} | ||
|
||
@SafeVarargs | ||
public final void verifyMessagesReceivedPropser(final SignedData<? extends Payload>... msgs) { | ||
verifyMessagesReceived(ImmutableList.of(proposer), msgs); | ||
} | ||
|
||
@SafeVarargs | ||
public final void verifyMessagesReceivedNonPropsingExcluding( | ||
final ValidatorPeer exclude, final SignedData<? extends Payload>... msgs) { | ||
final Collection<ValidatorPeer> candidates = Lists.newArrayList(nonProposingPeers); | ||
candidates.remove(exclude); | ||
verifyMessagesReceived(candidates, msgs); | ||
} | ||
|
||
@SafeVarargs | ||
public final void verifyMessagesReceivedNonPropsing(final SignedData<? extends Payload>... msgs) { | ||
verifyMessagesReceived(nonProposingPeers, msgs); | ||
} | ||
|
||
@SafeVarargs | ||
public final void verifyMessagesReceived(final SignedData<? extends Payload>... msgs) { | ||
verifyMessagesReceived(peers, msgs); | ||
} | ||
|
||
@SafeVarargs | ||
private final void verifyMessagesReceived( | ||
final Collection<ValidatorPeer> candidates, final SignedData<? extends Payload>... msgs) { | ||
candidates.forEach(n -> assertThat(n.getReceivedMessages().size()).isEqualTo(msgs.length)); | ||
|
||
List<SignedData<? extends Payload>> msgList = Arrays.asList(msgs); | ||
|
||
for (int i = 0; i < msgList.size(); i++) { | ||
final int index = i; | ||
final SignedData<? extends Payload> msg = msgList.get(index); | ||
candidates.forEach( | ||
n -> { | ||
final List<MessageData> rxMsgs = n.getReceivedMessages(); | ||
final MessageData rxMsgData = rxMsgs.get(index); | ||
verifyMessage(rxMsgData, msg); | ||
}); | ||
} | ||
candidates.forEach(ValidatorPeer::clearReceivedMessages); | ||
} | ||
|
||
private void verifyMessage( | ||
final MessageData actual, final SignedData<? extends Payload> signedExpectedPayload) { | ||
final Payload expectedPayload = signedExpectedPayload.getPayload(); | ||
SignedData<?> actualSignedPayload = null; | ||
|
||
switch (expectedPayload.getMessageType()) { | ||
case IbftV2.PROPOSAL: | ||
actualSignedPayload = ProposalMessageData.fromMessageData(actual).decode(); | ||
break; | ||
case IbftV2.PREPARE: | ||
actualSignedPayload = PrepareMessageData.fromMessageData(actual).decode(); | ||
break; | ||
case IbftV2.COMMIT: | ||
actualSignedPayload = CommitMessageData.fromMessageData(actual).decode(); | ||
break; | ||
case IbftV2.NEW_ROUND: | ||
actualSignedPayload = NewRoundMessageData.fromMessageData(actual).decode(); | ||
break; | ||
case IbftV2.ROUND_CHANGE: | ||
actualSignedPayload = RoundChangeMessageData.fromMessageData(actual).decode(); | ||
break; | ||
default: | ||
fail("Illegal IBFTV2 message type."); | ||
break; | ||
} | ||
assertThat(signedExpectedPayload) | ||
.isEqualToComparingFieldByFieldRecursively(actualSignedPayload); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.