Search in sources :

Example 1 with 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 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);
}
Also used : BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) Address(org.hyperledger.besu.datatypes.Address) BftContext(org.hyperledger.besu.consensus.common.bft.BftContext) SubsequentMessageValidator(org.hyperledger.besu.consensus.qbft.validation.MessageValidator.SubsequentMessageValidator) BlockValidator(org.hyperledger.besu.ethereum.BlockValidator) SubsequentMessageValidator(org.hyperledger.besu.consensus.qbft.validation.MessageValidator.SubsequentMessageValidator)

Example 2 with BftBlockInterface

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;
    }
}
Also used : BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) ConsensusRoundIdentifier(org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier) SignedData(org.hyperledger.besu.consensus.common.bft.payload.SignedData) BftContext(org.hyperledger.besu.consensus.common.bft.BftContext) PreparedRoundMetadata(org.hyperledger.besu.consensus.qbft.payload.PreparedRoundMetadata) Block(org.hyperledger.besu.ethereum.core.Block) Hash(org.hyperledger.besu.datatypes.Hash)

Example 3 with BftBlockInterface

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);
}
Also used : BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) BftContext(org.hyperledger.besu.consensus.common.bft.BftContext) ConsensusRoundIdentifier(org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier) ProposerSelector(org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) Collection(java.util.Collection) BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) ProtocolContext(org.hyperledger.besu.ethereum.ProtocolContext) BftHelpers(org.hyperledger.besu.consensus.common.bft.BftHelpers) BftExtraDataCodec(org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec) Address(org.hyperledger.besu.datatypes.Address) BlockValidator(org.hyperledger.besu.ethereum.BlockValidator) Address(org.hyperledger.besu.datatypes.Address) BftContext(org.hyperledger.besu.consensus.common.bft.BftContext)

Example 4 with 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));
}
Also used : BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) BftContext(org.hyperledger.besu.consensus.common.bft.BftContext) ConsensusRoundIdentifier(org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier) ProposerSelector(org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) Collection(java.util.Collection) BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) ProtocolContext(org.hyperledger.besu.ethereum.ProtocolContext) BftHelpers(org.hyperledger.besu.consensus.common.bft.BftHelpers) BftExtraDataCodec(org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec) Address(org.hyperledger.besu.datatypes.Address) BlockValidator(org.hyperledger.besu.ethereum.BlockValidator) Address(org.hyperledger.besu.datatypes.Address) BftContext(org.hyperledger.besu.consensus.common.bft.BftContext) BlockValidator(org.hyperledger.besu.ethereum.BlockValidator)

Example 5 with 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);
}
Also used : AssertionsForClassTypes.assertThatExceptionOfType(org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BftQueryService(org.hyperledger.besu.plugin.services.query.BftQueryService) Mock(org.mockito.Mock) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) RunWith(org.junit.runner.RunWith) Bytes(org.apache.tuweni.bytes.Bytes) Address(org.hyperledger.besu.datatypes.Address) Util(org.hyperledger.besu.ethereum.core.Util) BftBlockHeaderFunctions(org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions) Lists(com.google.common.collect.Lists) BftBlockInterface(org.hyperledger.besu.consensus.common.bft.BftBlockInterface) BftExtraDataCodec(org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec) NoSuchElementException(java.util.NoSuchElementException) Before(org.junit.Before) NonBesuBlockHeader(org.hyperledger.besu.ethereum.core.NonBesuBlockHeader) NodeKeyUtils(org.hyperledger.besu.crypto.NodeKeyUtils) BftExtraData(org.hyperledger.besu.consensus.common.bft.BftExtraData) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) Blockchain(org.hyperledger.besu.ethereum.chain.Blockchain) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) BlockHeaderTestFixture(org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture) Collectors(java.util.stream.Collectors) List(java.util.List) ValidatorProvider(org.hyperledger.besu.consensus.common.validator.ValidatorProvider) Optional(java.util.Optional) MockitoJUnitRunner(org.mockito.junit.MockitoJUnitRunner) NodeKey(org.hyperledger.besu.crypto.NodeKey) Hash(org.hyperledger.besu.datatypes.Hash) Address(org.hyperledger.besu.datatypes.Address) BftQueryService(org.hyperledger.besu.plugin.services.query.BftQueryService) Test(org.junit.Test)

Aggregations

BftBlockInterface (org.hyperledger.besu.consensus.common.bft.BftBlockInterface)14 BftContext (org.hyperledger.besu.consensus.common.bft.BftContext)7 Address (org.hyperledger.besu.datatypes.Address)7 BftExtraDataCodec (org.hyperledger.besu.consensus.common.bft.BftExtraDataCodec)4 ProposerSelector (org.hyperledger.besu.consensus.common.bft.blockcreation.ProposerSelector)4 ValidatorProvider (org.hyperledger.besu.consensus.common.validator.ValidatorProvider)4 ProtocolContext (org.hyperledger.besu.ethereum.ProtocolContext)4 BlockHeader (org.hyperledger.besu.ethereum.core.BlockHeader)4 ProtocolSchedule (org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule)4 BftQueryService (org.hyperledger.besu.plugin.services.query.BftQueryService)4 Test (org.junit.Test)4 NoSuchElementException (java.util.NoSuchElementException)3 EpochManager (org.hyperledger.besu.consensus.common.EpochManager)3 ConsensusRoundIdentifier (org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier)3 Hash (org.hyperledger.besu.datatypes.Hash)3 BlockValidator (org.hyperledger.besu.ethereum.BlockValidator)3 Lists (com.google.common.collect.Lists)2 Collection (java.util.Collection)2 List (java.util.List)2 Optional (java.util.Optional)2