use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class WeightedRotatingLeadersTest method when_get_proposer_skipping_views__then_should_return_same_result_as_in_order.
@Test
public void when_get_proposer_skipping_views__then_should_return_same_result_as_in_order() {
for (int validatorSetSize = 1; validatorSetSize <= 128; validatorSetSize *= 2) {
for (int sizeOfCache = 1; sizeOfCache <= 128; sizeOfCache *= 2) {
setUp(validatorSetSize, sizeOfCache);
// 2 * sizeOfCache so cache eviction occurs
final int viewsToTest = 2 * sizeOfCache;
for (int view = 0; view < viewsToTest; view++) {
weightedRotatingLeaders2.getProposer(View.of(view));
}
BFTNode node1 = weightedRotatingLeaders.getProposer(View.of(viewsToTest - 1));
BFTNode node2 = weightedRotatingLeaders2.getProposer(View.of(viewsToTest - 1));
assertThat(node1).isEqualTo(node2);
}
}
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class WeightedRotatingLeadersTest method when_validators_distributed_by_fibonacci__then_leaders_also_distributed_in_fibonacci.
@Test
public void when_validators_distributed_by_fibonacci__then_leaders_also_distributed_in_fibonacci() {
// fibonacci sequence can quickly explode so keep sizes small
final int validatorSetSize = 8;
final int sizeOfCache = 4;
final Supplier<IntStream> fibonacci = () -> Stream.iterate(new int[] { 1, 1 }, t -> new int[] { t[1], t[0] + t[1] }).mapToInt(t -> t[0]).limit(validatorSetSize);
final int sumOfPower = fibonacci.get().sum();
this.validatorsInOrder = fibonacci.get().mapToObj(p -> BFTValidator.from(BFTNode.random(), UInt256.from(p))).collect(ImmutableList.toImmutableList());
BFTValidatorSet validatorSet = BFTValidatorSet.from(validatorsInOrder);
this.weightedRotatingLeaders = new WeightedRotatingLeaders(validatorSet, sizeOfCache);
Map<BFTNode, UInt256> proposerCounts = Stream.iterate(View.of(0), View::next).limit(sumOfPower).map(this.weightedRotatingLeaders::getProposer).collect(groupingBy(p -> p, collectingAndThen(counting(), UInt256::from)));
Map<BFTNode, UInt256> expected = validatorsInOrder.stream().collect(toMap(BFTValidator::getNode, BFTValidator::getPower));
assertThat(proposerCounts).isEqualTo(expected);
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class MessageCentralBFTNetworkTest method when_send_vote__then_message_central_should_be_sent_vote_message.
@Test
public void when_send_vote__then_message_central_should_be_sent_vote_message() {
Vote vote = mock(Vote.class);
ECPublicKey leaderPk = ECKeyPair.generateNew().getPublicKey();
BFTNode leader = mock(BFTNode.class);
when(leader.getKey()).thenReturn(leaderPk);
network.voteDispatcher().dispatch(leader, vote);
verify(messageCentral, times(1)).send(eq(NodeId.fromPublicKey(leaderPk)), any(ConsensusEventMessage.class));
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class MessageCentralValidatorSyncTest method when_send_response__then_message_central_will_send_response.
@Test
public void when_send_response__then_message_central_will_send_response() {
VerifiedVertex vertex = mock(VerifiedVertex.class);
when(vertex.toSerializable()).thenReturn(mock(UnverifiedVertex.class));
ImmutableList<VerifiedVertex> vertices = ImmutableList.of(vertex);
BFTNode node = mock(BFTNode.class);
ECPublicKey ecPublicKey = mock(ECPublicKey.class);
when(node.getKey()).thenReturn(ecPublicKey);
sync.verticesResponseDispatcher().dispatch(node, new GetVerticesResponse(vertices));
verify(messageCentral, times(1)).send(any(), any(GetVerticesResponseMessage.class));
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class SafetyChecker method process.
private Optional<TestInvariantError> process(BFTNode node, VerifiedVertex vertex) {
final EpochView epochView = EpochView.of(vertex.getParentHeader().getLedgerHeader().getEpoch(), vertex.getView());
final VerifiedVertex currentVertexAtView = committedVertices.get(epochView);
if (currentVertexAtView != null) {
if (!currentVertexAtView.getId().equals(vertex.getId())) {
return conflictingVerticesError(vertex, currentVertexAtView);
}
} else {
EpochView parentEpochView = EpochView.of(vertex.getParentHeader().getLedgerHeader().getEpoch(), vertex.getParentHeader().getView());
VerifiedVertex parent = committedVertices.get(parentEpochView);
if (parent == null) {
Entry<EpochView, VerifiedVertex> higherCommitted = committedVertices.higherEntry(parentEpochView);
if (higherCommitted != null) {
BFTHeader higherParentHeader = higherCommitted.getValue().getParentHeader();
EpochView higherCommittedParentEpochView = EpochView.of(higherParentHeader.getLedgerHeader().getEpoch(), higherParentHeader.getView());
if (epochView.compareTo(higherCommittedParentEpochView) > 0) {
return brokenChainError(vertex, higherCommitted.getValue());
}
}
}
committedVertices.put(epochView, vertex);
}
// Clean up old vertices so that we avoid consuming too much memory
lastCommittedByNode.put(node, epochView);
final EpochView lowest = nodes.stream().map(n -> lastCommittedByNode.getOrDefault(n, EpochView.of(0, View.genesis()))).reduce((v0, v1) -> v0.compareTo(v1) < 0 ? v0 : v1).orElse(EpochView.of(0, View.genesis()));
committedVertices.headMap(lowest).clear();
return Optional.empty();
}
Aggregations