Remove QBFT hashmode in qbft core (#8351)

Signed-off-by: Jason Frame <jason.frame@consensys.net>
This commit is contained in:
Jason Frame
2025-02-27 11:30:11 +10:00
committed by GitHub
parent 98c70654b7
commit 7fbf97ba71
20 changed files with 48 additions and 240 deletions

View File

@@ -25,7 +25,6 @@ import org.hyperledger.besu.consensus.qbft.core.statemachine.PreparedCertificate
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.crypto.SECPSignature;
import org.hyperledger.besu.cryptoservices.NodeKey;
@@ -63,7 +62,6 @@ public class IntegrationTestHelpers {
final QbftExtraDataCodec bftExtraDataCodec = new QbftExtraDataCodec();
final BftBlockInterface bftBlockInterface = new BftBlockInterface(bftExtraDataCodec);
final QbftBlockInterface qbftBlockInterface = new QbftBlockInterfaceAdaptor(bftBlockInterface);
return qbftBlockInterface.replaceRoundInBlock(
proposalBlock, round, QbftHashMode.COMMITTED_SEAL);
return qbftBlockInterface.replaceRoundInBlock(proposalBlock, round);
}
}

View File

@@ -21,7 +21,6 @@ import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata;
import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
@@ -122,7 +121,7 @@ public class RoundChange extends BftMessage<RoundChangePayload> {
rlpIn.skipNext();
block = Optional.empty();
} else {
block = Optional.of(blockEncoder.readFrom(rlpIn, QbftHashMode.COMMITTED_SEAL));
block = Optional.of(blockEncoder.readFrom(rlpIn));
}
final List<SignedData<PreparePayload>> prepares =

View File

