use of com.radixdlt.consensus.bft.BFTNode in project radixdlt by radixdlt.
the class PacemakerState method updateView.
@Override
public void updateView(View nextView) {
if (nextView.lte(this.currentView)) {
return;
}
final BFTNode leader = this.proposerElection.getProposer(nextView);
final BFTNode nextLeader = this.proposerElection.getProposer(nextView.next());
this.currentView = nextView;
viewUpdateSender.dispatch(ViewUpdate.create(this.currentView, this.highQC, leader, nextLeader));
}
use of com.radixdlt.consensus.bft.BFTNode in project radixdlt by radixdlt.
the class LedgerInOrderInvariant method check.
@Override
public Observable<TestInvariantError> check(RunningNetwork network) {
Map<BFTNode, List<Txn>> commandsPerNode = new HashMap<>();
network.getNodes().forEach(n -> commandsPerNode.put(n, new ArrayList<>()));
return network.ledgerUpdates().flatMap(nodeAndCommand -> {
BFTNode node = nodeAndCommand.getFirst();
LedgerUpdate ledgerUpdate = nodeAndCommand.getSecond();
List<Txn> nodeTxns = commandsPerNode.get(node);
nodeTxns.addAll(ledgerUpdate.getNewTxns());
return commandsPerNode.values().stream().filter(list -> nodeTxns != list).filter(list -> list.size() >= nodeTxns.size()).findFirst().flatMap(list -> {
if (Collections.indexOfSubList(list, nodeTxns) != 0) {
TestInvariantError err = new TestInvariantError("Two nodes don't agree on commands: " + list + " " + nodeTxns);
return Optional.of(Observable.just(err));
}
return Optional.empty();
}).orElse(Observable.empty());
});
}
use of com.radixdlt.consensus.bft.BFTNode in project radixdlt by radixdlt.
the class SimulationNodes method createBFTInstance.
private Injector createBFTInstance(ECKeyPair self) {
Module module = Modules.combine(new AbstractModule() {
@Provides
@Self
private BFTNode self() {
return BFTNode.create(self.getPublicKey());
}
@Provides
@Self
private ECPublicKey key() {
return self.getPublicKey();
}
@Provides
@LocalSigner
HashSigner hashSigner() {
return self::sign;
}
}, new NodeNetworkMessagesModule(underlyingNetwork), baseModule);
// can break network behavior if incorrect modules are used
if (overrideModule != null) {
module = Modules.override(module).with(overrideModule);
}
Module byzantineModule = byzantineNodeModules.get(self);
if (byzantineModule != null) {
module = Modules.override(module).with(byzantineModule);
}
return Guice.createInjector(module);
}
use of com.radixdlt.consensus.bft.BFTNode in project radixdlt by radixdlt.
the class PendingVotes method processVoteForTC.
private Optional<TimeoutCertificate> processVoteForTC(Vote vote, BFTValidatorSet validatorSet) {
if (!vote.isTimeout()) {
// TC can't be formed if vote is not timed out
return Optional.empty();
}
final ECDSASignature timeoutSignature = vote.getTimeoutSignature().orElseThrow();
final VoteTimeout voteTimeout = VoteTimeout.of(vote);
final HashCode voteTimeoutHash = this.hasher.hash(voteTimeout);
final BFTNode node = vote.getAuthor();
final ValidationState validationState = this.timeoutVoteState.computeIfAbsent(voteTimeoutHash, k -> validatorSet.newValidationState());
final boolean signatureAdded = validationState.addSignature(node, vote.getTimestamp(), timeoutSignature);
if (signatureAdded && validationState.complete()) {
return Optional.of(new TimeoutCertificate(voteTimeout.getEpoch(), voteTimeout.getView(), validationState.signatures()));
} else {
return Optional.empty();
}
}
use of com.radixdlt.consensus.bft.BFTNode in project radixdlt by radixdlt.
the class PendingVotes method insertVote.
/**
* Inserts a vote for a given vertex, attempting to form either a quorum certificate for that
* vertex or a timeout certificate. A quorum will only be formed if permitted by the {@link
* BFTValidatorSet}.
*
* @param vote The vote to be inserted
* @return The result of vote processing
*/
public VoteProcessingResult insertVote(Vote vote, BFTValidatorSet validatorSet) {
final BFTNode node = vote.getAuthor();
final VoteData voteData = vote.getVoteData();
final HashCode voteDataHash = this.hasher.hash(voteData);
if (!validatorSet.containsNode(node)) {
return VoteProcessingResult.rejected(VoteRejectedReason.INVALID_AUTHOR);
}
if (!replacePreviousVote(node, vote, voteDataHash)) {
return VoteProcessingResult.rejected(VoteRejectedReason.DUPLICATE_VOTE);
}
return processVoteForQC(vote, validatorSet).<VoteProcessingResult>map(VoteProcessingResult::qcQuorum).or(() -> processVoteForTC(vote, validatorSet).map(VoteProcessingResult::tcQuorum)).orElseGet(VoteProcessingResult::accepted);
}
Aggregations