Search in sources :

Example 1 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet in project radixdlt by radixdlt.

the class PendingVotesTest method when_voting_again__previous_timeoutvote_is_removed.

@Test
public void when_voting_again__previous_timeoutvote_is_removed() {
    BFTNode author = mock(BFTNode.class);
    Vote vote = makeSignedVoteFor(author, View.genesis(), HashUtils.random256());
    when(vote.getTimeoutSignature()).thenReturn(Optional.of(mock(ECDSASignature.class)));
    when(vote.isTimeout()).thenReturn(true);
    BFTValidatorSet validatorSet = mock(BFTValidatorSet.class);
    ValidationState validationState = mock(ValidationState.class);
    TimestampedECDSASignatures signatures = mock(TimestampedECDSASignatures.class);
    when(validationState.signatures()).thenReturn(signatures);
    when(validationState.isEmpty()).thenReturn(true);
    when(validatorSet.newValidationState()).thenReturn(validationState);
    when(validatorSet.containsNode(any())).thenReturn(true);
    VoteData voteData = mock(VoteData.class);
    BFTHeader proposed = vote.getVoteData().getProposed();
    when(voteData.getProposed()).thenReturn(proposed);
    // Preconditions
    assertEquals(VoteProcessingResult.accepted(), this.pendingVotes.insertVote(vote, validatorSet));
    assertEquals(1, this.pendingVotes.voteStateSize());
    assertEquals(1, this.pendingVotes.timeoutVoteStateSize());
    assertEquals(1, this.pendingVotes.previousVotesSize());
    Vote vote2 = makeSignedVoteFor(author, View.of(1), HashUtils.random256());
    // Need a different hash for this (different) vote
    assertEquals(VoteProcessingResult.accepted(), this.pendingVotes.insertVote(vote2, validatorSet));
    assertEquals(1, this.pendingVotes.voteStateSize());
    assertEquals(0, this.pendingVotes.timeoutVoteStateSize());
    assertEquals(1, this.pendingVotes.previousVotesSize());
}
Also used : BFTNode(com.radixdlt.consensus.bft.BFTNode) ValidationState(com.radixdlt.consensus.bft.ValidationState) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) Test(org.junit.Test)

Example 2 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet in project radixdlt by radixdlt.

the class PendingVotesTest method when_inserting_valid_timeout_votes__then_tc_is_formed.

@Test
public void when_inserting_valid_timeout_votes__then_tc_is_formed() {
    HashCode vertexId1 = HashUtils.random256();
    HashCode vertexId2 = HashUtils.random256();
    Vote vote1 = makeSignedVoteFor(mock(BFTNode.class), View.genesis(), vertexId1);
    when(vote1.getTimeoutSignature()).thenReturn(Optional.of(mock(ECDSASignature.class)));
    when(vote1.isTimeout()).thenReturn(true);
    Vote vote2 = makeSignedVoteFor(mock(BFTNode.class), View.genesis(), vertexId2);
    when(vote2.getTimeoutSignature()).thenReturn(Optional.of(mock(ECDSASignature.class)));
    when(vote2.isTimeout()).thenReturn(true);
    BFTValidatorSet validatorSet = BFTValidatorSet.from(Arrays.asList(BFTValidator.from(vote1.getAuthor(), UInt256.ONE), BFTValidator.from(vote2.getAuthor(), UInt256.ONE)));
    assertTrue(this.pendingVotes.insertVote(vote1, validatorSet) instanceof VoteProcessingResult.VoteAccepted);
    VoteProcessingResult result2 = this.pendingVotes.insertVote(vote2, validatorSet);
    assertTrue(result2 instanceof VoteProcessingResult.QuorumReached);
    assertTrue(((VoteProcessingResult.QuorumReached) result2).getViewVotingResult() instanceof ViewVotingResult.FormedTC);
}
Also used : BFTNode(com.radixdlt.consensus.bft.BFTNode) HashCode(com.google.common.hash.HashCode) ViewVotingResult(com.radixdlt.consensus.bft.ViewVotingResult) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) VoteProcessingResult(com.radixdlt.consensus.bft.VoteProcessingResult) Test(org.junit.Test)

Example 3 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet in project radixdlt by radixdlt.

the class PendingVotesTest method when_inserting_valid_but_unaccepted_votes__then_no_qc_is_returned.