@@ -18,7 +18,6 @@ import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
import org.hyperledger.besu.consensus.qbft.core.messagedata.QbftV1;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
@@ -61,7 +60,7 @@ public class ProposalPayload extends QbftPayload {
final RLPInput rlpInput, final QbftBlockCodec blockEncoder) {
rlpInput.enterList();
final ConsensusRoundIdentifier roundIdentifier = readConsensusRound(rlpInput);
final QbftBlock proposedBlock = blockEncoder.readFrom(rlpInput, QbftHashMode.COMMITTED_SEAL);
final QbftBlock proposedBlock = blockEncoder.readFrom(rlpInput);
rlpInput.leaveList();
return new ProposalPayload(roundIdentifier, proposedBlock, blockEncoder);

View File

@@ -35,7 +35,6 @@ import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockImporter;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftContext;
import org.hyperledger.besu.consensus.qbft.core.types.QbftExtraDataProvider;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.consensus.qbft.core.types.QbftMinedBlockObserver;
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
import org.hyperledger.besu.crypto.SECPSignature;
@@ -168,9 +167,7 @@ public class QbftRound {
protocolContext.getConsensusContext(QbftContext.class).blockInterface();
blockToPublish =
bftBlockInterface.replaceRoundInBlock(
preparedBlock,
roundState.getRoundIdentifier().getRoundNumber(),
QbftHashMode.COMMITTED_SEAL);
preparedBlock, roundState.getRoundIdentifier().getRoundNumber());
}
LOG.debug(" proposal - new/prepared block hash : {}", blockToPublish.getHash());
@@ -397,8 +394,7 @@ public class QbftRound {
private QbftBlock createCommitBlock(final QbftBlock block) {
final QbftBlockInterface bftBlockInterface =
protocolContext.getConsensusContext(QbftContext.class).blockInterface();
return bftBlockInterface.replaceRoundInBlock(
block, getRoundIdentifier().getRoundNumber(), QbftHashMode.COMMITTED_SEAL);
return bftBlockInterface.replaceRoundInBlock(block, getRoundIdentifier().getRoundNumber());
}
private void notifyNewBlockListeners(final QbftBlock block) {

View File

@@ -20,13 +20,12 @@ import org.hyperledger.besu.ethereum.rlp.RLPOutput;
/** Block encoding and decoding to and from RLP */
public interface QbftBlockCodec {
/**
* Read a block from RLP
* Read a block from RLP using the committed seal hash
*
* @param rlpInput RLP input
* @param hashMode Hash mode to ensure the block hash is calculated correctly
* @return The block
*/
QbftBlock readFrom(RLPInput rlpInput, QbftHashMode hashMode);
QbftBlock readFrom(RLPInput rlpInput);
/**
* Write a block to RLP

View File

@@ -18,12 +18,12 @@ package org.hyperledger.besu.consensus.qbft.core.types;
public interface QbftBlockInterface {
/**
* Create a new block using the supplied block with round number replaced.
* Create a new block using the supplied block with round number replaced. The hash must be for
* the committed seal.
*
* @param proposalBlock the proposal block
* @param roundNumber the round number
* @param hashMode the hash mode
* @return the new qbft block with updated round number
*/
QbftBlock replaceRoundInBlock(QbftBlock proposalBlock, int roundNumber, QbftHashMode hashMode);
QbftBlock replaceRoundInBlock(QbftBlock proposalBlock, int roundNumber);
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright contributors to Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.qbft.core.types;
/**
* The mode in which the block hash is calculated for a QBFT block.
*
* <p>When a block is hashed, the hash may be calculated in different ways depending on the context
* in which the hash is being used.
*/
public enum QbftHashMode {
/**
* Hash the block for the committed seal. This typically means the block hash excludes the commit
* seal from the hashing.
*/
COMMITTED_SEAL,
/**
* Hash the block for onchain block. This typically means the block hash exclude the commit seals
* and round number from the hashing as each node may have a different value for these fields.
*/
ONCHAIN
}

View File

@@ -20,7 +20,6 @@ import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Prepare;
import org.hyperledger.besu.consensus.qbft.core.messagewrappers.Proposal;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.datatypes.Address;
import java.util.Collection;
@@ -54,8 +53,7 @@ public class MessageValidator {
final QbftBlock proposalBlock,
final QbftBlockInterface blockInterface) {
final QbftBlock commitBlock =
blockInterface.replaceRoundInBlock(
proposalBlock, targetRound.getRoundNumber(), QbftHashMode.COMMITTED_SEAL);
blockInterface.replaceRoundInBlock(proposalBlock, targetRound.getRoundNumber());
prepareValidator = new PrepareValidator(validators, targetRound, proposalBlock.getHash());
commitValidator =
new CommitValidator(

View File

@@ -28,7 +28,6 @@ import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockValidator;
import org.hyperledger.besu.consensus.qbft.core.types.QbftContext;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
@@ -146,8 +145,7 @@ public class ProposalValidator {
final QbftBlockInterface bftBlockInterface =
protocolContext.getConsensusContext(QbftContext.class).blockInterface();
final QbftBlock currentBlockWithOldRound =
bftBlockInterface.replaceRoundInBlock(
proposal.getBlock(), metadata.getPreparedRound(), QbftHashMode.COMMITTED_SEAL);
bftBlockInterface.replaceRoundInBlock(proposal.getBlock(), metadata.getPreparedRound());
final Hash expectedPriorBlockHash = currentBlockWithOldRound.getHash();

View File

@@ -16,7 +16,6 @@ package org.hyperledger.besu.consensus.qbft.core.messagewrappers;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
@@ -29,7 +28,6 @@ import org.hyperledger.besu.consensus.qbft.core.payload.ProposalPayload;
import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address;
@@ -51,7 +49,7 @@ public class ProposalTest {
@Test
public void canRoundTripProposalMessage() {
when(blockEncoder.readFrom(any(), eq(QbftHashMode.COMMITTED_SEAL))).thenReturn(BLOCK);
when(blockEncoder.readFrom(any())).thenReturn(BLOCK);
final NodeKey nodeKey = NodeKeyUtils.generate();
final Address addr = Util.publicKeyToAddress(nodeKey.getPublicKey());

View File

@@ -16,7 +16,6 @@ package org.hyperledger.besu.consensus.qbft.core.messagewrappers;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.consensus.common.bft.ConsensusRoundIdentifier;
@@ -28,7 +27,6 @@ import org.hyperledger.besu.consensus.qbft.core.payload.PreparedRoundMetadata;
import org.hyperledger.besu.consensus.qbft.core.payload.RoundChangePayload;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address;
@@ -51,7 +49,7 @@ public class RoundChangeTest {
@Test
public void canRoundTripARoundChangeMessage() {
when(blockEncoder.readFrom(any(), eq(QbftHashMode.COMMITTED_SEAL))).thenReturn(BLOCK);
when(blockEncoder.readFrom(any())).thenReturn(BLOCK);
final NodeKey nodeKey = NodeKeyUtils.generate();
final Address addr = Util.publicKeyToAddress(nodeKey.getPublicKey());

View File

@@ -244,8 +244,7 @@ public class QbftBlockHeightManagerTest {
public void onBlockTimerExpiryRoundTimerIsStartedAndProposalMessageIsTransmitted() {
when(finalState.isLocalNodeProposerForRound(roundIdentifier)).thenReturn(true);
when(blockTimer.checkEmptyBlockExpired(any(), eq(0L))).thenReturn(true);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(0), any()))
.thenReturn(createdBlock);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(0))).thenReturn(createdBlock);
final QbftBlockHeightManager manager =
new QbftBlockHeightManager(
@@ -300,8 +299,7 @@ public class QbftBlockHeightManagerTest {
messageValidatorFactory,
messageFactory);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(2), any()))
.thenReturn(createdBlock);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(2))).thenReturn(createdBlock);
// Force a new round to be started at new round number.
final ConsensusRoundIdentifier futureRoundIdentifier = createFrom(roundIdentifier, 0, +2);
@@ -377,8 +375,7 @@ public class QbftBlockHeightManagerTest {
when(roundChangeManager.appendRoundChangeMessage(any()))
.thenReturn(Optional.of(singletonList(roundChange)));
when(finalState.isLocalNodeProposerForRound(any())).thenReturn(true);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(2), any()))
.thenReturn(createdBlock);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(2))).thenReturn(createdBlock);
final QbftBlockHeightManager manager =
new QbftBlockHeightManager(
@@ -404,8 +401,7 @@ public class QbftBlockHeightManagerTest {
@Test
public void messagesForFutureRoundsAreBufferedAndUsedToPreloadNewRoundWhenItIsStarted() {
when(finalState.getQuorum()).thenReturn(1);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(2), any()))
.thenReturn(createdBlock);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(2))).thenReturn(createdBlock);
when(blockCreator.createSealedBlock(any(), any(), anyInt(), any())).thenReturn(createdBlock);
when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec);
when(protocolSpec.getBlockImporter()).thenReturn(blockImporter);
@@ -454,8 +450,7 @@ public class QbftBlockHeightManagerTest {
when(finalState.getQuorum()).thenReturn(1);
when(finalState.isLocalNodeProposerForRound(roundIdentifier)).thenReturn(true);
when(blockTimer.checkEmptyBlockExpired(any(), eq(0L))).thenReturn(true);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(0), any()))
.thenReturn(createdBlock);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(0))).thenReturn(createdBlock);
when(blockCreator.createSealedBlock(any(), any(), anyInt(), any())).thenReturn(createdBlock);
when(protocolSchedule.getByBlockHeader(any())).thenReturn(protocolSpec);
when(protocolSpec.getBlockImporter()).thenReturn(blockImporter);
@@ -497,9 +492,8 @@ public class QbftBlockHeightManagerTest {
public void preparedCertificateIncludedInRoundChangeMessageOnRoundTimeoutExpired() {
when(finalState.isLocalNodeProposerForRound(any())).thenReturn(true);
when(blockTimer.checkEmptyBlockExpired(any(), eq(0L))).thenReturn(true);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(0), any()))
.thenReturn(createdBlock);
when(blockEncoder.readFrom(any(), any())).thenReturn(createdBlock);
when(blockInterface.replaceRoundInBlock(eq(createdBlock), eq(0))).thenReturn(createdBlock);
when(blockEncoder.readFrom(any())).thenReturn(createdBlock);
final QbftBlockHeightManager manager =
new QbftBlockHeightManager(

View File

@@ -47,7 +47,6 @@ import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockImporter;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftContext;
import org.hyperledger.besu.consensus.qbft.core.types.QbftExtraDataProvider;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.consensus.qbft.core.types.QbftMinedBlockObserver;
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSpec;
@@ -190,8 +189,7 @@ public class QbftRoundTest {
qbftExtraDataProvider,
parentHeader);
when(blockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any()))
.thenReturn(proposedBlock);
when(blockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0))).thenReturn(proposedBlock);
round.handleProposalMessage(
messageFactory.createProposal(
@@ -205,8 +203,7 @@ public class QbftRoundTest {
final QbftBlockHeader header = new QbftBlockHeaderTestFixture().number(0).buildHeader();
final QbftBlock commitBlock = new QbftBlockTestFixture().blockHeader(header).build();
when(blockInteface.replaceRoundInBlock(proposedBlock, 0, QbftHashMode.COMMITTED_SEAL))
.thenReturn(commitBlock);
when(blockInteface.replaceRoundInBlock(proposedBlock, 0)).thenReturn(commitBlock);
final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator);
final QbftRound round =
@@ -240,10 +237,8 @@ public class QbftRoundTest {
new QbftBlockTestFixture()
.blockHeader(new QbftBlockHeaderTestFixture().number(0).buildHeader())
.build();
when(blockInteface.replaceRoundInBlock(proposedBlock, 0, QbftHashMode.COMMITTED_SEAL))
.thenReturn(publishBlock);
when(blockInteface.replaceRoundInBlock(publishBlock, 0, QbftHashMode.COMMITTED_SEAL))
.thenReturn(commitBlock);
when(blockInteface.replaceRoundInBlock(proposedBlock, 0)).thenReturn(publishBlock);
when(blockInteface.replaceRoundInBlock(publishBlock, 0)).thenReturn(commitBlock);
final ConsensusRoundIdentifier priorRoundChange = new ConsensusRoundIdentifier(1, 0);
final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator);
@@ -296,8 +291,7 @@ public class QbftRoundTest {
new QbftBlockTestFixture()
.blockHeader(new QbftBlockHeaderTestFixture().number(0).buildHeader())
.build();
when(blockInteface.replaceRoundInBlock(proposedBlock, 0, QbftHashMode.COMMITTED_SEAL))
.thenReturn(commitBlock);
when(blockInteface.replaceRoundInBlock(proposedBlock, 0)).thenReturn(commitBlock);
final RoundState roundState = new RoundState(roundIdentifier, 2, messageValidator);
final QbftRound round =
@@ -358,8 +352,7 @@ public class QbftRoundTest {
qbftExtraDataProvider,
parentHeader);
when(blockInteface.replaceRoundInBlock(proposedBlock, 0, QbftHashMode.COMMITTED_SEAL))
.thenReturn(proposedBlock);
when(blockInteface.replaceRoundInBlock(proposedBlock, 0)).thenReturn(proposedBlock);
when(blockCreator.createSealedBlock(eq(qbftExtraDataProvider), eq(proposedBlock), eq(0), any()))
.thenReturn(proposedBlock);
@@ -392,8 +385,7 @@ public class QbftRoundTest {
qbftExtraDataProvider,
parentHeader);
when(blockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any()))
.thenReturn(proposedBlock);
when(blockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0))).thenReturn(proposedBlock);
when(blockCreator.createSealedBlock(eq(qbftExtraDataProvider), eq(proposedBlock), eq(0), any()))
.thenReturn(proposedBlock);
@@ -430,8 +422,7 @@ public class QbftRoundTest {
qbftExtraDataProvider,
parentHeader);
when(blockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0), any()))
.thenReturn(proposedBlock);
when(blockInteface.replaceRoundInBlock(eq(proposedBlock), eq(0))).thenReturn(proposedBlock);
round.handleProposalMessage(
messageFactory.createProposal(

View File

@@ -40,7 +40,6 @@ import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockHeader;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockValidator;
import org.hyperledger.besu.consensus.qbft.core.types.QbftContext;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSchedule;
import org.hyperledger.besu.consensus.qbft.core.types.QbftProtocolSpec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftValidatorProvider;
@@ -323,7 +322,7 @@ public class ProposalValidatorTest {
final List<SignedData<RoundChangePayload>> roundChanges =
createEmptyRoundChangePayloads(
roundItem.roundIdentifier, validators.getNode(0), validators.getNode(1));
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final RoundChangePayload illegalPayload =
@@ -388,7 +387,7 @@ public class ProposalValidatorTest {
public void validationFailsIfPiggybackedPreparePayloadIsFromNonValidator() {
final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE);
final List<SignedData<RoundChangePayload>> roundChanges = createPreparedRoundZeroRoundChanges();
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final QbftNode nonValidator = QbftNode.create(blockEncoder);
@@ -413,7 +412,7 @@ public class ProposalValidatorTest {
public void validationFailsIfPiggybackedPreparePayloadHasDuplicatedAuthors() {
final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE);
final List<SignedData<RoundChangePayload>> roundChanges = createPreparedRoundZeroRoundChanges();
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final Proposal proposal =
@@ -437,7 +436,7 @@ public class ProposalValidatorTest {
public void validationFailsIfInsufficientPiggybackedPreparePayloads() {
final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE);
final List<SignedData<RoundChangePayload>> roundChanges = createPreparedRoundZeroRoundChanges();
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final Proposal proposal =
@@ -460,7 +459,7 @@ public class ProposalValidatorTest {
public void validationFailsIfPreparePayloadsDoNotMatchMetadataInRoundChanges() {
final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE);
final List<SignedData<RoundChangePayload>> roundChanges = createPreparedRoundZeroRoundChanges();
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final Proposal proposal =
@@ -484,7 +483,7 @@ public class ProposalValidatorTest {
public void validationFailsIfPreparePayloadsDoNotMatchBlockHashInRoundChanges() {
final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE);
final List<SignedData<RoundChangePayload>> roundChanges = createPreparedRoundZeroRoundChanges();
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final Proposal proposal =
@@ -508,7 +507,7 @@ public class ProposalValidatorTest {
public void validationFailsIfTwoRoundChangesArePreparedOnSameRoundDifferentBlock() {
final RoundSpecificItems roundItem = roundItems.get(ROUND_ID.ONE);
final List<SignedData<RoundChangePayload>> roundChanges = createPreparedRoundZeroRoundChanges();
when(blockInterface.replaceRoundInBlock(roundItem.block, 0, QbftHashMode.COMMITTED_SEAL))
when(blockInterface.replaceRoundInBlock(roundItem.block, 0))
.thenReturn(roundItems.get(ROUND_ID.ZERO).block);
final RoundChangePayload illegalPreparedRoundChangePayload =

View File

@@ -1,44 +0,0 @@
/*
* Copyright contributors to Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.qbft.adaptor;
import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
/** Utility class to get the correct BlockHeaderFunctions based on the QbftHashMode. */
public class BlockHeaderFunctionsUtil {
// Private constructor to prevent instantiation
private BlockHeaderFunctionsUtil() {}
/**
* Get the correct BlockHeaderFunctions based on the QbftHashMode.
*
* @param extraDataCodec the extra data codec
* @param hashMode the hash mode
* @return the block header functions
*/
public static BlockHeaderFunctions getBlockHeaderFunctions(
final QbftExtraDataCodec extraDataCodec, final QbftHashMode hashMode) {
if (hashMode == QbftHashMode.ONCHAIN) {
return BftBlockHeaderFunctions.forOnchainBlock(extraDataCodec);
} else if (hashMode == QbftHashMode.COMMITTED_SEAL) {
return BftBlockHeaderFunctions.forCommittedSeal(extraDataCodec);
} else {
throw new IllegalStateException("Invalid HashMode");
}
}
}

View File

@@ -14,14 +14,11 @@
*/
package org.hyperledger.besu.consensus.qbft.adaptor;
import static org.hyperledger.besu.consensus.qbft.adaptor.BlockHeaderFunctionsUtil.getBlockHeaderFunctions;
import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
@@ -40,10 +37,9 @@ public class QbftBlockCodecAdaptor implements QbftBlockCodec {
}
@Override
public QbftBlock readFrom(final RLPInput rlpInput, final QbftHashMode hashMode) {
final BlockHeaderFunctions blockHeaderFunctions =
getBlockHeaderFunctions(qbftExtraDataCodec, hashMode);
Block besuBlock = Block.readFrom(rlpInput, blockHeaderFunctions);
public QbftBlock readFrom(final RLPInput rlpInput) {
Block besuBlock =
Block.readFrom(rlpInput, BftBlockHeaderFunctions.forCommittedSeal(qbftExtraDataCodec));
return new QbftBlockAdaptor(besuBlock);
}

View File

@@ -14,14 +14,13 @@
*/
package org.hyperledger.besu.consensus.qbft.adaptor;
import static org.hyperledger.besu.consensus.qbft.adaptor.BlockHeaderFunctionsUtil.getBlockHeaderFunctions;
import static org.hyperledger.besu.consensus.qbft.adaptor.BlockUtil.toBesuBlock;
import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
import org.hyperledger.besu.consensus.common.bft.BftBlockInterface;
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions;
@@ -42,11 +41,10 @@ public class QbftBlockInterfaceAdaptor implements QbftBlockInterface {
}
@Override
public QbftBlock replaceRoundInBlock(
final QbftBlock proposalBlock, final int roundNumber, final QbftHashMode hashMode) {
public QbftBlock replaceRoundInBlock(final QbftBlock proposalBlock, final int roundNumber) {
final Block besuBlock = toBesuBlock(proposalBlock);
final BlockHeaderFunctions blockHeaderFunctions =
getBlockHeaderFunctions(bftExtraDataCodec, hashMode);
BftBlockHeaderFunctions.forCommittedSeal(bftExtraDataCodec);
final Block updatedRoundBlock =
bftBlockInterface.replaceRoundInBlock(besuBlock, roundNumber, blockHeaderFunctions);
return new QbftBlockAdaptor(updatedRoundBlock);

View File

@@ -1,69 +0,0 @@
/*
* Copyright contributors to Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.qbft.adaptor;
import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.consensus.common.bft.BftBlockHeaderFunctions;
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.crypto.SECPSignature;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import java.math.BigInteger;
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.Test;
class BlockHeaderFunctionsUtilTest {
private final QbftExtraDataCodec qbftExtraDataCodec = new QbftExtraDataCodec();
private final BftExtraData bftExtraData =
new BftExtraData(
Bytes.wrap(new byte[32]),
List.of(new SECPSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0)),
Optional.empty(),
2,
emptyList());
private final BlockHeader header =
new BlockHeaderTestFixture()
.number(1)
.extraData(new QbftExtraDataCodec().encode(bftExtraData))
.buildHeader();
@Test
void returnBlockHeaderFunctionThatHashesForCommitedSeal() {
Hash expectedHash = BftBlockHeaderFunctions.forCommittedSeal(qbftExtraDataCodec).hash(header);
Hash hash =
BlockHeaderFunctionsUtil.getBlockHeaderFunctions(
qbftExtraDataCodec, QbftHashMode.COMMITTED_SEAL)
.hash(header);
assertThat(hash).isEqualTo(expectedHash);
}
@Test
void returnBlockHeaderFunctionThatHashesForOnChain() {
Hash expectedHash = BftBlockHeaderFunctions.forOnchainBlock(qbftExtraDataCodec).hash(header);
Hash hash =
BlockHeaderFunctionsUtil.getBlockHeaderFunctions(qbftExtraDataCodec, QbftHashMode.ONCHAIN)
.hash(header);
assertThat(hash).isEqualTo(expectedHash);
}
}

View File

@@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.consensus.common.bft.BftExtraData;
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
@@ -32,14 +31,12 @@ import org.hyperledger.besu.ethereum.rlp.RLPInput;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.api.Test;
class QbftBlockCodecAdaptorTest {
@ParameterizedTest
@EnumSource(QbftHashMode.class)
void canRoundTripBlock(final QbftHashMode hashMode) {
@Test
void canRoundTripBlock() {
BftExtraData bftExtraData =
new BftExtraData(Bytes.wrap(new byte[32]), emptyList(), Optional.empty(), 0, emptyList());
Bytes encodedExtraData = new QbftExtraDataCodec().encode(bftExtraData);
@@ -52,7 +49,7 @@ class QbftBlockCodecAdaptorTest {
qbftBlockCodec.writeTo(block, rlpOutput);
RLPInput rlpInput = new BytesValueRLPInput(rlpOutput.encoded(), false);
QbftBlock decodedBlock = qbftBlockCodec.readFrom(rlpInput, hashMode);
QbftBlock decodedBlock = qbftBlockCodec.readFrom(rlpInput);
assertThat(decodedBlock).isEqualTo(block);
}
}

View File

@@ -22,7 +22,6 @@ import org.hyperledger.besu.consensus.common.bft.BftExtraData;
import org.hyperledger.besu.consensus.qbft.QbftExtraDataCodec;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlock;
import org.hyperledger.besu.consensus.qbft.core.types.QbftBlockInterface;
import org.hyperledger.besu.consensus.qbft.core.types.QbftHashMode;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockBody;
import org.hyperledger.besu.ethereum.core.BlockHeader;
@@ -51,8 +50,7 @@ class QbftBlockInterfaceAdaptorTest {
QbftBlock block = new QbftBlockAdaptor(besuBlock);
QbftBlockInterface qbftBlockInterface = new QbftBlockInterfaceAdaptor(bftBlockInterface);
QbftBlock updatedBlock =
qbftBlockInterface.replaceRoundInBlock(block, 1, QbftHashMode.COMMITTED_SEAL);
QbftBlock updatedBlock = qbftBlockInterface.replaceRoundInBlock(block, 1);
BftExtraData extraData =
qbftExtraDataCodec.decode(BlockUtil.toBesuBlockHeader(updatedBlock.getHeader()));
assertThat(extraData.getRound()).isEqualTo(1);