Search in sources :

Example 6 with BFTValidatorSet

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

the class PendingVotesTest method when_submitting_a_duplicate_vote__then_can_be_replaced_if_has_timeout.

@Test
public void when_submitting_a_duplicate_vote__then_can_be_replaced_if_has_timeout() {
    final var vertexId1 = HashUtils.random256();
    final var vertexId2 = HashUtils.random256();
    final var vote1 = makeSignedVoteFor(mock(BFTNode.class), View.genesis(), vertexId1);
    when(vote1.getTimeoutSignature()).thenReturn(Optional.empty());
    when(vote1.isTimeout()).thenReturn(false);
    final var 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);
    // submit duplicate vote, should fail
    assertEquals(VoteProcessingResult.rejected(VoteRejectedReason.DUPLICATE_VOTE), this.pendingVotes.insertVote(vote1, validatorSet));
    // submit again, but this time with a timeout
    when(vote1.getTimeoutSignature()).thenReturn(Optional.of(mock(ECDSASignature.class)));
    when(vote1.isTimeout()).thenReturn(true);
    // should be accepted
    assertEquals(VoteProcessingResult.accepted(), this.pendingVotes.insertVote(vote1, validatorSet));
    // insert another timeout vote
    final var result2 = this.pendingVotes.insertVote(vote2, validatorSet);
    // and form a TC
    assertTrue(result2 instanceof VoteProcessingResult.QuorumReached);
    assertTrue(((VoteProcessingResult.QuorumReached) result2).getViewVotingResult() instanceof ViewVotingResult.FormedTC);
}
Also used : BFTNode(com.radixdlt.consensus.bft.BFTNode) ViewVotingResult(com.radixdlt.consensus.bft.ViewVotingResult) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) VoteProcessingResult(com.radixdlt.consensus.bft.VoteProcessingResult) Test(org.junit.Test)

Example 7 with BFTValidatorSet

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

the class PendingVotesTest method when_voting_again__previous_vote_is_removed.

@Test
public void when_voting_again__previous_vote_is_removed() {
    BFTNode author = mock(BFTNode.class);
    Vote vote = makeSignedVoteFor(author, View.genesis(), HashUtils.random256());
    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.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(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 8 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet 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));
        }
    };
}
Also used : HighQC(com.radixdlt.consensus.HighQC) AccumulatorState(com.radixdlt.ledger.AccumulatorState) LocalSyncRequest(com.radixdlt.sync.messages.local.LocalSyncRequest) BFTCommittedUpdate(com.radixdlt.consensus.bft.BFTCommittedUpdate) VertexRequestTimeout(com.radixdlt.consensus.sync.VertexRequestTimeout) NextTxnsGenerator(com.radixdlt.consensus.liveness.NextTxnsGenerator) BFTInsertUpdate(com.radixdlt.consensus.bft.BFTInsertUpdate) PacemakerMaxExponent(com.radixdlt.consensus.bft.PacemakerMaxExponent) ViewUpdate(com.radixdlt.consensus.bft.ViewUpdate) VerifiedVertex(com.radixdlt.consensus.bft.VerifiedVertex) Consumer(java.util.function.Consumer) ScheduledEventDispatcher(com.radixdlt.environment.ScheduledEventDispatcher) Mempool(com.radixdlt.mempool.Mempool) StateComputer(com.radixdlt.ledger.StateComputerLedger.StateComputer) BFTNode(com.radixdlt.consensus.bft.BFTNode) Vote(com.radixdlt.consensus.Vote) NoVote(com.radixdlt.consensus.bft.NoVote) GetVerticesResponse(com.radixdlt.consensus.sync.GetVerticesResponse) HashSigner(com.radixdlt.consensus.HashSigner) RemoteEventDispatcher(com.radixdlt.environment.RemoteEventDispatcher) Hasher(com.radixdlt.crypto.Hasher) NoVote(com.radixdlt.consensus.bft.NoVote) Proposal(com.radixdlt.consensus.Proposal) LedgerStatusUpdate(com.radixdlt.sync.messages.remote.LedgerStatusUpdate) WeightedRotatingLeaders(com.radixdlt.consensus.liveness.WeightedRotatingLeaders) LedgerUpdate(com.radixdlt.ledger.LedgerUpdate) GetVerticesRequest(com.radixdlt.consensus.sync.GetVerticesRequest) LocalTimeoutOccurrence(com.radixdlt.consensus.liveness.LocalTimeoutOccurrence) EpochLocalTimeoutOccurrence(com.radixdlt.consensus.liveness.EpochLocalTimeoutOccurrence) Self(com.radixdlt.consensus.bft.Self) TimeSupplier(com.radixdlt.utils.TimeSupplier) PersistentVertexStore(com.radixdlt.consensus.bft.PersistentVertexStore) EpochLocalTimeoutOccurrence(com.radixdlt.consensus.liveness.EpochLocalTimeoutOccurrence) PacemakerRate(com.radixdlt.consensus.bft.PacemakerRate) RemoteEventDispatcher(com.radixdlt.environment.RemoteEventDispatcher) ScheduledEventDispatcher(com.radixdlt.environment.ScheduledEventDispatcher) EventDispatcher(com.radixdlt.environment.EventDispatcher) TypeLiteral(com.google.inject.TypeLiteral) BFTSyncPatienceMillis(com.radixdlt.consensus.sync.BFTSyncPatienceMillis) BFTRebuildUpdate(com.radixdlt.consensus.bft.BFTRebuildUpdate) GetVerticesErrorResponse(com.radixdlt.consensus.sync.GetVerticesErrorResponse) SystemCounters(com.radixdlt.counters.SystemCounters) PacemakerTimeout(com.radixdlt.consensus.bft.PacemakerTimeout) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) View(com.radixdlt.consensus.bft.View) AbstractModule(com.google.inject.AbstractModule) BFTConfiguration(com.radixdlt.consensus.BFTConfiguration) SystemCountersImpl(com.radixdlt.counters.SystemCountersImpl) ViewQuorumReached(com.radixdlt.consensus.bft.ViewQuorumReached) ScheduledLocalTimeout(com.radixdlt.consensus.liveness.ScheduledLocalTimeout) BFTHighQCUpdate(com.radixdlt.consensus.bft.BFTHighQCUpdate) GetVerticesRequestRateLimit(com.radixdlt.middleware2.network.GetVerticesRequestRateLimit) PersistentSafetyStateStore(com.radixdlt.consensus.safety.PersistentSafetyStateStore)