@Test
public void when_inserting_valid_but_unaccepted_votes__then_no_qc_is_returned() {
    HashCode vertexId = HashUtils.random256();
    Vote vote1 = makeSignedVoteFor(mock(BFTNode.class), View.genesis(), vertexId);
    Vote vote2 = makeSignedVoteFor(mock(BFTNode.class), View.genesis(), vertexId);
    BFTValidatorSet validatorSet = BFTValidatorSet.from(Collections.singleton(BFTValidator.from(vote1.getAuthor(), UInt256.ONE)));
    VoteData voteData = mock(VoteData.class);
    BFTHeader proposed = vote1.getVoteData().getProposed();
    when(voteData.getProposed()).thenReturn(proposed);
    assertEquals(VoteProcessingResult.rejected(VoteRejectedReason.INVALID_AUTHOR), this.pendingVotes.insertVote(vote2, validatorSet));
}
Also used : BFTNode(com.radixdlt.consensus.bft.BFTNode) HashCode(com.google.common.hash.HashCode) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) Test(org.junit.Test)

Example 4 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet in project radixdlt by radixdlt.

the class EpochManagerTest method should_not_send_consensus_messages_if_not_part_of_new_epoch.

@Test
public void should_not_send_consensus_messages_if_not_part_of_new_epoch() {
    // Arrange
    epochManager.start();
    BFTValidatorSet nextValidatorSet = BFTValidatorSet.from(Stream.of(BFTValidator.from(BFTNode.random(), UInt256.ONE)));
    var accumulatorState = new AccumulatorState(0, HashUtils.zero256());
    LedgerHeader header = LedgerHeader.genesis(accumulatorState, nextValidatorSet, 0);
    UnverifiedVertex genesisVertex = UnverifiedVertex.createGenesis(header);
    VerifiedVertex verifiedGenesisVertex = new VerifiedVertex(genesisVertex, hasher.hash(genesisVertex));
    LedgerHeader nextLedgerHeader = LedgerHeader.create(header.getEpoch() + 1, View.genesis(), header.getAccumulatorState(), header.timestamp());
    var genesisQC = QuorumCertificate.ofGenesis(verifiedGenesisVertex, nextLedgerHeader);
    var proposerElection = new WeightedRotatingLeaders(nextValidatorSet);
    var bftConfiguration = new BFTConfiguration(proposerElection, nextValidatorSet, VerifiedVertexStoreState.create(HighQC.from(genesisQC), verifiedGenesisVertex, Optional.empty(), hasher));
    LedgerProof proof = mock(LedgerProof.class);
    when(proof.getEpoch()).thenReturn(header.getEpoch() + 1);
    var epochChange = new EpochChange(proof, bftConfiguration);
    var ledgerUpdate = new LedgerUpdate(mock(VerifiedTxnsAndProof.class), ImmutableClassToInstanceMap.of(EpochChange.class, epochChange));
    // Act
    epochManager.epochsLedgerUpdateEventProcessor().process(ledgerUpdate);
    // Assert
    verify(proposalDispatcher, never()).dispatch(any(Iterable.class), argThat(p -> p.getEpoch() == epochChange.getEpoch()));
    verify(voteDispatcher, never()).dispatch(any(BFTNode.class), any());
}
Also used : LedgerUpdate(com.radixdlt.ledger.LedgerUpdate) Module(com.google.inject.Module) ScheduledLocalTimeout(com.radixdlt.consensus.liveness.ScheduledLocalTimeout) GetVerticesRequest(com.radixdlt.consensus.sync.GetVerticesRequest) EpochsConsensusModule(com.radixdlt.EpochsConsensusModule) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) Inject(com.google.inject.Inject) PacemakerTimeout(com.radixdlt.consensus.bft.PacemakerTimeout) Hasher(com.radixdlt.crypto.Hasher) HashSigner(com.radixdlt.consensus.HashSigner) BFTCommittedUpdate(com.radixdlt.consensus.bft.BFTCommittedUpdate) MempoolAdd(com.radixdlt.mempool.MempoolAdd) RemoteEventDispatcher(com.radixdlt.environment.RemoteEventDispatcher) VertexRequestTimeout(com.radixdlt.consensus.sync.VertexRequestTimeout) UnverifiedVertex(com.radixdlt.consensus.UnverifiedVertex) VerifiedTxnsAndProof(com.radixdlt.ledger.VerifiedTxnsAndProof) Map(java.util.Map) ViewQuorumReached(com.radixdlt.consensus.bft.ViewQuorumReached) LedgerProof(com.radixdlt.consensus.LedgerProof) View(com.radixdlt.consensus.bft.View) HashUtils(com.radixdlt.crypto.HashUtils) SystemCounters(com.radixdlt.counters.SystemCounters) LedgerModule(com.radixdlt.LedgerModule) WeightedRotatingLeaders(com.radixdlt.consensus.liveness.WeightedRotatingLeaders) PersistentSafetyStateStore(com.radixdlt.consensus.safety.PersistentSafetyStateStore) StateComputerResult(com.radixdlt.ledger.StateComputerLedger.StateComputerResult) StateComputer(com.radixdlt.ledger.StateComputerLedger.StateComputer) GetVerticesRequestRateLimit(com.radixdlt.middleware2.network.GetVerticesRequestRateLimit) BFTRebuildUpdate(com.radixdlt.consensus.bft.BFTRebuildUpdate) LedgerHeader(com.radixdlt.consensus.LedgerHeader) SystemCountersImpl(com.radixdlt.counters.SystemCountersImpl) List(java.util.List) Stream(java.util.stream.Stream) BFTHighQCUpdate(com.radixdlt.consensus.bft.BFTHighQCUpdate) PacemakerMaxExponent(com.radixdlt.consensus.bft.PacemakerMaxExponent) Optional(java.util.Optional) ImmutableClassToInstanceMap(com.google.common.collect.ImmutableClassToInstanceMap) TypeLiteral(com.google.inject.TypeLiteral) BFTSyncPatienceMillis(com.radixdlt.consensus.sync.BFTSyncPatienceMillis) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) HighQC(com.radixdlt.consensus.HighQC) ScheduledEventDispatcher(com.radixdlt.environment.ScheduledEventDispatcher) Proposal(com.radixdlt.consensus.Proposal) LocalTimeoutOccurrence(com.radixdlt.consensus.liveness.LocalTimeoutOccurrence) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) NextTxnsGenerator(com.radixdlt.consensus.liveness.NextTxnsGenerator) PreparedTxn(com.radixdlt.ledger.StateComputerLedger.PreparedTxn) RateLimiter(com.google.common.util.concurrent.RateLimiter) TypedMocks.rmock(com.radixdlt.utils.TypedMocks.rmock) LocalSyncRequest(com.radixdlt.sync.messages.local.LocalSyncRequest) LedgerStatusUpdate(com.radixdlt.sync.messages.remote.LedgerStatusUpdate) BFTValidator(com.radixdlt.consensus.bft.BFTValidator) CryptoModule(com.radixdlt.CryptoModule) Vote(com.radixdlt.consensus.Vote) LastEpochProof(com.radixdlt.store.LastEpochProof) BFTConfiguration(com.radixdlt.consensus.BFTConfiguration) ViewUpdate(com.radixdlt.consensus.bft.ViewUpdate) AccumulatorState(com.radixdlt.ledger.AccumulatorState) UInt256(com.radixdlt.utils.UInt256) Nullable(javax.annotation.Nullable) Before(org.junit.Before) TimeSupplier(com.radixdlt.utils.TimeSupplier) EventDispatcher(com.radixdlt.environment.EventDispatcher) ConsensusModule(com.radixdlt.ConsensusModule) Txn(com.radixdlt.atom.Txn) BFTInsertUpdate(com.radixdlt.consensus.bft.BFTInsertUpdate) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) VerifiedVertexStoreState(com.radixdlt.consensus.bft.VerifiedVertexStoreState) QuorumCertificate(com.radixdlt.consensus.QuorumCertificate) Mockito.verify(org.mockito.Mockito.verify) LedgerUpdate(com.radixdlt.ledger.LedgerUpdate) Consumer(java.util.function.Consumer) Mockito.never(org.mockito.Mockito.never) Provides(com.google.inject.Provides) VerifiedVertex(com.radixdlt.consensus.bft.VerifiedVertex) ECKeyPair(com.radixdlt.crypto.ECKeyPair) NoVote(com.radixdlt.consensus.bft.NoVote) PacemakerRate(com.radixdlt.consensus.bft.PacemakerRate) Self(com.radixdlt.consensus.bft.Self) Guice(com.google.inject.Guice) BFTNode(com.radixdlt.consensus.bft.BFTNode) PersistentVertexStore(com.radixdlt.consensus.bft.PersistentVertexStore) EpochLocalTimeoutOccurrence(com.radixdlt.consensus.liveness.EpochLocalTimeoutOccurrence) Mempool(com.radixdlt.mempool.Mempool) LastProof(com.radixdlt.store.LastProof) GetVerticesErrorResponse(com.radixdlt.consensus.sync.GetVerticesErrorResponse) GetVerticesResponse(com.radixdlt.consensus.sync.GetVerticesResponse) AbstractModule(com.google.inject.AbstractModule) BFTNode(com.radixdlt.consensus.bft.BFTNode) AccumulatorState(com.radixdlt.ledger.AccumulatorState) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) UnverifiedVertex(com.radixdlt.consensus.UnverifiedVertex) VerifiedVertex(com.radixdlt.consensus.bft.VerifiedVertex) LedgerHeader(com.radixdlt.consensus.LedgerHeader) BFTConfiguration(com.radixdlt.consensus.BFTConfiguration) VerifiedTxnsAndProof(com.radixdlt.ledger.VerifiedTxnsAndProof) LedgerProof(com.radixdlt.consensus.LedgerProof) WeightedRotatingLeaders(com.radixdlt.consensus.liveness.WeightedRotatingLeaders) Test(org.junit.Test)

