Search in sources :

Example 11 with Block

use of org.hyperledger.besu.ethereum.core.Block 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 12 with Block

use of org.hyperledger.besu.ethereum.core.Block in project besu by hyperledger.

the class QbftRound method startRoundWith.

public void startRoundWith(final RoundChangeArtifacts roundChangeArtifacts, final long headerTimestamp) {
    final Optional<PreparedCertificate> bestPreparedCertificate = roundChangeArtifacts.getBestPreparedPeer();
    Block blockToPublish;
    if (bestPreparedCertificate.isEmpty()) {
        LOG.debug("Sending proposal with new block. round={}", roundState.getRoundIdentifier());
        blockToPublish = blockCreator.createBlock(headerTimestamp);
    } else {
        LOG.debug("Sending proposal from PreparedCertificate. round={}", roundState.getRoundIdentifier());
        blockToPublish = bestPreparedCertificate.get().getBlock();
    }
    updateStateWithProposalAndTransmit(blockToPublish, roundChangeArtifacts.getRoundChanges(), bestPreparedCertificate.map(PreparedCertificate::getPrepares).orElse(emptyList()));
}
Also used : Block(org.hyperledger.besu.ethereum.core.Block)

Example 13 with Block

use of org.hyperledger.besu.ethereum.core.Block in project besu by hyperledger.

the class QbftRound method handleProposalMessage.

public void handleProposalMessage(final Proposal msg) {
    LOG.debug("Received a proposal message. round={}. author={}", roundState.getRoundIdentifier(), msg.getAuthor());
    final Block block = msg.getSignedPayload().getPayload().getProposedBlock();
    if (updateStateWithProposedBlock(msg)) {
        sendPrepare(block);
    }
}
Also used : Block(org.hyperledger.besu.ethereum.core.Block)

Example 14 with Block

use of org.hyperledger.besu.ethereum.core.Block in project besu by hyperledger.

the class QbftRound method peerIsPrepared.

private void peerIsPrepared(final Prepare msg) {
    final boolean wasPrepared = roundState.isPrepared();
    roundState.addPrepareMessage(msg);
    if (wasPrepared != roundState.isPrepared()) {
        LOG.debug("Sending commit message. round={}", roundState.getRoundIdentifier());
        final Block block = roundState.getProposedBlock().get();
        try {
            transmitter.multicastCommit(getRoundIdentifier(), block.getHash(), createCommitSeal(block));
        // Note: the local-node's commit message was added to RoundState on block acceptance
        // and thus does not need to be done again here.
        } catch (final SecurityModuleException e) {
            LOG.warn("Failed to construct a commit seal: {}", e.getMessage());
        }
    }
}
Also used : SecurityModuleException(org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException) Block(org.hyperledger.besu.ethereum.core.Block)

Example 15 with Block

use of org.hyperledger.besu.ethereum.core.Block in project besu by hyperledger.

the class QbftRound method updateStateWithProposedBlock.

private boolean updateStateWithProposedBlock(final Proposal msg) {
    final boolean wasPrepared = roundState.isPrepared();
    final boolean wasCommitted = roundState.isCommitted();
    final boolean blockAccepted = roundState.setProposedBlock(msg);
    if (blockAccepted) {
        final Block block = roundState.getProposedBlock().get();
        final SECPSignature commitSeal;
        try {
            commitSeal = createCommitSeal(block);
        } catch (final SecurityModuleException e) {
            LOG.warn("Failed to construct commit seal; {}", e.getMessage());
            return true;
        }
        // There are times handling a proposed block is enough to enter prepared.
        if (wasPrepared != roundState.isPrepared()) {
            LOG.debug("Sending commit message. round={}", roundState.getRoundIdentifier());
            transmitter.multicastCommit(getRoundIdentifier(), block.getHash(), commitSeal);
        }
        // prepare
        try {
            final Commit localCommitMessage = messageFactory.createCommit(roundState.getRoundIdentifier(), msg.getBlock().getHash(), commitSeal);
            roundState.addCommitMessage(localCommitMessage);
        } catch (final SecurityModuleException e) {
            LOG.warn("Failed to create signed Commit message; {}", e.getMessage());
            return true;
        }
        // It is possible sufficient commit seals are now available and the block should be imported
        if (wasCommitted != roundState.isCommitted()) {
            importBlockToChain();
        }
    }
    return blockAccepted;
}
Also used : SECPSignature(org.hyperledger.besu.crypto.SECPSignature) Commit(org.hyperledger.besu.consensus.qbft.messagewrappers.Commit) SecurityModuleException(org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleException) Block(org.hyperledger.besu.ethereum.core.Block)

Aggregations

Block (org.hyperledger.besu.ethereum.core.Block)425 Test (org.junit.Test)236 BlockHeader (org.hyperledger.besu.ethereum.core.BlockHeader)118 BlockDataGenerator (org.hyperledger.besu.ethereum.core.BlockDataGenerator)91 List (java.util.List)57 Hash (org.hyperledger.besu.datatypes.Hash)54 TransactionReceipt (org.hyperledger.besu.ethereum.core.TransactionReceipt)52 BlockBody (org.hyperledger.besu.ethereum.core.BlockBody)47 ProtocolContext (org.hyperledger.besu.ethereum.ProtocolContext)40 ArrayList (java.util.ArrayList)37 Test (org.junit.jupiter.api.Test)37 ConsensusRoundIdentifier (org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier)36 Transaction (org.hyperledger.besu.ethereum.core.Transaction)34 RespondingEthPeer (org.hyperledger.besu.ethereum.eth.manager.RespondingEthPeer)34 Optional (java.util.Optional)33 Bytes (org.apache.tuweni.bytes.Bytes)33 MutableBlockchain (org.hyperledger.besu.ethereum.chain.MutableBlockchain)31 ProtocolSchedule (org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule)31 Address (org.hyperledger.besu.datatypes.Address)28 Difficulty (org.hyperledger.besu.ethereum.core.Difficulty)28