use of org.hyperledger.besu.consensus.common.bft.BftBlockInterface in project besu by hyperledger.
the class MessageValidatorFactory method createMessageValidator.
public MessageValidator createMessageValidator(final ConsensusRoundIdentifier roundIdentifier, final BlockHeader parentHeader) {
final Collection<Address> validatorsForHeight = getValidatorsAfterBlock(parentHeader);
final BlockValidator blockValidator = protocolSchedule.getByBlockNumber(roundIdentifier.getSequenceNumber()).getBlockValidator();
final ProposalValidator proposalValidator = new ProposalValidator(blockValidator, protocolContext, BftHelpers.calculateRequiredValidatorQuorum(validatorsForHeight.size()), validatorsForHeight, roundIdentifier, proposerSelector.selectProposerForRound(roundIdentifier), bftExtraDataCodec);
final BftBlockInterface blockInterface = protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return new MessageValidator(block -> new SubsequentMessageValidator(validatorsForHeight, roundIdentifier, block, blockInterface, bftExtraDataCodec), proposalValidator);
}
use of org.hyperledger.besu.consensus.common.bft.BftBlockInterface in project besu by hyperledger.
the class ProposalValidator method validateProposalAndRoundChangeAreConsistent.
private boolean validateProposalAndRoundChangeAreConsistent(final Proposal proposal) {
final ConsensusRoundIdentifier proposalRoundIdentifier = proposal.getRoundIdentifier();
if (proposalRoundIdentifier.getRoundNumber() == 0) {
if (!validateRoundZeroProposalHasNoRoundChangesOrPrepares(proposal)) {
return false;
}
return validateBlockCoinbaseMatchesMsgAuthor(proposal);
} else {
if (!validateRoundChanges(proposal, proposal.getRoundChanges())) {
LOG.info("{}: failed to validate piggy-backed round change payloads", ERROR_PREFIX);
return false;
}
// The RoundChangePayloadValidator ensures the PreparedRound is less than targetRound
// therefore, no need to validate that here.
final Optional<SignedData<RoundChangePayload>> roundChangeWithLatestPreparedRound = getRoundChangeWithLatestPreparedRound(proposal.getRoundChanges());
if (roundChangeWithLatestPreparedRound.isPresent()) {
final PreparedRoundMetadata metadata = roundChangeWithLatestPreparedRound.get().getPayload().getPreparedRoundMetadata().get();
// The Hash in the roundchange/proposals is NOT the same as the value in the
// prepares/roundchanges
// as said payloads reference the block with an OLD round number in it - therefore, need
// to create a block with the old round in it, then re-calc expected hash
// Need to check that if we substitute the LatestPrepareCert round number into the supplied
// block that we get the SAME hash as PreparedCert.
final BftBlockInterface bftBlockInterface = protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
final Block currentBlockWithOldRound = bftBlockInterface.replaceRoundInBlock(proposal.getBlock(), metadata.getPreparedRound(), BftBlockHeaderFunctions.forCommittedSeal(bftExtraDataCodec));
final Hash expectedPriorBlockHash = currentBlockWithOldRound.getHash();
if (!metadata.getPreparedBlockHash().equals(expectedPriorBlockHash)) {
LOG.info("{}: Latest Prepared Metadata blockhash does not align with proposed block", ERROR_PREFIX);
return false;
}
// validate the prepares
if (!validatePrepares(metadata, proposal.getRoundIdentifier().getSequenceNumber(), proposal.getPrepares())) {
LOG.info("{}: Piggy-backed prepares failed validation", ERROR_PREFIX);
return false;
}
} else {
// no one prepared, so prepares should be empty
if (!proposal.getPrepares().isEmpty()) {
LOG.info("{}: No PreparedMetadata exists, so prepare list must be empty", ERROR_PREFIX);
return false;
}
return validateBlockCoinbaseMatchesMsgAuthor(proposal);
}
return true;
}
}
use of org.hyperledger.besu.consensus.common.bft.BftBlockInterface in project besu by hyperledger.
the class MessageValidatorFactory method createRoundChangeMessageValidator.
public RoundChangeMessageValidator createRoundChangeMessageValidator(final long chainHeight, final BlockHeader parentHeader) {
final Collection<Address> validators = getValidatorsAfterBlock(parentHeader);
final BftBlockInterface bftBlockInterface = protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return new RoundChangeMessageValidator(new RoundChangePayloadValidator((roundIdentifier) -> createSignedDataValidator(roundIdentifier, parentHeader), validators, BftHelpers.prepareMessageCountForQuorum(BftHelpers.calculateRequiredValidatorQuorum(validators.size())), chainHeight), new ProposalBlockConsistencyValidator(), bftBlockInterface);
}
use of org.hyperledger.besu.consensus.common.bft.BftBlockInterface in project besu by hyperledger.
the class MessageValidatorFactory method createMessageValidator.
public MessageValidator createMessageValidator(final ConsensusRoundIdentifier roundIdentifier, final BlockHeader parentHeader) {
final BlockValidator blockValidator = protocolSchedule.getByBlockNumber(roundIdentifier.getSequenceNumber()).getBlockValidator();
final Collection<Address> validators = getValidatorsAfterBlock(parentHeader);
final BftBlockInterface bftBlockInterface = protocolContext.getConsensusContext(BftContext.class).getBlockInterface();
return new MessageValidator(createSignedDataValidator(roundIdentifier, parentHeader), new ProposalBlockConsistencyValidator(), blockValidator, protocolContext, new RoundChangeCertificateValidator(validators, (ri) -> createSignedDataValidator(ri, parentHeader), roundIdentifier.getSequenceNumber(), bftExtraDataCodec, bftBlockInterface));
}
use of org.hyperledger.besu.consensus.common.bft.BftBlockInterface in project besu by hyperledger.
the class BftQueryServiceImplTest method getSignersReturnsAddressesOfSignersInBlock.
@Test
public void getSignersReturnsAddressesOfSignersInBlock() {
final BftQueryService service = new BftQueryServiceImpl(bftBlockInterface, blockchain, validatorProvider, null, null);
final List<Address> signers = signingKeys.stream().map(nodeKey -> Util.publicKeyToAddress(nodeKey.getPublicKey())).collect(Collectors.toList());
when(bftBlockInterface.getCommitters(any())).thenReturn(signers);
assertThat(service.getSignersFrom(blockHeader)).containsExactlyElementsOf(signers);
}
Aggregations