Example 5 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet in project radixdlt by radixdlt.

the class PacemakerViewUpdateRaceConditionTest method test_pacemaker_view_update_race_condition.

@Test
public void test_pacemaker_view_update_race_condition() {
    final DeterministicTest test = DeterministicTest.builder().numNodes(numNodes).messageSelector(MessageSelector.randomSelector(random)).messageMutator(messUpMessagesForNodeUnderTest()).pacemakerTimeout(pacemakerTimeout).overrideWithIncorrectModule(new AbstractModule() {

        @ProvidesIntoSet
        @ProcessOnDispatch
        private EventProcessor<BFTInsertUpdate> bftInsertUpdateProcessor() {
            final Map<HashCode, PreparedVertex> insertedVertices = new HashMap<>();
            return bftInsertUpdate -> {
                final PreparedVertex inserted = bftInsertUpdate.getInserted();
                insertedVertices.putIfAbsent(inserted.getId(), inserted);
                final Optional<PreparedVertex> maybeParent = Optional.ofNullable(insertedVertices.get(inserted.getParentId()));
                maybeParent.ifPresent(parent -> {
                    if (parent.getView().equals(inserted.getView())) {
                        throw new IllegalStateException("Vertex can't have the same view as its parent.");
                    }
                });
            };
        }

        @Provides
        public ProposerElection proposerElection(BFTValidatorSet validatorSet) {
            final var sortedValidators = validatorSet.getValidators().stream().map(BFTValidator::getNode).sorted(Comparator.comparing(BFTNode::getKey, KeyComparator.instance().reversed())).toList();
            return view -> sortedValidators.get(((int) view.number() - 1) % sortedValidators.size());
        }
    }).buildWithoutEpochs().runUntil(nodeUnderTestReachesView(View.of(3)));
    final var counters = test.getSystemCounters(nodeUnderTestIndex);
    assertThat(counters.get(SystemCounters.CounterType.BFT_VOTE_QUORUMS)).isEqualTo(// ensure that quorum was formed
    2);
    assertThat(counters.get(SystemCounters.CounterType.BFT_PACEMAKER_TIMEOUTS_SENT)).isEqualTo(// ensure that timeouts were processed
    2);
}
Also used : PreparedVertex(com.radixdlt.consensus.bft.PreparedVertex) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest) Provides(com.google.inject.Provides) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) ProvidesIntoSet(com.google.inject.multibindings.ProvidesIntoSet) AbstractModule(com.google.inject.AbstractModule) EventProcessor(com.radixdlt.environment.EventProcessor) ProcessOnDispatch(com.radixdlt.environment.ProcessOnDispatch) HashMap(java.util.HashMap) Map(java.util.Map) ProposerElection(com.radixdlt.consensus.liveness.ProposerElection) Test(org.junit.Test) DeterministicTest(com.radixdlt.harness.deterministic.DeterministicTest)

