use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class MessageCentralValidatorSyncTest method when_send_error_response__then_message_central_will_send_error_response.
@Test
public void when_send_error_response__then_message_central_will_send_error_response() {
QuorumCertificate qc = mock(QuorumCertificate.class);
HighQC highQC = mock(HighQC.class);
when(highQC.highestQC()).thenReturn(qc);
when(highQC.highestCommittedQC()).thenReturn(qc);
BFTNode node = mock(BFTNode.class);
ECPublicKey ecPublicKey = mock(ECPublicKey.class);
when(node.getKey()).thenReturn(ecPublicKey);
final var request = new GetVerticesRequest(HashUtils.random256(), 3);
sync.verticesErrorResponseDispatcher().dispatch(node, new GetVerticesErrorResponse(highQC, request));
verify(messageCentral, times(1)).send(eq(NodeId.fromPublicKey(ecPublicKey)), any(GetVerticesErrorResponseMessage.class));
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class ConsensusModuleTest method getExternalModule.
private Module getExternalModule() {
return new AbstractModule() {
@Override
protected void configure() {
bind(Ledger.class).toInstance(mock(Ledger.class));
bind(new TypeLiteral<EventDispatcher<LocalTimeoutOccurrence>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<ViewUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTInsertUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTRebuildUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTHighQCUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTCommittedUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<LocalSyncRequest>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<GetVerticesRequest>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<ScheduledLocalTimeout>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<ViewQuorumReached>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<Vote>>() {
}).toInstance(rmock(RemoteEventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<Proposal>>() {
}).toInstance(rmock(RemoteEventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<GetVerticesRequest>>() {
}).toInstance(requestSender);
bind(new TypeLiteral<RemoteEventDispatcher<GetVerticesResponse>>() {
}).toInstance(responseSender);
bind(new TypeLiteral<RemoteEventDispatcher<GetVerticesErrorResponse>>() {
}).toInstance(errorResponseSender);
bind(new TypeLiteral<EventDispatcher<NoVote>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<View>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<VertexRequestTimeout>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(PersistentVertexStore.class).toInstance(mock(PersistentVertexStore.class));
bind(PersistentSafetyStateStore.class).toInstance(mock(PersistentSafetyStateStore.class));
bind(NextTxnsGenerator.class).toInstance(mock(NextTxnsGenerator.class));
bind(SystemCounters.class).toInstance(mock(SystemCounters.class));
bind(TimeSupplier.class).toInstance(mock(TimeSupplier.class));
bind(BFTConfiguration.class).toInstance(bftConfiguration);
bind(BFTValidatorSet.class).toInstance(bftConfiguration.getValidatorSet());
LedgerProof proof = mock(LedgerProof.class);
when(proof.getView()).thenReturn(View.genesis());
bind(LedgerProof.class).annotatedWith(LastProof.class).toInstance(proof);
bind(RateLimiter.class).annotatedWith(GetVerticesRequestRateLimit.class).toInstance(RateLimiter.create(Double.MAX_VALUE));
bindConstant().annotatedWith(BFTSyncPatienceMillis.class).to(200);
bindConstant().annotatedWith(PacemakerTimeout.class).to(1000L);
bindConstant().annotatedWith(PacemakerRate.class).to(2.0);
bindConstant().annotatedWith(PacemakerMaxExponent.class).to(6);
ECKeyPair ecKeyPair = ECKeyPair.generateNew();
bind(HashSigner.class).toInstance(ecKeyPair::sign);
}
@Provides
ViewUpdate viewUpdate(@Self BFTNode node) {
return ViewUpdate.create(View.of(1), mock(HighQC.class), node, node);
}
@Provides
@Self
private BFTNode bftNode() {
return BFTNode.create(ecKeyPair.getPublicKey());
}
};
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class EpochManagerTest method getExternalModule.
private Module getExternalModule() {
BFTNode self = BFTNode.create(ecKeyPair.getPublicKey());
return new AbstractModule() {
@Override
protected void configure() {
bind(HashSigner.class).toInstance(ecKeyPair::sign);
bind(BFTNode.class).annotatedWith(Self.class).toInstance(self);
bind(new TypeLiteral<EventDispatcher<LocalTimeoutOccurrence>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTInsertUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTRebuildUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTHighQCUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<BFTCommittedUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<EpochLocalTimeoutOccurrence>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<EpochView>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<LocalSyncRequest>>() {
}).toInstance(syncLedgerRequestSender);
bind(new TypeLiteral<EventDispatcher<ViewQuorumReached>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<EpochViewUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<ViewUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<NoVote>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<EventDispatcher<LedgerUpdate>>() {
}).toInstance(rmock(EventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<GetVerticesRequest>>() {
}).toInstance(timeoutScheduler);
bind(new TypeLiteral<ScheduledEventDispatcher<ScheduledLocalTimeout>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<Epoched<ScheduledLocalTimeout>>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(new TypeLiteral<ScheduledEventDispatcher<VertexRequestTimeout>>() {
}).toInstance(rmock(ScheduledEventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<Proposal>>() {
}).toInstance(proposalDispatcher);
bind(new TypeLiteral<RemoteEventDispatcher<Vote>>() {
}).toInstance(voteDispatcher);
bind(new TypeLiteral<RemoteEventDispatcher<GetVerticesRequest>>() {
}).toInstance(rmock(RemoteEventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<GetVerticesResponse>>() {
}).toInstance(rmock(RemoteEventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<GetVerticesErrorResponse>>() {
}).toInstance(rmock(RemoteEventDispatcher.class));
bind(new TypeLiteral<RemoteEventDispatcher<LedgerStatusUpdate>>() {
}).toInstance(rmock(RemoteEventDispatcher.class));
bind(PersistentSafetyStateStore.class).toInstance(mock(PersistentSafetyStateStore.class));
bind(NextTxnsGenerator.class).toInstance(nextTxnsGenerator);
bind(SystemCounters.class).toInstance(new SystemCountersImpl());
bind(Mempool.class).toInstance(mempool);
bind(StateComputer.class).toInstance(stateComputer);
bind(PersistentVertexStore.class).toInstance(mock(PersistentVertexStore.class));
bind(RateLimiter.class).annotatedWith(GetVerticesRequestRateLimit.class).toInstance(RateLimiter.create(Double.MAX_VALUE));
bindConstant().annotatedWith(BFTSyncPatienceMillis.class).to(50);
bindConstant().annotatedWith(PacemakerTimeout.class).to(10L);
bindConstant().annotatedWith(PacemakerRate.class).to(2.0);
bindConstant().annotatedWith(PacemakerMaxExponent.class).to(0);
bind(TimeSupplier.class).toInstance(System::currentTimeMillis);
bind(new TypeLiteral<Consumer<EpochViewUpdate>>() {
}).toInstance(rmock(Consumer.class));
}
@Provides
private ViewUpdate view(BFTConfiguration bftConfiguration) {
HighQC highQC = bftConfiguration.getVertexStoreState().getHighQC();
View view = highQC.highestQC().getView().next();
return ViewUpdate.create(view, highQC, self, self);
}
@Provides
BFTValidatorSet validatorSet() {
return BFTValidatorSet.from(Stream.of(BFTValidator.from(self, UInt256.ONE)));
}
@Provides
@LastProof
LedgerProof verifiedLedgerHeaderAndProof(BFTValidatorSet validatorSet) {
var accumulatorState = new AccumulatorState(0, HashUtils.zero256());
return LedgerProof.genesis(accumulatorState, validatorSet, 0);
}
@Provides
@LastEpochProof
LedgerProof lastEpochProof(BFTValidatorSet validatorSet) {
var accumulatorState = new AccumulatorState(0, HashUtils.zero256());
return LedgerProof.genesis(accumulatorState, validatorSet, 0);
}
@Provides
BFTConfiguration bftConfiguration(@Self BFTNode self, Hasher hasher, BFTValidatorSet validatorSet) {
var accumulatorState = new AccumulatorState(0, HashUtils.zero256());
var unverifiedVertex = UnverifiedVertex.createGenesis(LedgerHeader.genesis(accumulatorState, validatorSet, 0));
var verifiedVertex = new VerifiedVertex(unverifiedVertex, hasher.hash(unverifiedVertex));
var qc = QuorumCertificate.ofGenesis(verifiedVertex, LedgerHeader.genesis(accumulatorState, validatorSet, 0));
var proposerElection = new WeightedRotatingLeaders(validatorSet);
return new BFTConfiguration(proposerElection, validatorSet, VerifiedVertexStoreState.create(HighQC.from(qc), verifiedVertex, Optional.empty(), hasher));
}
};
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class PacemakerTest method when_local_timeout__then_send_empty_vote_if_no_previous.
@Test
public void when_local_timeout__then_send_empty_vote_if_no_previous() {
HighQC viewUpdateHighQc = mock(HighQC.class);
QuorumCertificate committedQc = mock(QuorumCertificate.class);
QuorumCertificate highestQc = mock(QuorumCertificate.class);
when(viewUpdateHighQc.highestCommittedQC()).thenReturn(committedQc);
when(viewUpdateHighQc.highestQC()).thenReturn(highestQc);
BFTHeader highestQcProposed = mock(BFTHeader.class);
HashCode highQcParentVertexId = mock(HashCode.class);
when(highestQcProposed.getVertexId()).thenReturn(highQcParentVertexId);
when(highestQc.getProposed()).thenReturn(highestQcProposed);
when(committedQc.getView()).thenReturn(View.of(0));
ViewUpdate viewUpdate = ViewUpdate.create(View.of(1), viewUpdateHighQc, mock(BFTNode.class), mock(BFTNode.class));
this.pacemaker.processViewUpdate(viewUpdate);
View view = View.of(1);
Vote emptyVote = mock(Vote.class);
Vote emptyVoteWithTimeout = mock(Vote.class);
ImmutableSet<BFTNode> validators = rmock(ImmutableSet.class);
BFTHeader bftHeader = mock(BFTHeader.class);
HighQC highQC = mock(HighQC.class);
BFTInsertUpdate bftInsertUpdate = mock(BFTInsertUpdate.class);
when(bftInsertUpdate.getHeader()).thenReturn(bftHeader);
PreparedVertex preparedVertex = mock(PreparedVertex.class);
when(preparedVertex.getView()).thenReturn(view);
when(preparedVertex.getLedgerHeader()).thenReturn(mock(LedgerHeader.class));
VerifiedVertexStoreState vertexStoreState = mock(VerifiedVertexStoreState.class);
when(vertexStoreState.getHighQC()).thenReturn(highQC);
when(bftInsertUpdate.getInserted()).thenReturn(preparedVertex);
when(bftInsertUpdate.getVertexStoreState()).thenReturn(vertexStoreState);
var node = BFTNode.random();
when(preparedVertex.getId()).thenReturn(hasher.hash(UnverifiedVertex.createTimeout(highestQc, view, node)));
when(this.safetyRules.getLastVote(view)).thenReturn(Optional.empty());
when(this.safetyRules.createVote(any(), any(), anyLong(), any())).thenReturn(emptyVote);
when(this.safetyRules.timeoutVote(emptyVote)).thenReturn(emptyVoteWithTimeout);
when(this.validatorSet.nodes()).thenReturn(validators);
when(this.vertexStore.getPreparedVertex(any())).thenReturn(Optional.empty());
this.pacemaker.processLocalTimeout(ScheduledLocalTimeout.create(ViewUpdate.create(View.of(1), mock(HighQC.class), node, BFTNode.random()), 0L));
this.pacemaker.processBFTUpdate(bftInsertUpdate);
verify(this.voteDispatcher, times(1)).dispatch(eq(validators), eq(emptyVoteWithTimeout));
verify(this.safetyRules, times(1)).getLastVote(view);
verify(this.safetyRules, times(1)).createVote(any(), any(), anyLong(), any());
verify(this.safetyRules, times(1)).timeoutVote(emptyVote);
verifyNoMoreInteractions(this.safetyRules);
verify(this.vertexStore, times(1)).getPreparedVertex(any());
ArgumentCaptor<VerifiedVertex> insertVertexCaptor = ArgumentCaptor.forClass(VerifiedVertex.class);
verify(this.vertexStore, times(1)).insertVertex(insertVertexCaptor.capture());
assertEquals(insertVertexCaptor.getValue().getParentId(), highQcParentVertexId);
verifyNoMoreInteractions(this.vertexStore);
}
use of com.radixdlt.hotstuff.bft.BFTNode in project radixdlt by radixdlt.
the class WeightedRotatingLeadersTest method when_get_proposer_multiple_times__then_should_return_the_same_key.
@Test
public void when_get_proposer_multiple_times__then_should_return_the_same_key() {
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;
BFTNode expectedNodeForView0 = weightedRotatingLeaders.getProposer(View.of(0));
for (View view = View.of(1); view.compareTo(View.of(viewsToTest)) <= 0; view = view.next()) {
weightedRotatingLeaders.getProposer(view);
}
assertThat(weightedRotatingLeaders.getProposer(View.of(0))).isEqualTo(expectedNodeForView0);
}
}
}
Aggregations