Example 9 with BFTValidatorSet

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

the class WeightedRotatingLeadersTest method setUp.

private void setUp(int validatorSetSize, int sizeOfCache) {
    this.validatorsInOrder = Stream.generate(() -> ECKeyPair.generateNew().getPublicKey()).limit(validatorSetSize).map(BFTNode::create).map(node -> BFTValidator.from(node, UInt256.ONE)).sorted(Comparator.comparing(v -> v.getNode().getKey(), KeyComparator.instance().reversed())).collect(ImmutableList.toImmutableList());
    BFTValidatorSet validatorSet = BFTValidatorSet.from(validatorsInOrder);
    this.weightedRotatingLeaders = new WeightedRotatingLeaders(validatorSet, sizeOfCache);
    this.weightedRotatingLeaders2 = new WeightedRotatingLeaders(validatorSet, sizeOfCache);
}
Also used : IntStream(java.util.stream.IntStream) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Collectors.counting(java.util.stream.Collectors.counting) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) Test(org.junit.Test) Collectors.collectingAndThen(java.util.stream.Collectors.collectingAndThen) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) Supplier(java.util.function.Supplier) BFTValidator(com.radixdlt.consensus.bft.BFTValidator) ECKeyPair(com.radixdlt.crypto.ECKeyPair) Stream(java.util.stream.Stream) Collectors.toMap(java.util.stream.Collectors.toMap) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) BFTNode(com.radixdlt.consensus.bft.BFTNode) KeyComparator(com.radixdlt.utils.KeyComparator) Comparator(java.util.Comparator) View(com.radixdlt.consensus.bft.View) UInt256(com.radixdlt.utils.UInt256) BFTNode(com.radixdlt.consensus.bft.BFTNode) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet)

Example 10 with BFTValidatorSet

use of com.radixdlt.consensus.bft.BFTValidatorSet 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);
}
Also used : IntStream(java.util.stream.IntStream) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Collectors.counting(java.util.stream.Collectors.counting) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) Test(org.junit.Test) Collectors.collectingAndThen(java.util.stream.Collectors.collectingAndThen) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) Supplier(java.util.function.Supplier) BFTValidator(com.radixdlt.consensus.bft.BFTValidator) ECKeyPair(com.radixdlt.crypto.ECKeyPair) Stream(java.util.stream.Stream) Collectors.toMap(java.util.stream.Collectors.toMap) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) BFTNode(com.radixdlt.consensus.bft.BFTNode) KeyComparator(com.radixdlt.utils.KeyComparator) Comparator(java.util.Comparator) View(com.radixdlt.consensus.bft.View) UInt256(com.radixdlt.utils.UInt256) BFTNode(com.radixdlt.consensus.bft.BFTNode) BFTValidatorSet(com.radixdlt.consensus.bft.BFTValidatorSet) IntStream(java.util.stream.IntStream) UInt256(com.radixdlt.utils.UInt256) Test(org.junit.Test)

Aggregations

BFTNode (com.radixdlt.consensus.bft.BFTNode)10 BFTValidatorSet (com.radixdlt.consensus.bft.BFTValidatorSet)10 Test (org.junit.Test)9 BFTValidator (com.radixdlt.consensus.bft.BFTValidator)3 ValidationState (com.radixdlt.consensus.bft.ValidationState)3 View (com.radixdlt.consensus.bft.View)3 ImmutableList (com.google.common.collect.ImmutableList)2 HashCode (com.google.common.hash.HashCode)2 AbstractModule (com.google.inject.AbstractModule)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 NoVote (com.radixdlt.consensus.bft.NoVote)2