Aggregations

BFTValidatorSet (com.radixdlt.consensus.bft.BFTValidatorSet)11 BFTNode (com.radixdlt.consensus.bft.BFTNode)10 Test (org.junit.Test)10 Map (java.util.Map)4 AbstractModule (com.google.inject.AbstractModule)3 BFTValidator (com.radixdlt.consensus.bft.BFTValidator)3 View (com.radixdlt.consensus.bft.View)3 ImmutableList (com.google.common.collect.ImmutableList)2 HashCode (com.google.common.hash.HashCode)2 Provides (com.google.inject.Provides)2 TypeLiteral (com.google.inject.TypeLiteral)2 BFTConfiguration (com.radixdlt.consensus.BFTConfiguration)2 HashSigner (com.radixdlt.consensus.HashSigner)2 HighQC (com.radixdlt.consensus.HighQC)2 Proposal (com.radixdlt.consensus.Proposal)2 Vote (com.radixdlt.consensus.Vote)2 BFTCommittedUpdate (com.radixdlt.consensus.bft.BFTCommittedUpdate)2 BFTHighQCUpdate (com.radixdlt.consensus.bft.BFTHighQCUpdate)2 BFTInsertUpdate (com.radixdlt.consensus.bft.BFTInsertUpdate)2 BFTRebuildUpdate (com.radixdlt.consensus.bft.BFTRebuildUpdate)2