use of org.hyperledger.besu.consensus.qbft.payload.ProposalPayload in project besu by hyperledger.
the class ProposalTest method canRoundTripProposalMessage.
@Test
public void canRoundTripProposalMessage() {
final NodeKey nodeKey = NodeKeyUtils.generate();
final Address addr = Util.publicKeyToAddress(nodeKey.getPublicKey());
final ProposalPayload payload = new ProposalPayload(new ConsensusRoundIdentifier(1, 1), BLOCK);
final SignedData<ProposalPayload> signedPayload = SignedData.create(payload, nodeKey.sign(payload.hashForSignature()));
final PreparePayload preparePayload = new PreparePayload(new ConsensusRoundIdentifier(1, 0), BLOCK.getHash());
final SignedData<PreparePayload> prepare = SignedData.create(preparePayload, nodeKey.sign(preparePayload.hashForSignature()));
final RoundChangePayload roundChangePayload = new RoundChangePayload(new ConsensusRoundIdentifier(1, 0), Optional.of(new PreparedRoundMetadata(BLOCK.getHash(), 0)));
final SignedData<RoundChangePayload> roundChange = SignedData.create(roundChangePayload, nodeKey.sign(roundChangePayload.hashForSignature()));
final Proposal proposal = new Proposal(signedPayload, List.of(roundChange), List.of(prepare));
final Proposal decodedProposal = Proposal.decode(proposal.encode(), bftExtraDataCodec);
assertThat(decodedProposal.getAuthor()).isEqualTo(addr);
assertThat(decodedProposal.getMessageType()).isEqualTo(QbftV1.PROPOSAL);
assertThat(decodedProposal.getPrepares()).hasSize(1);
assertThat(decodedProposal.getPrepares().get(0)).isEqualToComparingFieldByField(prepare);
assertThat(decodedProposal.getRoundChanges()).hasSize(1);
assertThat(decodedProposal.getRoundChanges().get(0)).isEqualToComparingFieldByField(roundChange);
assertThat(decodedProposal.getSignedPayload().getPayload().getProposedBlock()).isEqualTo(BLOCK);
assertThat(decodedProposal.getSignedPayload().getPayload().getRoundIdentifier()).isEqualTo(payload.getRoundIdentifier());
}
use of org.hyperledger.besu.consensus.qbft.payload.ProposalPayload in project besu by hyperledger.
the class ProposalPayloadValidator method validate.
public boolean validate(final SignedData<ProposalPayload> signedPayload) {
if (!signedPayload.getAuthor().equals(expectedProposer)) {
LOG.info("{}: proposal created by non-proposer", ERROR_PREFIX);
return false;
}
final ProposalPayload payload = signedPayload.getPayload();
if (!payload.getRoundIdentifier().equals(targetRound)) {
LOG.info("{}: proposal is not for expected round", ERROR_PREFIX);
return false;
}
final Block block = payload.getProposedBlock();
if (!validateBlock(block)) {
return false;
}
if (block.getHeader().getNumber() != payload.getRoundIdentifier().getSequenceNumber()) {
LOG.info("{}: block number does not match sequence number", ERROR_PREFIX);
return false;
}
if (cmsValidator.isPresent()) {
return validateCms(block, protocolContext.getConsensusContext(QbftContext.class).getBlockInterface(), cmsValidator.get());
}
return true;
}
use of org.hyperledger.besu.consensus.qbft.payload.ProposalPayload in project besu by hyperledger.
the class Proposal method decode.
public static Proposal decode(final Bytes data, final BftExtraDataCodec bftExtraDataCodec) {
final RLPInput rlpIn = RLP.input(data);
rlpIn.enterList();
final SignedData<ProposalPayload> payload = readPayload(rlpIn, rlpInput -> ProposalPayload.readFrom(rlpInput, bftExtraDataCodec));
rlpIn.enterList();
final List<SignedData<RoundChangePayload>> roundChanges = rlpIn.readList(r -> readPayload(r, RoundChangePayload::readFrom));
final List<SignedData<PreparePayload>> prepares = rlpIn.readList(r -> readPayload(r, PreparePayload::readFrom));
rlpIn.leaveList();
rlpIn.leaveList();
return new Proposal(payload, roundChanges, prepares);
}
use of org.hyperledger.besu.consensus.qbft.payload.ProposalPayload in project besu by hyperledger.
the class ProposalMessage method toBftMessage.
@Override
public BftMessage<ProposalPayload> toBftMessage() {
final List<SignedData<RoundChangePayload>> signedRoundChanges = roundChanges.stream().map(SignedRoundChange::toSignedRoundChangePayload).collect(Collectors.toList());
final List<SignedData<PreparePayload>> signedPrepares = prepares.stream().map(PrepareMessage::toSignedPreparePayload).collect(Collectors.toList());
final Block block = Block.readFrom(RLP.input(Bytes.fromHexString(signedProposal.unsignedProposal.block)), BftBlockHeaderFunctions.forCommittedSeal(new QbftExtraDataCodec()));
final ProposalPayload proposalPayload = new ProposalPayload(new ConsensusRoundIdentifier(signedProposal.unsignedProposal.sequence, signedProposal.unsignedProposal.round), block);
final SignedData<ProposalPayload> signedProposalPayload = SignedData.create(proposalPayload, SignatureAlgorithmFactory.getInstance().decodeSignature(Bytes.fromHexString(signedProposal.signature)));
return new Proposal(signedProposalPayload, signedRoundChanges, signedPrepares);
}
Aggregations