From 795b7c4dfbf5c37d9fd8968823cdc87313725c15 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Tue, 11 Apr 2023 14:55:50 +1000 Subject: [PATCH] [23.4] Remove IBFT1 consensus mechanism (#5302) * remove controller and config * remove ibftlegacy module * remove further config options * run non-mainnet ATs just to be sure * remove temp change to circle config --------- Signed-off-by: Sally MacFarlane --- CHANGELOG.md | 8 +- ...ermissioningIbft2StallAcceptanceTest.java} | 2 +- besu/build.gradle | 1 - .../besu/controller/BesuController.java | 6 +- .../IbftLegacyBesuControllerBuilder.java | 154 -------- .../chainimport/RlpBlockImporterTest.java | 45 --- .../besu/controller/BesuControllerTest.java | 28 +- .../test/resources/ibftlegacy_genesis.json | 38 -- .../besu/config/GenesisConfigOptions.java | 11 +- .../besu/config/IbftLegacyConfigOptions.java | 104 ------ .../besu/config/JsonGenesisConfigOptions.java | 12 - .../besu/config/StubGenesisConfigOptions.java | 8 - .../besu/config/GenesisConfigOptionsTest.java | 17 - .../config/JsonGenesisConfigOptionsTest.java | 30 -- consensus/ibftlegacy/build.gradle | 51 --- .../ibftlegacy/IbftBlockHashing.java | 169 --------- ...ftBlockHeaderValidationRulesetFactory.java | 85 ----- .../consensus/ibftlegacy/IbftExtraData.java | 184 ---------- .../consensus/ibftlegacy/IbftHelpers.java | 36 -- .../ibftlegacy/IbftLegacyBlockInterface.java | 105 ------ .../ibftlegacy/IbftProtocolSchedule.java | 104 ------ .../LegacyIbftBlockHeaderFunctions.java | 38 -- .../blockcreation/IbftBlockCreator.java | 132 ------- .../IbftExtraDataValidationRule.java | 147 -------- .../VoteValidationRule.java | 45 --- .../protocol/Istanbul99Protocol.java | 130 ------- .../protocol/Istanbul99ProtocolManager.java | 90 ----- .../ibftlegacy/BftBlockHashingTest.java | 133 ------- .../ibftlegacy/BftExtraDataCodecTest.java | 157 --------- ...ockHeaderValidationRulesetFactoryTest.java | 166 --------- .../IbftLegacyBlockInterfaceTest.java | 133 ------- .../ibftlegacy/IbftLegacyContextBuilder.java | 41 --- .../consensus/ibftlegacy/TestHelpers.java | 59 ---- .../blockcreation/BftBlockCreatorTest.java | 131 ------- .../BftExtraDataValidationRuleTest.java | 330 ------------------ .../Istanbul99ProtocolManagerTest.java | 159 --------- .../besu/evmtool/GenesisFileModule.java | 2 +- settings.gradle | 1 - 38 files changed, 14 insertions(+), 3078 deletions(-) rename acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/{NodeSmartContractPermissioningIbftStallAcceptanceTest.java => NodeSmartContractPermissioningIbft2StallAcceptanceTest.java} (97%) delete mode 100644 besu/src/main/java/org/hyperledger/besu/controller/IbftLegacyBesuControllerBuilder.java delete mode 100644 besu/src/test/resources/ibftlegacy_genesis.json delete mode 100644 config/src/main/java/org/hyperledger/besu/config/IbftLegacyConfigOptions.java delete mode 100644 consensus/ibftlegacy/build.gradle delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHashing.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactory.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftExtraData.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftHelpers.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterface.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftProtocolSchedule.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/LegacyIbftBlockHeaderFunctions.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/IbftBlockCreator.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/IbftExtraDataValidationRule.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/VoteValidationRule.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99Protocol.java delete mode 100644 consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManager.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftBlockHashingTest.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftExtraDataCodecTest.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactoryTest.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterfaceTest.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyContextBuilder.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/TestHelpers.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/BftBlockCreatorTest.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/BftExtraDataValidationRuleTest.java delete mode 100644 consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManagerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ae4c2d8ae..00d66acd18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 23.4-RC +### Breaking Changes +- Removed IBFT1 feature [#5302](https://github.com/hyperledger/besu/pull/5302) + ### Additions and Improvements - Update most dependencies to latest version [#5269](https://github.com/hyperledger/besu/pull/5269) @@ -15,9 +18,8 @@ - In `--ethstats`, if the port is not specified in the URI, it will default to 443 and 80 for ssl and non-ssl connections respectively instead of 3000. [#5301](https://github.com/hyperledger/besu/pull/5301) ### Additions and Improvements - -- An alternate build target for the EVM using GraalVM AOT compilaiton was added. [#5192](https://github.com/hyperledger/besu/pull/5192) -- To generate the binary install and use GraalVM 23.3.r17 or higher and run `./gradlew naticeCompile`. The binary will be located in `ethereum/evmtool/build/native/nativeCompile` +- An alternate build target for the EVM using GraalVM AOT compilation was added. [#5192](https://github.com/hyperledger/besu/pull/5192) +- To generate the binary install and use GraalVM 23.3.r17 or higher and run `./gradlew nativeCompile`. The binary will be located in `ethereum/evmtool/build/native/nativeCompile` - Upgrade RocksDB version from 7.7.3 to 8.0.0. Besu Team [contributed](https://github.com/facebook/rocksdb/pull/11099) to this release to make disabling checksum verification work. - Log an error with stacktrace when RPC responds with internal error [#5288](https://github.com/hyperledger/besu/pull/5288) - `--ethstats-cacert` to specify root CA of ethstats server (useful for non-production environments). [#5301](https://github.com/hyperledger/besu/pull/5301) diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbftStallAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbft2StallAcceptanceTest.java similarity index 97% rename from acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbftStallAcceptanceTest.java rename to acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbft2StallAcceptanceTest.java index fa22cac247..fc64ee1386 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbftStallAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbft2StallAcceptanceTest.java @@ -24,7 +24,7 @@ import java.util.Optional; import org.junit.Test; -public class NodeSmartContractPermissioningIbftStallAcceptanceTest +public class NodeSmartContractPermissioningIbft2StallAcceptanceTest extends NodeSmartContractPermissioningAcceptanceTestBase { private static final String GENESIS_FILE = diff --git a/besu/build.gradle b/besu/build.gradle index 9d63c8f85e..de74b92182 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -35,7 +35,6 @@ dependencies { implementation project(':consensus:clique') implementation project(':consensus:common') implementation project(':consensus:ibft') - implementation project(':consensus:ibftlegacy') implementation project(':consensus:merge') implementation project(':consensus:qbft') implementation project(':crypto:services') diff --git a/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java b/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java index 6736ab58c7..4beb7f4f12 100644 --- a/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java +++ b/besu/src/main/java/org/hyperledger/besu/controller/BesuController.java @@ -325,7 +325,8 @@ public class BesuController implements java.io.Closeable { } else if (configOptions.isIbft2()) { builder = new IbftBesuControllerBuilder(); } else if (configOptions.isIbftLegacy()) { - builder = new IbftLegacyBesuControllerBuilder(); + throw new IllegalStateException( + "IBFT1 (legacy) is no longer supported. Consider using IBFT2 or QBFT."); } else if (configOptions.isQbft()) { builder = new QbftBesuControllerBuilder(); } else if (configOptions.isClique()) { @@ -358,7 +359,8 @@ public class BesuController implements java.io.Closeable { if (configOptions.isIbft2()) { originalControllerBuilder = new IbftBesuControllerBuilder(); } else if (configOptions.isIbftLegacy()) { - originalControllerBuilder = new IbftLegacyBesuControllerBuilder(); + throw new IllegalStateException( + "IBFT1 (legacy) is no longer supported. Consider using IBFT2 or QBFT."); } else { throw new IllegalStateException( "Invalid genesis migration config. Migration is supported from IBFT (legacy) or IBFT2 to QBFT)"); diff --git a/besu/src/main/java/org/hyperledger/besu/controller/IbftLegacyBesuControllerBuilder.java b/besu/src/main/java/org/hyperledger/besu/controller/IbftLegacyBesuControllerBuilder.java deleted file mode 100644 index 31c942e697..0000000000 --- a/besu/src/main/java/org/hyperledger/besu/controller/IbftLegacyBesuControllerBuilder.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.controller; - -import org.hyperledger.besu.config.IbftLegacyConfigOptions; -import org.hyperledger.besu.consensus.common.BlockInterface; -import org.hyperledger.besu.consensus.common.EpochManager; -import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; -import org.hyperledger.besu.consensus.common.validator.blockbased.BlockValidatorProvider; -import org.hyperledger.besu.consensus.ibft.IbftLegacyContext; -import org.hyperledger.besu.consensus.ibftlegacy.IbftLegacyBlockInterface; -import org.hyperledger.besu.consensus.ibftlegacy.IbftProtocolSchedule; -import org.hyperledger.besu.consensus.ibftlegacy.protocol.Istanbul99Protocol; -import org.hyperledger.besu.consensus.ibftlegacy.protocol.Istanbul99ProtocolManager; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator; -import org.hyperledger.besu.ethereum.blockcreation.NoopMiningCoordinator; -import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.MiningParameters; -import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; -import org.hyperledger.besu.ethereum.eth.manager.EthContext; -import org.hyperledger.besu.ethereum.eth.manager.EthMessages; -import org.hyperledger.besu.ethereum.eth.manager.EthPeers; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; -import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; -import org.hyperledger.besu.ethereum.eth.manager.MergePeerFilter; -import org.hyperledger.besu.ethereum.eth.manager.snap.SnapProtocolManager; -import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator; -import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.sync.state.SyncState; -import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.p2p.config.SubProtocolConfiguration; -import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; - -import java.util.List; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** The Ibft legacy besu controller builder. */ -public class IbftLegacyBesuControllerBuilder extends BesuControllerBuilder { - - private static final Logger LOG = LoggerFactory.getLogger(IbftLegacyBesuControllerBuilder.class); - private final BlockInterface blockInterface = new IbftLegacyBlockInterface(); - - // TODO remove this warning once IBFT1 has been deprecated - /** Default constructor */ - public IbftLegacyBesuControllerBuilder() { - LOG.warn( - "IBFT1 is being deprecated and will be removed in a future release. Consider using QBFT instead of IBFT1 or using GoQuorum instead of Besu if you need to use IBFT1"); - } - - @Override - protected SubProtocolConfiguration createSubProtocolConfiguration( - final EthProtocolManager ethProtocolManager, - final Optional snapProtocolManage) { - return new SubProtocolConfiguration() - .withSubProtocol(Istanbul99Protocol.get(), ethProtocolManager); - } - - @Override - protected MiningCoordinator createMiningCoordinator( - final ProtocolSchedule protocolSchedule, - final ProtocolContext protocolContext, - final TransactionPool transactionPool, - final MiningParameters miningParameters, - final SyncState syncState, - final EthProtocolManager ethProtocolManager) { - return new NoopMiningCoordinator(miningParameters); - } - - @Override - protected ProtocolSchedule createProtocolSchedule() { - return IbftProtocolSchedule.create( - configOptionsSupplier.get(), privacyParameters, isRevertReasonEnabled, evmConfiguration); - } - - @Override - protected IbftLegacyContext createConsensusContext( - final Blockchain blockchain, - final WorldStateArchive worldStateArchive, - final ProtocolSchedule protocolSchedule) { - final IbftLegacyConfigOptions ibftConfig = - configOptionsSupplier.get().getIbftLegacyConfigOptions(); - final EpochManager epochManager = new EpochManager(ibftConfig.getEpochLength()); - final ValidatorProvider validatorProvider = - BlockValidatorProvider.nonForkingValidatorProvider( - blockchain, epochManager, blockInterface); - - return new IbftLegacyContext(validatorProvider, epochManager, blockInterface); - } - - @Override - protected PluginServiceFactory createAdditionalPluginServices( - final Blockchain blockchain, final ProtocolContext protocolContext) { - return new NoopPluginServiceFactory(); - } - - @Override - protected void validateContext(final ProtocolContext context) { - final BlockHeader genesisBlockHeader = context.getBlockchain().getGenesisBlock().getHeader(); - - if (blockInterface.validatorsInBlock(genesisBlockHeader).isEmpty()) { - LOG.warn("Genesis block contains no signers - chain will not progress."); - } - } - - @Override - protected String getSupportedProtocol() { - return Istanbul99Protocol.get().getName(); - } - - @Override - protected EthProtocolManager createEthProtocolManager( - final ProtocolContext protocolContext, - final SynchronizerConfiguration synchronizerConfiguration, - final TransactionPool transactionPool, - final EthProtocolConfiguration ethereumWireProtocolConfiguration, - final EthPeers ethPeers, - final EthContext ethContext, - final EthMessages ethMessages, - final EthScheduler scheduler, - final List peerValidators, - final Optional mergePeerFilter) { - LOG.info("Operating on IBFT-1.0 network."); - return new Istanbul99ProtocolManager( - protocolContext.getBlockchain(), - networkId, - protocolContext.getWorldStateArchive(), - transactionPool, - ethereumWireProtocolConfiguration, - ethPeers, - ethMessages, - ethContext, - peerValidators, - synchronizerConfiguration, - scheduler); - } -} diff --git a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java index d7a4e2f20f..d08fcc6c5b 100644 --- a/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java +++ b/besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java @@ -14,7 +14,6 @@ */ package org.hyperledger.besu.chainimport; -import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -37,12 +36,9 @@ import org.hyperledger.besu.testutil.TestClock; import java.io.IOException; import java.math.BigInteger; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import java.util.concurrent.CompletionException; -import com.google.common.io.Resources; import org.apache.tuweni.units.bigints.UInt256; import org.junit.Rule; import org.junit.Test; @@ -147,45 +143,4 @@ public final class RlpBlockImporterTest { assertThat(result.count).isEqualTo(1); assertThat(result.td).isEqualTo(UInt256.valueOf(34351349760L)); } - - @Test - public void ibftImport() throws IOException { - final Path dataDir = folder.newFolder().toPath(); - final Path source = dataDir.resolve("ibft.blocks"); - final String config = - Resources.toString(this.getClass().getResource("/ibftlegacy_genesis.json"), UTF_8); - - try { - Files.write( - source, - Resources.toByteArray(this.getClass().getResource("/ibft.blocks")), - StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING); - } catch (final IOException ex) { - throw new IllegalStateException(ex); - } - - final BesuController controller = - new BesuController.Builder() - .fromGenesisConfig(GenesisConfigFile.fromConfig(config), SyncMode.FULL) - .synchronizerConfiguration(SynchronizerConfiguration.builder().build()) - .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) - .storageProvider(new InMemoryKeyValueStorageProvider()) - .networkId(BigInteger.valueOf(10)) - .miningParameters(new MiningParameters.Builder().miningEnabled(false).build()) - .nodeKey(NodeKeyUtils.generate()) - .metricsSystem(new NoOpMetricsSystem()) - .privacyParameters(PrivacyParameters.DEFAULT) - .dataDirectory(dataDir) - .clock(TestClock.fixed()) - .transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT) - .gasLimitCalculator(GasLimitCalculator.constant()) - .evmConfiguration(EvmConfiguration.DEFAULT) - .build(); - final RlpBlockImporter.ImportResult result = - rlpBlockImporter.importBlockchain(source, controller, false); - - // Don't count the Genesis block - assertThat(result.count).isEqualTo(958); - } } diff --git a/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java b/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java index 97c74238b2..e6b631a4e8 100644 --- a/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java +++ b/besu/src/test/java/org/hyperledger/besu/controller/BesuControllerTest.java @@ -72,7 +72,7 @@ public class BesuControllerTest { public void invalidConsensusCombination() { when(genesisConfigFile.getConfigOptions(any())).thenReturn(genesisConfigOptions); when(genesisConfigOptions.isConsensusMigration()).thenReturn(true); - // explicitly not setting isIbftLegacy() or isIbft2() for genesisConfigOptions + // explicitly not setting isIbft2() for genesisConfigOptions assertThatThrownBy( () -> new BesuController.Builder().fromGenesisConfig(genesisConfigFile, SyncMode.FULL)) @@ -101,27 +101,6 @@ public class BesuControllerTest { .isInstanceOf(QbftBesuControllerBuilder.class); } - @Test - public void createConsensusScheduleBesuControllerBuilderWhenMigratingFromIbftLegacyToQbft() { - final long qbftStartBlock = 10L; - mockGenesisConfigForMigration("ibftLegacy", OptionalLong.of(qbftStartBlock)); - - final BesuControllerBuilder besuControllerBuilder = - new BesuController.Builder().fromGenesisConfig(genesisConfigFile, SyncMode.FULL); - - assertThat(besuControllerBuilder).isInstanceOf(ConsensusScheduleBesuControllerBuilder.class); - - final Map besuControllerBuilderSchedule = - ((ConsensusScheduleBesuControllerBuilder) besuControllerBuilder) - .getBesuControllerBuilderSchedule(); - - assertThat(besuControllerBuilderSchedule).containsKeys(0L, qbftStartBlock); - assertThat(besuControllerBuilderSchedule.get(0L)) - .isInstanceOf(IbftLegacyBesuControllerBuilder.class); - assertThat(besuControllerBuilderSchedule.get(qbftStartBlock)) - .isInstanceOf(QbftBesuControllerBuilder.class); - } - private void mockGenesisConfigForMigration( final String consensus, final OptionalLong startBlock) { when(genesisConfigFile.getConfigOptions(any())).thenReturn(genesisConfigOptions); @@ -133,11 +112,6 @@ public class BesuControllerTest { when(genesisConfigOptions.isIbft2()).thenReturn(true); break; } - case "ibftlegacy": - { - when(genesisConfigOptions.isIbftLegacy()).thenReturn(true); - break; - } default: fail("Invalid consensus algorithm"); } diff --git a/besu/src/test/resources/ibftlegacy_genesis.json b/besu/src/test/resources/ibftlegacy_genesis.json deleted file mode 100644 index 6930159d99..0000000000 --- a/besu/src/test/resources/ibftlegacy_genesis.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "config": { - "chainId": 2017, - "homesteadBlock": 0, - "eip150Block": 0, - "eip158Block": 0, - - "ibft": { - "epochLength": 30000, - "blockPeriodSeconds" : 1, - "requestTimeoutSeconds": 10 - } - }, - "nonce": "0x0", - "timestamp": "0x5b3c3d18", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f89af85494c332d0db1704d18f89a590e7586811e36d37ce049424defc2d149861d3d245749b81fe0e6b28e04f31943814f17bd4b7ce47ab8146684b3443c0a4b2fc2c942a813d7db3de19b07f92268b6d4125ed295cbe00b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0", - "gasLimit": "0x47b760", - "difficulty": "0x1", - "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "24defc2d149861d3d245749b81fe0e6b28e04f31": { - "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" - }, - "2a813d7db3de19b07f92268b6d4125ed295cbe00": { - "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" - }, - "3814f17bd4b7ce47ab8146684b3443c0a4b2fc2c": { - "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" - }, - "c332d0db1704d18f89a590e7586811e36d37ce04": { - "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java index fe92131c01..d144884e02 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -44,7 +44,7 @@ public interface GenesisConfigOptions { boolean isKeccak256(); /** - * Is ibft legacy boolean. + * Is ibft legacy boolean (NOTE this is a deprecated feature). * * @return the boolean */ @@ -77,7 +77,7 @@ public interface GenesisConfigOptions { * @return the boolean */ default boolean isConsensusMigration() { - return (isIbft2() || isIbftLegacy()) && isQbft(); + return isIbft2() && isQbft(); } /** @@ -87,13 +87,6 @@ public interface GenesisConfigOptions { */ String getConsensusEngine(); - /** - * Gets ibft legacy config options. - * - * @return the ibft legacy config options - */ - IbftLegacyConfigOptions getIbftLegacyConfigOptions(); - /** * Gets checkpoint options. * diff --git a/config/src/main/java/org/hyperledger/besu/config/IbftLegacyConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/IbftLegacyConfigOptions.java deleted file mode 100644 index 112fdfadc5..0000000000 --- a/config/src/main/java/org/hyperledger/besu/config/IbftLegacyConfigOptions.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.config; - -import java.util.Map; - -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.ImmutableMap; - -/** The Ibft legacy config options. */ -public class IbftLegacyConfigOptions { - - /** The constant DEFAULT. */ - public static final IbftLegacyConfigOptions DEFAULT = - new IbftLegacyConfigOptions(JsonUtil.createEmptyObjectNode()); - - private static final long DEFAULT_EPOCH_LENGTH = 30_000; - private static final int DEFAULT_BLOCK_PERIOD_SECONDS = 1; - private static final int DEFAULT_ROUND_EXPIRY_SECONDS = 1; - private static final long DEFAULT_CEIL_2N_BY_3_BLOCK = 0L; - - private final ObjectNode ibftConfigRoot; - - /** - * Instantiates a new Ibft legacy config options. - * - * @param ibftConfigRoot the ibft config root - */ - IbftLegacyConfigOptions(final ObjectNode ibftConfigRoot) { - this.ibftConfigRoot = ibftConfigRoot; - } - - /** - * Gets epoch length. - * - * @return the epoch length - */ - public long getEpochLength() { - return JsonUtil.getLong(ibftConfigRoot, "epochlength", DEFAULT_EPOCH_LENGTH); - } - - /** - * Gets block period seconds. - * - * @return the block period seconds - */ - public int getBlockPeriodSeconds() { - return JsonUtil.getPositiveInt( - ibftConfigRoot, "blockperiodseconds", DEFAULT_BLOCK_PERIOD_SECONDS); - } - - /** - * Gets request timeout seconds. - * - * @return the request timeout seconds - */ - public int getRequestTimeoutSeconds() { - return JsonUtil.getInt(ibftConfigRoot, "requesttimeoutseconds", DEFAULT_ROUND_EXPIRY_SECONDS); - } - - /** - * Gets ceil 2N by 3 block. - * - * @return the ceil 2N by 3 block - */ - public long getCeil2Nby3Block() { - return JsonUtil.getLong(ibftConfigRoot, "ceil2nby3block", DEFAULT_CEIL_2N_BY_3_BLOCK); - } - - /** - * As map. - * - * @return the map - */ - Map asMap() { - final ImmutableMap.Builder builder = ImmutableMap.builder(); - if (ibftConfigRoot.has("epochlength")) { - builder.put("epochLength", getEpochLength()); - } - if (ibftConfigRoot.has("blockperiodseconds")) { - builder.put("blockPeriodSeconds", getBlockPeriodSeconds()); - } - if (ibftConfigRoot.has("requesttimeoutseconds")) { - builder.put("requestTimeoutSeconds", getRequestTimeoutSeconds()); - } - if (ibftConfigRoot.has("ceil2nby3block")) { - builder.put("ceil2nby3block", getCeil2Nby3Block()); - } - - return builder.build(); - } -} diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java index 2f66ab343b..5bb5d9e7c1 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -113,8 +113,6 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { return KECCAK256_CONFIG_KEY; } else if (isIbft2()) { return IBFT2_CONFIG_KEY; - } else if (isIbftLegacy()) { - return IBFT_LEGACY_CONFIG_KEY; } else if (isQbft()) { return QBFT_CONFIG_KEY; } else if (isClique()) { @@ -154,13 +152,6 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { return configRoot.has(QBFT_CONFIG_KEY); } - @Override - public IbftLegacyConfigOptions getIbftLegacyConfigOptions() { - return JsonUtil.getObjectNode(configRoot, IBFT_LEGACY_CONFIG_KEY) - .map(IbftLegacyConfigOptions::new) - .orElse(IbftLegacyConfigOptions.DEFAULT); - } - @Override public BftConfigOptions getBftConfigOptions() { final String fieldKey = isIbft2() ? IBFT2_CONFIG_KEY : QBFT_CONFIG_KEY; @@ -503,9 +494,6 @@ public class JsonGenesisConfigOptions implements GenesisConfigOptions { if (isKeccak256()) { builder.put("keccak256", getKeccak256ConfigOptions().asMap()); } - if (isIbftLegacy()) { - builder.put("ibft", getIbftLegacyConfigOptions().asMap()); - } if (isIbft2()) { builder.put("ibft2", getBftConfigOptions().asMap()); } diff --git a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java index d391e04100..bd4313ddef 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -121,11 +121,6 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable return false; } - @Override - public IbftLegacyConfigOptions getIbftLegacyConfigOptions() { - return IbftLegacyConfigOptions.DEFAULT; - } - @Override public CheckpointConfigOptions getCheckpointOptions() { return CheckpointConfigOptions.DEFAULT; @@ -402,9 +397,6 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable if (isKeccak256()) { builder.put("keccak256", getKeccak256ConfigOptions().asMap()); } - if (isIbftLegacy()) { - builder.put("ibft", getIbftLegacyConfigOptions().asMap()); - } if (isIbft2()) { builder.put("ibft2", getBftConfigOptions().asMap()); } diff --git a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java index a106e65065..7d13fac6c3 100644 --- a/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java @@ -55,25 +55,9 @@ public class GenesisConfigOptionsTest { assertThat(config.isKeccak256()).isFalse(); } - @Test - public void shouldUseIbftLegacyWhenIbftInConfig() { - final GenesisConfigOptions config = fromConfigOptions(singletonMap("ibft", emptyMap())); - assertThat(config.isIbftLegacy()).isTrue(); - assertThat(config.getIbftLegacyConfigOptions()).isNotSameAs(IbftLegacyConfigOptions.DEFAULT); - assertThat(config.getConsensusEngine()).isEqualTo("ibft"); - } - - @Test - public void shouldNotUseIbftLegacyIfIbftNotPresent() { - final GenesisConfigOptions config = fromConfigOptions(emptyMap()); - assertThat(config.isIbftLegacy()).isFalse(); - assertThat(config.getIbftLegacyConfigOptions()).isSameAs(IbftLegacyConfigOptions.DEFAULT); - } - @Test public void shouldUseIbft2WhenIbft2InConfig() { final GenesisConfigOptions config = fromConfigOptions(singletonMap("ibft2", emptyMap())); - assertThat(config.isIbftLegacy()).isFalse(); assertThat(config.isIbft2()).isTrue(); assertThat(config.getConsensusEngine()).isEqualTo("ibft2"); } @@ -264,7 +248,6 @@ public class GenesisConfigOptionsTest { public void shouldSupportEmptyGenesisConfig() { final GenesisConfigOptions config = GenesisConfigFile.fromConfig("{}").getConfigOptions(); assertThat(config.isEthHash()).isFalse(); - assertThat(config.isIbftLegacy()).isFalse(); assertThat(config.isClique()).isFalse(); assertThat(config.getHomesteadBlockNumber()).isEmpty(); } diff --git a/config/src/test/java/org/hyperledger/besu/config/JsonGenesisConfigOptionsTest.java b/config/src/test/java/org/hyperledger/besu/config/JsonGenesisConfigOptionsTest.java index f33dd17f8e..2e36bf3ca1 100644 --- a/config/src/test/java/org/hyperledger/besu/config/JsonGenesisConfigOptionsTest.java +++ b/config/src/test/java/org/hyperledger/besu/config/JsonGenesisConfigOptionsTest.java @@ -233,28 +233,6 @@ public class JsonGenesisConfigOptionsTest { assertThat(configOptions.isConsensusMigration()).isTrue(); } - @Test - public void configWithMigrationFromIbftLegacyToQbft() { - final ObjectNode configNode = loadConfigWithMigrationFromIbftLegacyToQbft(); - - final JsonGenesisConfigOptions configOptions = - JsonGenesisConfigOptions.fromJsonObject(configNode); - - assertThat(configOptions.isIbftLegacy()).isTrue(); - assertThat(configOptions.isQbft()).isTrue(); - assertThat(configOptions.isConsensusMigration()).isTrue(); - } - - @Test - public void configWithoutMigration() { - final ObjectNode configNode = loadCompleteDataSet(); - - final JsonGenesisConfigOptions configOptions = - JsonGenesisConfigOptions.fromJsonObject(configNode); - - assertThat(configOptions.isIbftLegacy()).isFalse(); - } - private ObjectNode loadConfigWithMigrationFromIbft2ToQbft() { try { final String configText = @@ -266,12 +244,4 @@ public class JsonGenesisConfigOptionsTest { throw new RuntimeException("Failed to load resource", e); } } - - private ObjectNode loadConfigWithMigrationFromIbftLegacyToQbft() { - ObjectNode configNode = loadConfigWithMigrationFromIbft2ToQbft(); - JsonNode consensusConfig = configNode.get("ibft2"); - configNode.remove("ibft2"); - configNode.set("ibft", consensusConfig); - return configNode; - } } diff --git a/consensus/ibftlegacy/build.gradle b/consensus/ibftlegacy/build.gradle deleted file mode 100644 index 3c4fdc8c56..0000000000 --- a/consensus/ibftlegacy/build.gradle +++ /dev/null @@ -1,51 +0,0 @@ -apply plugin: 'java-library' - -jar { - archiveBaseName = 'besu-ibftlegacy' - manifest { - attributes( - 'Specification-Title': archiveBaseName, - 'Specification-Version': project.version, - 'Implementation-Title': archiveBaseName, - 'Implementation-Version': calculateVersion() - ) - } -} - -dependencies { - implementation project(':config') - implementation project(':consensus:common') - implementation project(':consensus:ibft') - implementation project(':crypto:algorithms') - implementation project(':datatypes') - implementation project(':ethereum:api') - implementation project(':ethereum:blockcreation') - implementation project(':ethereum:core') - implementation project(':ethereum:eth') - implementation project(':ethereum:p2p') - implementation project(':ethereum:rlp') - implementation project(':evm') - implementation project(':metrics:core') - implementation project(':services:kvstore') - - implementation 'com.google.guava:guava' - implementation 'io.vertx:vertx-core' - implementation 'com.fasterxml.jackson.core:jackson-databind' - implementation 'org.apache.tuweni:tuweni-bytes' - implementation 'org.apache.tuweni:tuweni-units' - - testImplementation project(path: ':consensus:common', configuration: 'testSupportArtifacts') - testImplementation project(path: ':consensus:ibft', configuration: 'testSupportArtifacts') - testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') - testImplementation project(path: ':ethereum:eth', configuration: 'testSupportArtifacts') - testImplementation project(':metrics:core') - testImplementation project(':testutil') - - testImplementation 'junit:junit' - testImplementation 'org.assertj:assertj-core' - testImplementation 'org.awaitility:awaitility' - testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.mockito:mockito-core' - - testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHashing.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHashing.java deleted file mode 100644 index 4b60f028a4..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHashing.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Util; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; - -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import org.apache.tuweni.bytes.Bytes; - -/** The Ibft block hashing. */ -public class IbftBlockHashing { - - private static final Bytes COMMIT_MSG_CODE = Bytes.wrap(new byte[] {2}); - - /** - * Constructs a hash of the block header, suitable for use when creating the proposer seal. The - * extra data is modified to have a null proposer seal and empty list of committed seals. - * - * @param header The header for which a proposer seal is to be calculated - * @param ibftExtraData The extra data block which is to be inserted to the header once seal is - * calculated - * @return the hash of the header suitable for signing as the proposer seal - */ - public static Hash calculateDataHashForProposerSeal( - final BlockHeader header, final IbftExtraData ibftExtraData) { - final Bytes headerRlp = - serializeHeader(header, () -> encodeExtraDataWithoutCommittedSeals(ibftExtraData, null)); - - // Proposer hash is the hash of the hash - return Hash.hash(Hash.hash(headerRlp)); - } - - /** - * Constructs a hash of the block header suitable for signing as a committed seal. The extra data - * in the hash uses an empty list for the committed seals. - * - * @param header The header for which a proposer seal is to be calculated (without extra data) - * @param ibftExtraData The extra data block which is to be inserted to the header once seal is - * calculated - * @return the hash of the header including the validator and proposer seal in the extra data - */ - public static Hash calculateDataHashForCommittedSeal( - final BlockHeader header, final IbftExtraData ibftExtraData) { - // The data signed by a committer is an array of [Hash, COMMIT_MSG_CODE] - final Hash dataHash = Hash.hash(serializeHeaderWithoutCommittedSeals(header, ibftExtraData)); - final Bytes seal = Bytes.wrap(dataHash, COMMIT_MSG_CODE); - return Hash.hash(seal); - } - - /** - * Constructs a hash of the block header, but omits the committerSeals (as this changes on each of - * the potentially circulated blocks at the current chain height). - * - * @param header The header for which a block hash is to be calculated - * @return the hash of the header including the validator and proposer seal in the extra data - */ - public static Hash calculateHashOfIbftBlockOnchain(final BlockHeader header) { - final IbftExtraData ibftExtraData = IbftExtraData.decode(header); - return Hash.hash(serializeHeaderWithoutCommittedSeals(header, ibftExtraData)); - } - - private static Bytes serializeHeaderWithoutCommittedSeals( - final BlockHeader header, final IbftExtraData ibftExtraData) { - return serializeHeader( - header, - () -> encodeExtraDataWithoutCommittedSeals(ibftExtraData, ibftExtraData.getProposerSeal())); - } - - /** - * Recovers the proposer's {@link Address} from the proposer seal. - * - * @param header the block header that was signed by the proposer seal - * @param ibftExtraData the parsed IBftExtraData from the header - * @return the proposer address - */ - public static Address recoverProposerAddress( - final BlockHeader header, final IbftExtraData ibftExtraData) { - final Hash proposerHash = calculateDataHashForProposerSeal(header, ibftExtraData); - return Util.signatureToAddress(ibftExtraData.getProposerSeal(), proposerHash); - } - - /** - * Recovers the {@link Address} for each validator that contributed a committed seal to the block. - * - * @param header the block header that was signed by the committed seals - * @param ibftExtraData the parsed IBftExtraData from the header - * @return the addresses of validators that provided a committed seal - */ - public static List
recoverCommitterAddresses( - final BlockHeader header, final IbftExtraData ibftExtraData) { - final Hash committerHash = - IbftBlockHashing.calculateDataHashForCommittedSeal(header, ibftExtraData); - - return ibftExtraData.getSeals().stream() - .map(p -> Util.signatureToAddress(p, committerHash)) - .collect(Collectors.toList()); - } - - private static Bytes encodeExtraDataWithoutCommittedSeals( - final IbftExtraData ibftExtraData, final SECPSignature proposerSeal) { - final BytesValueRLPOutput extraDataEncoding = new BytesValueRLPOutput(); - extraDataEncoding.startList(); - extraDataEncoding.writeList( - ibftExtraData.getValidators(), (validator, rlp) -> rlp.writeBytes(validator)); - - if (proposerSeal != null) { - extraDataEncoding.writeBytes(proposerSeal.encodedBytes()); - } else { - extraDataEncoding.writeNull(); - } - - // Represents an empty committer list (i.e this is not included in the hashing of the block) - extraDataEncoding.startList(); - extraDataEncoding.endList(); - - extraDataEncoding.endList(); - - return Bytes.wrap(ibftExtraData.getVanityData(), extraDataEncoding.encoded()); - } - - private static Bytes serializeHeader( - final BlockHeader header, final Supplier extraDataSerializer) { - final BytesValueRLPOutput out = new BytesValueRLPOutput(); - out.startList(); - - out.writeBytes(header.getParentHash()); - out.writeBytes(header.getOmmersHash()); - out.writeBytes(header.getCoinbase()); - out.writeBytes(header.getStateRoot()); - out.writeBytes(header.getTransactionsRoot()); - out.writeBytes(header.getReceiptsRoot()); - out.writeBytes(header.getLogsBloom()); - out.writeBytes(header.getDifficulty().toMinimalBytes()); - out.writeLongScalar(header.getNumber()); - out.writeLongScalar(header.getGasLimit()); - out.writeLongScalar(header.getGasUsed()); - out.writeLongScalar(header.getTimestamp()); - // Cannot decode an IbftExtraData on block 0 due to missing/illegal signatures - if (header.getNumber() == 0) { - out.writeBytes(header.getExtraData()); - } else { - out.writeBytes(extraDataSerializer.get()); - } - out.writeBytes(header.getMixHash()); - out.writeLong(header.getNonce()); - out.endList(); - return out.encoded(); - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactory.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactory.java deleted file mode 100644 index f971411373..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MAX_GAS_LIMIT; -import static org.hyperledger.besu.ethereum.mainnet.AbstractGasLimitSpecification.DEFAULT_MIN_GAS_LIMIT; - -import org.hyperledger.besu.consensus.ibftlegacy.headervalidationrules.IbftExtraDataValidationRule; -import org.hyperledger.besu.consensus.ibftlegacy.headervalidationrules.VoteValidationRule; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; -import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.AncestryValidationRule; -import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.ConstantFieldValidationRule; -import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasLimitRangeAndDeltaValidationRule; -import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.GasUsageValidationRule; -import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampBoundedByFutureParameter; -import org.hyperledger.besu.ethereum.mainnet.headervalidationrules.TimestampMoreRecentThanParent; - -import org.apache.tuweni.units.bigints.UInt256; - -/** The Ibft block header validation ruleset factory. */ -public class IbftBlockHeaderValidationRulesetFactory { - - /** - * Produces a BlockHeaderValidator configured for assessing ibft block headers which are to form - * part of the BlockChain (i.e. not proposed blocks, which do not contain commit seals) - * - * @param secondsBetweenBlocks the minimum number of seconds which must elapse between blocks. - * @param ceil2nBy3Block the block after which 2/3n commit seals must exist, rather than 2F+1 - * @return BlockHeaderValidator configured for assessing ibft block headers - */ - public static BlockHeaderValidator.Builder ibftBlockHeaderValidator( - final long secondsBetweenBlocks, final long ceil2nBy3Block) { - return createValidator(secondsBetweenBlocks, true, ceil2nBy3Block); - } - - /** - * Produces a BlockHeaderValidator configured for assessing IBFT proposed blocks (i.e. blocks - * which need to be vetted by the validators, and do not contain commit seals). - * - * @param secondsBetweenBlocks the minimum number of seconds which must elapse between blocks. - * @return BlockHeaderValidator configured for assessing ibft block headers - */ - public static BlockHeaderValidator.Builder ibftProposedBlockValidator( - final long secondsBetweenBlocks) { - return createValidator(secondsBetweenBlocks, false, 0); - } - - private static BlockHeaderValidator.Builder createValidator( - final long secondsBetweenBlocks, - final boolean validateCommitSeals, - final long ceil2nBy3Block) { - return new BlockHeaderValidator.Builder() - .addRule(new AncestryValidationRule()) - .addRule(new GasUsageValidationRule()) - .addRule( - new GasLimitRangeAndDeltaValidationRule(DEFAULT_MIN_GAS_LIMIT, DEFAULT_MAX_GAS_LIMIT)) - .addRule(new TimestampBoundedByFutureParameter(1)) - .addRule(new TimestampMoreRecentThanParent(secondsBetweenBlocks)) - .addRule( - new ConstantFieldValidationRule<>( - "MixHash", BlockHeader::getMixHash, IbftHelpers.EXPECTED_MIX_HASH)) - .addRule( - new ConstantFieldValidationRule<>( - "OmmersHash", BlockHeader::getOmmersHash, Hash.EMPTY_LIST_HASH)) - .addRule( - new ConstantFieldValidationRule<>( - "Difficulty", BlockHeader::getDifficulty, UInt256.ONE)) - .addRule(new VoteValidationRule()) - .addRule(new IbftExtraDataValidationRule(validateCommitSeals, ceil2nBy3Block)); - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftExtraData.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftExtraData.java deleted file mode 100644 index 73779fd634..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftExtraData.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.ParsedExtraData; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.rlp.RLPInput; - -import java.util.Collection; - -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import org.apache.tuweni.bytes.Bytes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Represents the data structure stored in the extraData field of the BlockHeader used when - * operating under an IBFT consensus mechanism. - */ -public class IbftExtraData implements ParsedExtraData { - private static final Logger LOG = LoggerFactory.getLogger(IbftExtraData.class); - - /** The constant EXTRA_VANITY_LENGTH. */ - public static final int EXTRA_VANITY_LENGTH = 32; - - private static final Supplier SIGNATURE_ALGORITHM = - Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - - private final Bytes vanityData; - private final Collection seals; - private final SECPSignature proposerSeal; - private final Collection
validators; - - /** - * Instantiates a new Ibft extra data. - * - * @param vanityData the vanity data - * @param seals the seals - * @param proposerSeal the proposer seal - * @param validators the validators - */ - public IbftExtraData( - final Bytes vanityData, - final Collection seals, - final SECPSignature proposerSeal, - final Collection
validators) { - - checkNotNull(vanityData); - checkNotNull(seals); - checkNotNull(validators); - - this.vanityData = vanityData; - this.seals = seals; - this.proposerSeal = proposerSeal; - this.validators = validators; - } - - /** - * Decode header and return ibft extra data. - * - * @param header the header - * @return the ibft extra data - */ - public static IbftExtraData decode(final BlockHeader header) { - final Object inputExtraData = header.getParsedExtraData(); - if (inputExtraData instanceof IbftExtraData) { - return (IbftExtraData) inputExtraData; - } - LOG.warn( - "Expected a IbftExtraData instance but got {}. Reparsing required.", - inputExtraData != null ? inputExtraData.getClass().getName() : "null"); - return decodeRaw(header.getExtraData()); - } - - /** - * Decode raw input and return ibft extra data. - * - * @param input the input - * @return the ibft extra data - */ - static IbftExtraData decodeRaw(final Bytes input) { - checkArgument( - input.size() > EXTRA_VANITY_LENGTH, - "Invalid Bytes supplied - too short to produce a valid IBFT Extra Data object."); - - final Bytes vanityData = input.slice(0, EXTRA_VANITY_LENGTH); - - final Bytes rlpData = input.slice(EXTRA_VANITY_LENGTH); - final RLPInput rlpInput = new BytesValueRLPInput(rlpData, false); - - rlpInput.enterList(); // This accounts for the "root node" which contains IBFT data items. - final Collection
validators = rlpInput.readList(Address::readFrom); - final SECPSignature proposerSeal = parseProposerSeal(rlpInput); - final Collection seals = - rlpInput.readList(rlp -> SIGNATURE_ALGORITHM.get().decodeSignature(rlp.readBytes())); - rlpInput.leaveList(); - - return new IbftExtraData(vanityData, seals, proposerSeal, validators); - } - - private static SECPSignature parseProposerSeal(final RLPInput rlpInput) { - final Bytes data = rlpInput.readBytes(); - return data.isZero() ? null : SIGNATURE_ALGORITHM.get().decodeSignature(data); - } - - /** - * Encode extra data to bytes. - * - * @return the bytes - */ - public Bytes encode() { - final BytesValueRLPOutput encoder = new BytesValueRLPOutput(); - encoder.startList(); - encoder.writeList(validators, (validator, rlp) -> rlp.writeBytes(validator)); - if (proposerSeal != null) { - encoder.writeBytes(proposerSeal.encodedBytes()); - } else { - encoder.writeNull(); - } - encoder.writeList(seals, (committer, rlp) -> rlp.writeBytes(committer.encodedBytes())); - encoder.endList(); - - return Bytes.wrap(vanityData, encoder.encoded()); - } - - /** - * Gets vanity data. - * - * @return the vanity data - */ - // Accessors - public Bytes getVanityData() { - return vanityData; - } - - /** - * Gets seals. - * - * @return the seals - */ - public Collection getSeals() { - return seals; - } - - /** - * Gets proposer seal. - * - * @return the proposer seal - */ - public SECPSignature getProposerSeal() { - return proposerSeal; - } - - /** - * Gets validators. - * - * @return the validators - */ - public Collection
getValidators() { - return validators; - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftHelpers.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftHelpers.java deleted file mode 100644 index 7b5b3c72fe..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftHelpers.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import org.hyperledger.besu.datatypes.Hash; - -/** The Ibft helpers utility class. */ -public class IbftHelpers { - - /** The constant EXPECTED_MIX_HASH. */ - public static final Hash EXPECTED_MIX_HASH = - Hash.fromHexString("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365"); - - /** - * Calculate required validator quorum. - * - * @param validatorCount the validator count - * @return the int - */ - public static int calculateRequiredValidatorQuorum(final int validatorCount) { - final int F = (validatorCount - 1) / 3; - return (2 * F) + 1; - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterface.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterface.java deleted file mode 100644 index baa49ad20d..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterface.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import org.hyperledger.besu.consensus.common.BlockInterface; -import org.hyperledger.besu.consensus.common.validator.ValidatorVote; -import org.hyperledger.besu.consensus.common.validator.VoteType; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; - -import java.util.Collection; -import java.util.Optional; - -import com.google.common.collect.ImmutableBiMap; -import org.apache.tuweni.bytes.Bytes; - -/** The Ibft legacy block interface. */ -public class IbftLegacyBlockInterface implements BlockInterface { - - /** The constant NO_VOTE_SUBJECT. */ - public static final Address NO_VOTE_SUBJECT = Address.wrap(Bytes.wrap(new byte[Address.SIZE])); - - /** The constant ADD_NONCE. */ - public static final long ADD_NONCE = 0xFFFFFFFFFFFFFFFFL; - /** The constant DROP_NONCE. */ - public static final long DROP_NONCE = 0x0L; - - private static final ImmutableBiMap voteToValue = - ImmutableBiMap.of( - VoteType.ADD, ADD_NONCE, - VoteType.DROP, DROP_NONCE); - - @Override - public Address getProposerOfBlock(final BlockHeader header) { - final IbftExtraData ibftExtraData = IbftExtraData.decode(header); - return IbftBlockHashing.recoverProposerAddress(header, ibftExtraData); - } - - @Override - public Address getProposerOfBlock(final org.hyperledger.besu.plugin.data.BlockHeader header) { - return getProposerOfBlock( - BlockHeader.convertPluginBlockHeader(header, new LegacyIbftBlockHeaderFunctions())); - } - - @Override - public Optional extractVoteFromHeader(final BlockHeader header) { - final Address candidate = header.getCoinbase(); - if (!candidate.equals(NO_VOTE_SUBJECT)) { - final Address proposer = getProposerOfBlock(header); - final VoteType votePolarity = voteToValue.inverse().get(header.getNonce()); - final Address recipient = header.getCoinbase(); - - return Optional.of(new ValidatorVote(votePolarity, proposer, recipient)); - } - return Optional.empty(); - } - - /** - * Insert vote to header builder and return block header builder. - * - * @param builder the builder - * @param vote the vote - * @return the block header builder - */ - public static BlockHeaderBuilder insertVoteToHeaderBuilder( - final BlockHeaderBuilder builder, final Optional vote) { - if (vote.isPresent()) { - final ValidatorVote voteToCast = vote.get(); - builder.nonce(voteToValue.get(voteToCast.getVotePolarity())); - builder.coinbase(voteToCast.getRecipient()); - } else { - builder.nonce(voteToValue.get(VoteType.DROP)); - builder.coinbase(NO_VOTE_SUBJECT); - } - return builder; - } - - @Override - public Collection
validatorsInBlock(final BlockHeader header) { - return IbftExtraData.decode(header).getValidators(); - } - - /** - * Is valid vote value. - * - * @param value the value - * @return the boolean - */ - public static boolean isValidVoteValue(final long value) { - return voteToValue.values().contains(value); - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftProtocolSchedule.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftProtocolSchedule.java deleted file mode 100644 index 1a8b5fe7de..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/IbftProtocolSchedule.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHeaderValidationRulesetFactory.ibftBlockHeaderValidator; - -import org.hyperledger.besu.config.GenesisConfigOptions; -import org.hyperledger.besu.config.IbftLegacyConfigOptions; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; -import org.hyperledger.besu.ethereum.mainnet.MainnetBlockBodyValidator; -import org.hyperledger.besu.ethereum.mainnet.MainnetBlockImporter; -import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSpecs; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder; -import org.hyperledger.besu.evm.internal.EvmConfiguration; - -import java.math.BigInteger; - -/** Defines the protocol behaviours for a blockchain using IBFT. */ -public class IbftProtocolSchedule { - - private static final BigInteger DEFAULT_CHAIN_ID = BigInteger.ONE; - - /** - * Create protocol schedule. - * - * @param config the config - * @param privacyParameters the privacy parameters - * @param isRevertReasonEnabled the is revert reason enabled - * @param evmConfiguration the evm configuration - * @return the protocol schedule - */ - public static ProtocolSchedule create( - final GenesisConfigOptions config, - final PrivacyParameters privacyParameters, - final boolean isRevertReasonEnabled, - final EvmConfiguration evmConfiguration) { - final IbftLegacyConfigOptions ibftConfig = config.getIbftLegacyConfigOptions(); - final long blockPeriod = ibftConfig.getBlockPeriodSeconds(); - - return new ProtocolScheduleBuilder( - config, - DEFAULT_CHAIN_ID, - ProtocolSpecAdapters.create( - 0, - builder -> - applyIbftChanges( - blockPeriod, builder, config.isQuorum(), ibftConfig.getCeil2Nby3Block())), - privacyParameters, - isRevertReasonEnabled, - config.isQuorum(), - evmConfiguration) - .createProtocolSchedule(); - } - - /** - * Create protocol schedule. - * - * @param config the config - * @param isRevertReasonEnabled the is revert reason enabled - * @param evmConfiguration the evm configuration - * @return the protocol schedule - */ - public static ProtocolSchedule create( - final GenesisConfigOptions config, - final boolean isRevertReasonEnabled, - final EvmConfiguration evmConfiguration) { - return create(config, PrivacyParameters.DEFAULT, isRevertReasonEnabled, evmConfiguration); - } - - private static ProtocolSpecBuilder applyIbftChanges( - final long secondsBetweenBlocks, - final ProtocolSpecBuilder builder, - final boolean goQuorumMode, - final long ceil2nBy3Block) { - return builder - .blockHeaderValidatorBuilder( - feeMarket -> ibftBlockHeaderValidator(secondsBetweenBlocks, ceil2nBy3Block)) - .ommerHeaderValidatorBuilder( - feeMarket -> ibftBlockHeaderValidator(secondsBetweenBlocks, ceil2nBy3Block)) - .blockBodyValidatorBuilder(MainnetBlockBodyValidator::new) - .blockValidatorBuilder(MainnetProtocolSpecs.blockValidatorBuilder(goQuorumMode)) - .blockImporterBuilder(MainnetBlockImporter::new) - .difficultyCalculator((time, parent, protocolContext) -> BigInteger.ONE) - .blockReward(Wei.ZERO) - .skipZeroBlockRewards(true) - .blockHeaderFunctions(new LegacyIbftBlockHeaderFunctions()); - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/LegacyIbftBlockHeaderFunctions.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/LegacyIbftBlockHeaderFunctions.java deleted file mode 100644 index 5486f859b6..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/LegacyIbftBlockHeaderFunctions.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; - -/** The Legacy ibft block header functions. */ -public class LegacyIbftBlockHeaderFunctions implements BlockHeaderFunctions { - - @Override - public Hash hash(final BlockHeader header) { - return IbftBlockHashing.calculateHashOfIbftBlockOnchain(header); - } - - @Override - public IbftExtraData parseExtraData(final BlockHeader header) { - return IbftExtraData.decodeRaw(header.getExtraData()); - } - - @Override - public int getCheckPointWindowSize(final BlockHeader header) { - return IbftExtraData.decodeRaw(header.getExtraData()).getValidators().size(); - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/IbftBlockCreator.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/IbftBlockCreator.java deleted file mode 100644 index bb8ccac64a..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/IbftBlockCreator.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.blockcreation; - -import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHashing; -import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData; -import org.hyperledger.besu.consensus.ibftlegacy.IbftHelpers; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.blockcreation.AbstractBlockCreator; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; -import org.hyperledger.besu.ethereum.core.SealableBlockHeader; -import org.hyperledger.besu.ethereum.core.Util; -import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; - -import java.util.Optional; -import java.util.function.Supplier; - -/** - * Responsible for producing a Block which conforms to IBFT validation rules (other than missing - * commit seals). Transactions and associated Hashes (stateroot, receipts etc.) are loaded into the - * Block in the base class as part of the transaction selection process. - */ -public class IbftBlockCreator extends AbstractBlockCreator { - - private final KeyPair nodeKeys; - - /** - * Instantiates a new Ibft block creator. - * - * @param coinbase the coinbase - * @param targetGasLimitSupplier the target gas limit supplier - * @param extraDataCalculator the extra data calculator - * @param pendingTransactions the pending transactions - * @param protocolContext the protocol context - * @param protocolSchedule the protocol schedule - * @param nodeKeys the node keys - * @param minTransactionGasPrice the min transaction gas price - * @param minBlockOccupancyRatio the min block occupancy ratio - * @param parentHeader the parent header - */ - public IbftBlockCreator( - final Address coinbase, - final Supplier> targetGasLimitSupplier, - final ExtraDataCalculator extraDataCalculator, - final PendingTransactions pendingTransactions, - final ProtocolContext protocolContext, - final ProtocolSchedule protocolSchedule, - final KeyPair nodeKeys, - final Wei minTransactionGasPrice, - final Double minBlockOccupancyRatio, - final BlockHeader parentHeader) { - super( - coinbase, - __ -> Util.publicKeyToAddress(nodeKeys.getPublicKey()), - targetGasLimitSupplier, - extraDataCalculator, - pendingTransactions, - protocolContext, - protocolSchedule, - minTransactionGasPrice, - minBlockOccupancyRatio, - parentHeader); - this.nodeKeys = nodeKeys; - } - - /** - * Responsible for signing (hash of) the block (including MixHash and Nonce), and then injecting - * the seal into the extraData. This is called after a suitable set of transactions have been - * identified, and all resulting hashes have been inserted into the passed-in SealableBlockHeader. - * - * @param sealableBlockHeader A block header containing StateRoots, TransactionHashes etc. - * @return The blockhead which is to be added to the block being proposed. - */ - @Override - protected BlockHeader createFinalBlockHeader(final SealableBlockHeader sealableBlockHeader) { - - final BlockHeaderFunctions blockHeaderFunctions = - ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); - - final BlockHeaderBuilder builder = - BlockHeaderBuilder.create() - .populateFrom(sealableBlockHeader) - .mixHash(IbftHelpers.EXPECTED_MIX_HASH) - .nonce(0) - .blockHeaderFunctions(blockHeaderFunctions); - - final IbftExtraData sealedExtraData = constructSignedExtraData(builder.buildBlockHeader()); - - // Replace the extraData in the BlockHeaderBuilder, and return header. - return builder.extraData(sealedExtraData.encode()).buildBlockHeader(); - } - - /** - * Produces an IbftExtraData object with a populated proposerSeal. The signature in the block is - * generated from the Hash of the header (minus proposer and committer seals) and the nodeKeys. - * - * @param headerToSign An almost fully populated header (proposer and committer seals are empty) - * @return Extra data containing the same vanity data and validators as extraData, however - * proposerSeal will also be populated. - */ - private IbftExtraData constructSignedExtraData(final BlockHeader headerToSign) { - final IbftExtraData extraData = IbftExtraData.decode(headerToSign); - final Hash hashToSign = - IbftBlockHashing.calculateDataHashForProposerSeal(headerToSign, extraData); - return new IbftExtraData( - extraData.getVanityData(), - extraData.getSeals(), - SignatureAlgorithmFactory.getInstance().sign(hashToSign, nodeKeys), - extraData.getValidators()); - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/IbftExtraDataValidationRule.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/IbftExtraDataValidationRule.java deleted file mode 100644 index b4b4a3f336..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/IbftExtraDataValidationRule.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.headervalidationrules; - -import org.hyperledger.besu.consensus.common.bft.BftHelpers; -import org.hyperledger.besu.consensus.ibft.IbftLegacyContext; -import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHashing; -import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData; -import org.hyperledger.besu.consensus.ibftlegacy.IbftHelpers; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.mainnet.AttachedBlockHeaderValidationRule; -import org.hyperledger.besu.ethereum.rlp.RLPException; - -import java.util.Collection; -import java.util.List; -import java.util.NavigableSet; -import java.util.TreeSet; - -import com.google.common.collect.Iterables; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Ensures the byte content of the extraData field can be deserialised into an appropriate - * structure, and that the structure created contains data matching expectations from preceding - * blocks. - */ -public class IbftExtraDataValidationRule implements AttachedBlockHeaderValidationRule { - - private static final Logger LOG = LoggerFactory.getLogger(IbftExtraDataValidationRule.class); - - private final boolean validateCommitSeals; - private final long ceil2nBy3Block; - - /** - * Instantiates a new Ibft extra data validation rule. - * - * @param validateCommitSeals the validate commit seals - * @param ceil2nBy3Block the ceil 2 n by 3 block - */ - public IbftExtraDataValidationRule(final boolean validateCommitSeals, final long ceil2nBy3Block) { - this.validateCommitSeals = validateCommitSeals; - this.ceil2nBy3Block = ceil2nBy3Block; - } - - @Override - public boolean validate( - final BlockHeader header, final BlockHeader parent, final ProtocolContext context) { - try { - final Collection
storedValidators = - context - .getConsensusContext(IbftLegacyContext.class) - .getValidatorProvider() - .getValidatorsAfterBlock(parent); - final IbftExtraData ibftExtraData = IbftExtraData.decode(header); - - final Address proposer = IbftBlockHashing.recoverProposerAddress(header, ibftExtraData); - - if (!storedValidators.contains(proposer)) { - LOG.info("Invalid block header: Proposer sealing block is not a member of the validators."); - return false; - } - - if (validateCommitSeals) { - final List
committers = - IbftBlockHashing.recoverCommitterAddresses(header, ibftExtraData); - - final int minimumSealsRequired = - header.getNumber() < ceil2nBy3Block - ? IbftHelpers.calculateRequiredValidatorQuorum(storedValidators.size()) - : BftHelpers.calculateRequiredValidatorQuorum(storedValidators.size()); - - if (!validateCommitters(committers, storedValidators, minimumSealsRequired)) { - return false; - } - } - - final NavigableSet
sortedReportedValidators = - new TreeSet<>(ibftExtraData.getValidators()); - - if (!Iterables.elementsEqual(ibftExtraData.getValidators(), sortedReportedValidators)) { - LOG.info( - "Invalid block header: Validators are not sorted in ascending order. Expected {} but got {}.", - sortedReportedValidators, - ibftExtraData.getValidators()); - return false; - } - - if (!Iterables.elementsEqual(ibftExtraData.getValidators(), storedValidators)) { - LOG.info( - "Invalid block header: Incorrect validators. Expected {} but got {}.", - storedValidators, - ibftExtraData.getValidators()); - return false; - } - - } catch (final RLPException ex) { - LOG.info( - "Invalid block header: ExtraData field was unable to be deserialised into an IBFT Struct.", - ex); - return false; - } catch (final IllegalArgumentException ex) { - LOG.info("Invalid block header: Failed to verify extra data", ex); - return false; - } catch (final RuntimeException ex) { - LOG.info("Invalid block header: Failed to find validators at parent"); - return false; - } - - return true; - } - - private boolean validateCommitters( - final Collection
committers, - final Collection
storedValidators, - final int minimumSealsRequired) { - if (committers.size() < minimumSealsRequired) { - LOG.info( - "Invalid block header: Insufficient committers to seal block. (Required {}, received {})", - minimumSealsRequired, - committers.size()); - return false; - } - - if (!storedValidators.containsAll(committers)) { - LOG.info( - "Invalid block header: Not all committers are in the locally maintained validator list."); - return false; - } - - return true; - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/VoteValidationRule.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/VoteValidationRule.java deleted file mode 100644 index 8506ef8eb7..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/VoteValidationRule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.headervalidationrules; - -import org.hyperledger.besu.consensus.ibftlegacy.IbftLegacyBlockInterface; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.mainnet.DetachedBlockHeaderValidationRule; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** The Vote validation rule. */ -public class VoteValidationRule implements DetachedBlockHeaderValidationRule { - - private static final Logger LOG = LoggerFactory.getLogger(VoteValidationRule.class); - - /** - * Responsible for ensuring the nonce is either auth or drop. - * - * @param header the block header to validate - * @param parent the block header corresponding to the parent of the header being validated. - * @return true if the nonce in the header is a valid validator vote value. - */ - @Override - public boolean validate(final BlockHeader header, final BlockHeader parent) { - final long nonce = header.getNonce(); - if (!IbftLegacyBlockInterface.isValidVoteValue(nonce)) { - LOG.info("Invalid block header: Nonce value ({}) is neither auth or drop.", nonce); - return false; - } - return true; - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99Protocol.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99Protocol.java deleted file mode 100644 index 1a122cb793..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99Protocol.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.protocol; - -import org.hyperledger.besu.ethereum.eth.messages.EthPV62; -import org.hyperledger.besu.ethereum.eth.messages.EthPV63; -import org.hyperledger.besu.ethereum.eth.messages.EthPV65; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; - -import java.util.Arrays; -import java.util.List; - -/** - * Represents the istanbul/64 protocol as used by Quorum (effectively an extension of eth/65, which - * adds a single message type (0x11) to encapsulate all communications required for IBFT block - * mining. - */ -public class Istanbul99Protocol implements SubProtocol { - - /** The constant NAME. */ - public static final String NAME = "istanbul"; - - private static final int VERSION = 99; - - /** The Istanbul 99. */ - static final Capability ISTANBUL99 = Capability.create(NAME, 99); - /** The Instanbul msg. */ - static final int INSTANBUL_MSG = 0x11; - - private static final Istanbul99Protocol INSTANCE = new Istanbul99Protocol(); - - private static final List istanbul64Messages = - Arrays.asList( - EthPV62.STATUS, - EthPV62.NEW_BLOCK_HASHES, - EthPV62.TRANSACTIONS, - EthPV62.GET_BLOCK_HEADERS, - EthPV62.BLOCK_HEADERS, - EthPV62.GET_BLOCK_BODIES, - EthPV62.BLOCK_BODIES, - EthPV62.NEW_BLOCK, - EthPV65.NEW_POOLED_TRANSACTION_HASHES, - EthPV65.GET_POOLED_TRANSACTIONS, - EthPV65.POOLED_TRANSACTIONS, - EthPV63.GET_NODE_DATA, - EthPV63.NODE_DATA, - EthPV63.GET_RECEIPTS, - EthPV63.RECEIPTS, - INSTANBUL_MSG); - - @Override - public String getName() { - return NAME; - } - - @Override - public int messageSpace(final int protocolVersion) { - return INSTANBUL_MSG + 1; - } - - @Override - public boolean isValidMessageCode(final int protocolVersion, final int code) { - if (protocolVersion == VERSION) { - return istanbul64Messages.contains(code); - } - return false; - } - - @Override - public String messageName(final int protocolVersion, final int code) { - switch (code) { - case EthPV62.STATUS: - return "Status"; - case EthPV62.NEW_BLOCK_HASHES: - return "NewBlockHashes"; - case EthPV62.TRANSACTIONS: - return "Transactions"; - case EthPV62.GET_BLOCK_HEADERS: - return "GetBlockHeaders"; - case EthPV62.BLOCK_HEADERS: - return "BlockHeaders"; - case EthPV62.GET_BLOCK_BODIES: - return "GetBlockBodies"; - case EthPV62.BLOCK_BODIES: - return "BlockBodies"; - case EthPV62.NEW_BLOCK: - return "NewBlock"; - case EthPV65.NEW_POOLED_TRANSACTION_HASHES: - return "NewPooledTransactionHashes"; - case EthPV65.GET_POOLED_TRANSACTIONS: - return "GetPooledTransactions"; - case EthPV65.POOLED_TRANSACTIONS: - return "PooledTransactions"; - case EthPV63.GET_NODE_DATA: - return "GetNodeData"; - case EthPV63.NODE_DATA: - return "NodeData"; - case EthPV63.GET_RECEIPTS: - return "GetReceipts"; - case EthPV63.RECEIPTS: - return "Receipts"; - case INSTANBUL_MSG: - return "InstanbulMsg"; - default: - return INVALID_MESSAGE_NAME; - } - } - - /** - * Get istanbul99 protocol singleton instance. - * - * @return the istanbul 99 protocol instance - */ - public static Istanbul99Protocol get() { - return INSTANCE; - } -} diff --git a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManager.java b/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManager.java deleted file mode 100644 index af45044a9e..0000000000 --- a/consensus/ibftlegacy/src/main/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManager.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.protocol; - -import static java.util.Collections.singletonList; - -import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; -import org.hyperledger.besu.ethereum.eth.manager.EthContext; -import org.hyperledger.besu.ethereum.eth.manager.EthMessages; -import org.hyperledger.besu.ethereum.eth.manager.EthPeers; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; -import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; -import org.hyperledger.besu.ethereum.eth.peervalidation.PeerValidator; -import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; -import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; - -import java.math.BigInteger; -import java.util.List; -import java.util.Optional; - -/** This allows for interoperability with Quorum, but shouldn't be used otherwise. */ -public class Istanbul99ProtocolManager extends EthProtocolManager { - - /** - * Instantiates a new Istanbul99 protocol manager. - * - * @param blockchain the blockchain - * @param networkId the network id - * @param worldStateArchive the world state archive - * @param transactionPool the transaction pool - * @param ethereumWireProtocolConfiguration the ethereum wire protocol configuration - * @param ethPeers the eth peers - * @param ethMessages the eth messages - * @param ethContext the eth context - * @param peerValidators the peer validators - * @param synchronizerConfiguration the synchronizer configuration - * @param scheduler the scheduler - */ - public Istanbul99ProtocolManager( - final Blockchain blockchain, - final BigInteger networkId, - final WorldStateArchive worldStateArchive, - final TransactionPool transactionPool, - final EthProtocolConfiguration ethereumWireProtocolConfiguration, - final EthPeers ethPeers, - final EthMessages ethMessages, - final EthContext ethContext, - final List peerValidators, - final SynchronizerConfiguration synchronizerConfiguration, - final EthScheduler scheduler) { - super( - blockchain, - networkId, - worldStateArchive, - transactionPool, - ethereumWireProtocolConfiguration, - ethPeers, - ethMessages, - ethContext, - peerValidators, - Optional.empty(), - synchronizerConfiguration, - scheduler); - } - - @Override - public List getSupportedCapabilities() { - return singletonList(Istanbul99Protocol.ISTANBUL99); - } - - @Override - public String getSupportedProtocol() { - return Istanbul99Protocol.get().getName(); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftBlockHashingTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftBlockHashingTest.java deleted file mode 100644 index 1d97a0f71a..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftBlockHashingTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.core.Difficulty; -import org.hyperledger.besu.evm.log.LogsBloomFilter; - -import java.util.Arrays; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.assertj.core.api.Assertions; -import org.junit.Test; - -public class BftBlockHashingTest { - - private static final Address PROPOSER_IN_HEADER = - Address.fromHexString("0x24defc2d149861d3d245749b81fe0e6b28e04f31"); - private static final List
VALIDATORS_IN_HEADER = - Arrays.asList( - PROPOSER_IN_HEADER, - Address.fromHexString("0x2a813d7db3de19b07f92268b6d4125ed295cbe00"), - Address.fromHexString("0x3814f17bd4b7ce47ab8146684b3443c0a4b2fc2c"), - Address.fromHexString("0xc332d0db1704d18f89a590e7586811e36d37ce04")); - private static final List
COMMITTERS_IN_HEADER = - Arrays.asList( - Address.fromHexString("0x3814f17bd4b7ce47ab8146684b3443c0a4b2fc2c"), - PROPOSER_IN_HEADER, - Address.fromHexString("0x2a813d7db3de19b07f92268b6d4125ed295cbe00")); - private static final Hash KNOWN_BLOCK_HASH = - Hash.fromHexString("0x0d60351c129af309fc8597c81358652d3d0f0e3141b5432888c4aae405ee0184"); - - private final BlockHeader header = createKnownHeaderFromCapturedData(); - - @Test - public void recoverProposerAddressFromSeal() { - final IbftExtraData ibftExtraData = IbftExtraData.decode(header); - final Address proposerAddress = IbftBlockHashing.recoverProposerAddress(header, ibftExtraData); - - assertThat(proposerAddress).isEqualTo(PROPOSER_IN_HEADER); - } - - @Test - public void readValidatorListFromExtraData() { - final IbftExtraData ibftExtraData = IbftExtraData.decode(header); - Assertions.assertThat(ibftExtraData.getValidators()).isEqualTo(VALIDATORS_IN_HEADER); - } - - @Test - public void recoverCommitterAddresses() { - final IbftExtraData ibftExtraData = IbftExtraData.decode(header); - final List
committers = - IbftBlockHashing.recoverCommitterAddresses(header, ibftExtraData); - - assertThat(committers).isEqualTo(COMMITTERS_IN_HEADER); - } - - @Test - public void calculateBlockHash() { - assertThat(header.getHash()).isEqualTo(KNOWN_BLOCK_HASH); - } - - /* - Header information was extracted from a chain export (RLP) from a Quorum IBFT network. - The hash was determined by looking at the parentHash of the subsequent block (i.e. not calculated - by internal calculations, but rather by Quorum). - */ - private BlockHeader createKnownHeaderFromCapturedData() { - final BlockHeaderBuilder builder = new BlockHeaderBuilder(); - - final String extraDataHexString = - "0xd783010800846765746887676f312e392e32856c696e757800000" - + "00000000000f90164f8549424defc2d149861d3d245749b81fe0e6b28e04f31942a813d7db3de19b07f92268b6d4" - + "125ed295cbe00943814f17bd4b7ce47ab8146684b3443c0a4b2fc2c94c332d0db1704d18f89a590e7586811e36d3" - + "7ce04b8417480a32e81936a40da3b8b730c28963a80011fdddb70470573675a11c7871873165e213b80b1ed5bf5a" - + "59a31874baf1d6e83d55141f719ada73815c8712c4c6501f8c9b8417ba97752c9a3d14ae8c5f6f864c2808b816a0" - + "d3ebef9a3b03c3cf9e31311baeb2e32609ccc99f13488e9e8ea192debf1c26f8c70c2332dfbb8456292fd9366110" - + "0b841bbf2d1710a41bee7895dadbbbc92713ba9e74129bb665984f349950d7b5275303db99b12ea3483430079dd5" - + "d90bcc3962f72217863725f6cd72ab5c10c8c540001b8415df74d9bf9687a3da10a4660cfd6fd6739df59db5535f" - + "a3a7c58382ec587f4fe581089a9e3cd4b8c3b77eeabdd756f1f34ffb990cfd47e81bb205bd10be619d001"; - - builder.parentHash( - Hash.fromHexString("0xa7762d3307dbf2ae6a1ae1b09cf61c7603722b2379731b6b90409cdb8c8288a0")); - builder.ommersHash( - Hash.fromHexString("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); - builder.coinbase(Address.fromHexString("0x0000000000000000000000000000000000000000")); - builder.stateRoot( - Hash.fromHexString("0xca07595b82f908822971b7e848398e3395e59ee52565c7ef3603df1a1fa7bc80")); - builder.transactionsRoot( - Hash.fromHexString("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); - builder.receiptsRoot( - Hash.fromHexString("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")); - builder.logsBloom( - LogsBloomFilter.fromHexString( - "0x000000000000000000000000000000000000000000000000" - + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - + "0000")); - builder.difficulty(Difficulty.ONE); - builder.number(1); - builder.gasLimit(4704588); - builder.gasUsed(0); - builder.timestamp(1530674616); - builder.extraData(Bytes.fromHexString(extraDataHexString)); - builder.mixHash( - Hash.fromHexString("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365")); - builder.nonce(0); - builder.blockHeaderFunctions(new LegacyIbftBlockHeaderFunctions()); - - return builder.buildBlockHeader(); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftExtraDataCodecTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftExtraDataCodecTest.java deleted file mode 100644 index 6e4fcce930..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/BftExtraDataCodecTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.rlp.RLPException; - -import java.math.BigInteger; -import java.util.Arrays; -import java.util.List; -import java.util.Random; - -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.Lists; -import org.apache.tuweni.bytes.Bytes; -import org.bouncycastle.util.encoders.Hex; -import org.junit.Test; - -public class BftExtraDataCodecTest { - - private static final Supplier SIGNATURE_ALGORITHM = - Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - - @Test - public void emptyListsConstituteValidContent() { - final SECPSignature proposerSeal = - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0); - final List
validators = Lists.newArrayList(); - final List committerSeals = Lists.newArrayList(); - - final BytesValueRLPOutput encoder = new BytesValueRLPOutput(); - encoder.startList(); - encoder.writeList(validators, (validator, rlp) -> rlp.writeBytes(validator)); - encoder.writeBytes(proposerSeal.encodedBytes()); - encoder.writeList(committerSeals, (committer, rlp) -> rlp.writeBytes(committer.encodedBytes())); - encoder.endList(); - - // Create a byte buffer with no data. - final byte[] vanity_bytes = new byte[32]; - final Bytes vanity_data = Bytes.wrap(vanity_bytes); - final Bytes bufferToInject = Bytes.wrap(vanity_data, encoder.encoded()); - - final IbftExtraData extraData = IbftExtraData.decodeRaw(bufferToInject); - - assertThat(extraData.getVanityData()).isEqualTo(vanity_data); - assertThat(extraData.getProposerSeal()).isEqualTo(proposerSeal); - assertThat(extraData.getSeals()).isEqualTo(committerSeals); - assertThat(extraData.getValidators()).isEqualTo(validators); - } - - @Test - public void fullyPopulatedDataProducesCorrectlyFormedExtraDataObject() { - final List
validators = Arrays.asList(Address.ECREC, Address.SHA256); - final SECPSignature proposerSeal = - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0); - final List committerSeals = - Arrays.asList( - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0), - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0)); - - final BytesValueRLPOutput encoder = new BytesValueRLPOutput(); - encoder.startList(); // This is required to create a "root node" for all RLP'd data - encoder.writeList(validators, (validator, rlp) -> rlp.writeBytes(validator)); - encoder.writeBytes(proposerSeal.encodedBytes()); - encoder.writeList(committerSeals, (committer, rlp) -> rlp.writeBytes(committer.encodedBytes())); - encoder.endList(); - - // Create randomised vanity data. - final byte[] vanity_bytes = new byte[32]; - new Random().nextBytes(vanity_bytes); - final Bytes vanity_data = Bytes.wrap(vanity_bytes); - final Bytes bufferToInject = Bytes.wrap(vanity_data, encoder.encoded()); - - final IbftExtraData extraData = IbftExtraData.decodeRaw(bufferToInject); - - assertThat(extraData.getVanityData()).isEqualTo(vanity_data); - assertThat(extraData.getProposerSeal()).isEqualTo(proposerSeal); - assertThat(extraData.getSeals()).isEqualTo(committerSeals); - assertThat(extraData.getValidators()).isEqualTo(validators); - } - - @Test - public void incorrectlyStructuredRlpThrowsException() { - final SECPSignature proposerSeal = - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0); - final List
validators = Lists.newArrayList(); - final List committerSeals = Lists.newArrayList(); - - final BytesValueRLPOutput encoder = new BytesValueRLPOutput(); - encoder.startList(); - encoder.writeList(validators, (validator, rlp) -> rlp.writeBytes(validator)); - encoder.writeBytes(proposerSeal.encodedBytes()); - encoder.writeList(committerSeals, (committer, rlp) -> rlp.writeBytes(committer.encodedBytes())); - encoder.writeLong(1); - encoder.endList(); - - final Bytes bufferToInject = Bytes.wrap(Bytes.wrap(new byte[32]), encoder.encoded()); - - assertThatThrownBy(() -> IbftExtraData.decodeRaw(bufferToInject)) - .isInstanceOf(RLPException.class); - } - - @Test - public void incorrectlySizedVanityDataThrowsException() { - final List
validators = Arrays.asList(Address.ECREC, Address.SHA256); - final SECPSignature proposerSeal = - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0); - final List committerSeals = - Arrays.asList( - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 0), - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.TEN, BigInteger.ONE, (byte) 0)); - - final BytesValueRLPOutput encoder = new BytesValueRLPOutput(); - encoder.startList(); - encoder.writeList(validators, (validator, rlp) -> rlp.writeBytes(validator)); - encoder.writeBytes(proposerSeal.encodedBytes()); - encoder.writeList(committerSeals, (committer, rlp) -> rlp.writeBytes(committer.encodedBytes())); - encoder.endList(); - - final Bytes bufferToInject = Bytes.wrap(Bytes.wrap(new byte[31]), encoder.encoded()); - - assertThatThrownBy(() -> IbftExtraData.decodeRaw(bufferToInject)) - .isInstanceOf(RLPException.class); - } - - @Test - public void parseGenesisBlockWithZeroProposerSeal() { - final byte[] genesisBlockExtraData = - Hex.decode( - "0000000000000000000000000000000000000000000000000000000000000000f89af85494c332d0db1704d18f89a590e7586811e36d37ce049424defc2d149861d3d245749b81fe0e6b28e04f31943814f17bd4b7ce47ab8146684b3443c0a4b2fc2c942a813d7db3de19b07f92268b6d4125ed295cbe00b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"); - - final Bytes bufferToInject = Bytes.wrap(genesisBlockExtraData); - - final IbftExtraData extraData = IbftExtraData.decodeRaw(bufferToInject); - assertThat(extraData.getProposerSeal()).isNull(); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactoryTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactoryTest.java deleted file mode 100644 index 89310524e4..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftBlockHeaderValidationRulesetFactoryTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; -import org.hyperledger.besu.consensus.ibft.IbftLegacyContext; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; -import org.hyperledger.besu.ethereum.core.Difficulty; -import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; -import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; - -import java.math.BigInteger; -import java.util.Collection; -import java.util.List; - -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import org.apache.tuweni.bytes.Bytes; -import org.junit.Test; -import org.mockito.Mockito; - -public class IbftBlockHeaderValidationRulesetFactoryTest { - - private static final Supplier SIGNATURE_ALGORITHM = - Suppliers.memoize(SignatureAlgorithmFactory::getInstance); - - private ProtocolContext setupContextWithValidators(final Collection
validators) { - final IbftLegacyContext bftContext = mock(IbftLegacyContext.class); - final ValidatorProvider mockValidatorProvider = mock(ValidatorProvider.class); - when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider); - when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators); - when(bftContext.as(Mockito.any())).thenReturn(bftContext); - return new ProtocolContext(null, null, bftContext); - } - - @Test - public void ibftValidateHeaderPasses() { - final KeyPair proposerKeyPair = SIGNATURE_ALGORITHM.get().generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = singletonList(proposerAddress); - - final BlockHeader parentHeader = buildBlockHeader(1, proposerKeyPair, validators, null); - final BlockHeader blockHeader = buildBlockHeader(2, proposerKeyPair, validators, parentHeader); - - final BlockHeaderValidator validator = - IbftBlockHeaderValidationRulesetFactory.ibftBlockHeaderValidator(5, 0).build(); - - assertThat( - validator.validateHeader( - blockHeader, - parentHeader, - setupContextWithValidators(validators), - HeaderValidationMode.FULL)) - .isTrue(); - } - - @Test - public void ibftValidateHeaderFails() { - final KeyPair proposerKeyPair = SIGNATURE_ALGORITHM.get().generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = singletonList(proposerAddress); - - final BlockHeader parentHeader = buildBlockHeader(1, proposerKeyPair, validators, null); - final BlockHeader blockHeader = buildBlockHeader(2, proposerKeyPair, validators, null); - - final BlockHeaderValidator validator = - IbftBlockHeaderValidationRulesetFactory.ibftBlockHeaderValidator(5, 0).build(); - - assertThat( - validator.validateHeader( - blockHeader, - parentHeader, - setupContextWithValidators(validators), - HeaderValidationMode.FULL)) - .isFalse(); - } - - private BlockHeader buildBlockHeader( - final long number, - final KeyPair proposerKeyPair, - final List
validators, - final BlockHeader parent) { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - - if (parent != null) { - builder.parentHash(parent.getHash()); - } - builder.number(number); - builder.gasLimit(5000); - builder.timestamp(6000 * number); - builder.mixHash( - Hash.fromHexString("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365")); - builder.ommersHash(Hash.EMPTY_LIST_HASH); - builder.nonce(IbftLegacyBlockInterface.DROP_NONCE); - builder.difficulty(Difficulty.ONE); - - // Construct an extraData block - final IbftExtraData initialIbftExtraData = - new IbftExtraData( - Bytes.wrap(new byte[IbftExtraData.EXTRA_VANITY_LENGTH]), - emptyList(), - SIGNATURE_ALGORITHM.get().createSignature(BigInteger.ONE, BigInteger.ONE, (byte) 0), - validators); - - builder.extraData(initialIbftExtraData.encode()); - final BlockHeader parentHeader = builder.buildHeader(); - final Hash proposerSealHash = - IbftBlockHashing.calculateDataHashForProposerSeal(parentHeader, initialIbftExtraData); - - final SECPSignature proposerSignature = - SIGNATURE_ALGORITHM.get().sign(proposerSealHash, proposerKeyPair); - - final IbftExtraData proposedData = - new IbftExtraData( - Bytes.wrap(new byte[IbftExtraData.EXTRA_VANITY_LENGTH]), - singletonList(proposerSignature), - proposerSignature, - validators); - - final Hash headerHashForCommitters = - IbftBlockHashing.calculateDataHashForCommittedSeal(parentHeader, proposedData); - final SECPSignature proposerAsCommitterSignature = - SIGNATURE_ALGORITHM.get().sign(headerHashForCommitters, proposerKeyPair); - - final IbftExtraData sealedData = - new IbftExtraData( - Bytes.wrap(new byte[IbftExtraData.EXTRA_VANITY_LENGTH]), - singletonList(proposerAsCommitterSignature), - proposerSignature, - validators); - - builder.extraData(sealedData.encode()); - return builder.buildHeader(); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterfaceTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterfaceTest.java deleted file mode 100644 index 03346483e0..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyBlockInterfaceTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.common.validator.VoteType.ADD; -import static org.hyperledger.besu.consensus.common.validator.VoteType.DROP; - -import org.hyperledger.besu.consensus.common.validator.ValidatorVote; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.core.AddressHelpers; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; -import org.hyperledger.besu.ethereum.core.Util; - -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -import org.junit.Before; -import org.junit.Test; - -public class IbftLegacyBlockInterfaceTest { - - private static final KeyPair proposerKeys = - SignatureAlgorithmFactory.getInstance().generateKeyPair(); - private static final Address proposerAddress = - Util.publicKeyToAddress(proposerKeys.getPublicKey()); - private static final List
validatorList = singletonList(proposerAddress); - - private final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); - private final IbftLegacyBlockInterface blockInterface = new IbftLegacyBlockInterface(); - private final BlockHeaderBuilder builder = - BlockHeaderBuilder.fromHeader(headerBuilder.buildHeader()) - .blockHeaderFunctions(new LegacyIbftBlockHeaderFunctions()); - - @Before - public void setup() { - // must set "number" to ensure extradata is correctly deserialised during hashing. - headerBuilder.coinbase(AddressHelpers.ofValue(0)).number(1); - } - - @Test - public void headerWithZeroCoinbaseReturnsAnEmptyVote() { - assertThat(blockInterface.extractVoteFromHeader(headerBuilder.buildHeader())).isEmpty(); - } - - @Test - public void headerWithNonceOfZeroReportsDropVote() { - headerBuilder.nonce(0x0L).coinbase(AddressHelpers.ofValue(2)); - final BlockHeader header = - TestHelpers.createIbftSignedBlockHeader(headerBuilder, proposerKeys, validatorList); - final Optional extractedVote = blockInterface.extractVoteFromHeader(header); - - assertThat(extractedVote) - .contains(new ValidatorVote(DROP, proposerAddress, header.getCoinbase())); - } - - @Test - public void headerWithNonceOfMaxLongReportsAddVote() { - headerBuilder.nonce(0xFFFFFFFFFFFFFFFFL).coinbase(AddressHelpers.ofValue(2)); - - final BlockHeader header = - TestHelpers.createIbftSignedBlockHeader(headerBuilder, proposerKeys, validatorList); - final Optional extractedVote = blockInterface.extractVoteFromHeader(header); - - assertThat(extractedVote) - .contains(new ValidatorVote(ADD, proposerAddress, header.getCoinbase())); - } - - @Test - public void blendingAddVoteToHeaderResultsInHeaderWithNonceOfMaxLong() { - final ValidatorVote vote = - new ValidatorVote(ADD, AddressHelpers.ofValue(1), AddressHelpers.ofValue(2)); - final BlockHeaderBuilder builderWithVote = - IbftLegacyBlockInterface.insertVoteToHeaderBuilder(builder, Optional.of(vote)); - - final BlockHeader header = builderWithVote.buildBlockHeader(); - - assertThat(header.getCoinbase()).isEqualTo(vote.getRecipient()); - assertThat(header.getNonce()).isEqualTo(0xFFFFFFFFFFFFFFFFL); - } - - @Test - public void blendingDropVoteToHeaderResultsInHeaderWithNonceOfZero() { - final ValidatorVote vote = - new ValidatorVote(DROP, AddressHelpers.ofValue(1), AddressHelpers.ofValue(2)); - final BlockHeaderBuilder builderWithVote = - IbftLegacyBlockInterface.insertVoteToHeaderBuilder(builder, Optional.of(vote)); - - final BlockHeader header = builderWithVote.buildBlockHeader(); - - assertThat(header.getCoinbase()).isEqualTo(vote.getRecipient()); - assertThat(header.getNonce()).isEqualTo(0x0L); - } - - @Test - public void nonVoteBlendedIntoHeaderResultsInACoinbaseOfZero() { - final BlockHeaderBuilder builderWithVote = - IbftLegacyBlockInterface.insertVoteToHeaderBuilder(builder, Optional.empty()); - - final BlockHeader header = builderWithVote.buildBlockHeader(); - - assertThat(header.getCoinbase()).isEqualTo(AddressHelpers.ofValue(0)); - assertThat(header.getNonce()).isEqualTo(0x0L); - } - - @Test - public void extractsValidatorsFromHeader() { - final BlockHeader header = - TestHelpers.createIbftSignedBlockHeader(headerBuilder, proposerKeys, validatorList); - - final Collection
extractedValidators = blockInterface.validatorsInBlock(header); - - assertThat(extractedValidators).isEqualTo(validatorList); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyContextBuilder.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyContextBuilder.java deleted file mode 100644 index 3dc42c2e98..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/IbftLegacyContextBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -import org.hyperledger.besu.consensus.common.validator.ValidatorProvider; -import org.hyperledger.besu.consensus.ibft.IbftLegacyContext; -import org.hyperledger.besu.datatypes.Address; - -import java.util.Collection; - -import org.mockito.Mockito; - -public class IbftLegacyContextBuilder { - - public static IbftLegacyContext setupContextWithValidators(final Collection
validators) { - final IbftLegacyContext bftContext = mock(IbftLegacyContext.class, withSettings().lenient()); - final ValidatorProvider mockValidatorProvider = - mock(ValidatorProvider.class, withSettings().lenient()); - when(bftContext.getValidatorProvider()).thenReturn(mockValidatorProvider); - when(mockValidatorProvider.getValidatorsAfterBlock(any())).thenReturn(validators); - when(bftContext.as(Mockito.any())).thenReturn(bftContext); - return bftContext; - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/TestHelpers.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/TestHelpers.java deleted file mode 100644 index d8618c0110..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/TestHelpers.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; - -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; - -public class TestHelpers { - - public static BlockHeader createIbftSignedBlockHeader( - final BlockHeaderTestFixture blockHeaderBuilder, - final KeyPair signer, - final List
validators) { - - final IbftExtraData unsignedExtraData = - new IbftExtraData(Bytes.wrap(new byte[32]), Collections.emptyList(), null, validators); - blockHeaderBuilder.extraData(unsignedExtraData.encode()); - - final Hash signingHash = - IbftBlockHashing.calculateDataHashForProposerSeal( - blockHeaderBuilder.buildHeader(), unsignedExtraData); - - final SECPSignature proposerSignature = - SignatureAlgorithmFactory.getInstance().sign(signingHash, signer); - - final IbftExtraData signedExtraData = - new IbftExtraData( - unsignedExtraData.getVanityData(), - unsignedExtraData.getSeals(), - proposerSignature, - unsignedExtraData.getValidators()); - - blockHeaderBuilder.extraData(signedExtraData.encode()); - - return blockHeaderBuilder.buildHeader(); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/BftBlockCreatorTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/BftBlockCreatorTest.java deleted file mode 100644 index da3fbd363b..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/blockcreation/BftBlockCreatorTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.blockcreation; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.ibftlegacy.IbftLegacyContextBuilder.setupContextWithValidators; -import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.config.GenesisConfigFile; -import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHeaderValidationRulesetFactory; -import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData; -import org.hyperledger.besu.consensus.ibftlegacy.IbftProtocolSchedule; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.chain.MutableBlockchain; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; -import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.sorter.GasPricePendingTransactionsSorter; -import org.hyperledger.besu.ethereum.mainnet.BlockHeaderValidator; -import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.evm.internal.EvmConfiguration; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.plugin.services.MetricsSystem; -import org.hyperledger.besu.testutil.TestClock; - -import java.time.Instant; -import java.time.ZoneId; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import com.google.common.collect.Lists; -import org.apache.tuweni.bytes.Bytes; -import org.junit.Test; - -public class BftBlockCreatorTest { - private final MetricsSystem metricsSystem = new NoOpMetricsSystem(); - - @Test - public void headerProducedPassesValidationRules() { - // Construct a parent block. - final BlockHeaderTestFixture blockHeaderBuilder = new BlockHeaderTestFixture(); - blockHeaderBuilder.gasLimit(5000); // required to pass validation rule checks. - final BlockHeader parentHeader = blockHeaderBuilder.buildHeader(); - final Optional optionalHeader = Optional.of(parentHeader); - - // Construct a block chain and world state - final MutableBlockchain blockchain = mock(MutableBlockchain.class); - when(blockchain.getChainHeadHash()).thenReturn(parentHeader.getHash()); - when(blockchain.getBlockHeader(any())).thenReturn(optionalHeader); - final BlockHeader blockHeader = mock(BlockHeader.class); - when(blockHeader.getBaseFee()).thenReturn(Optional.empty()); - when(blockchain.getChainHeadHeader()).thenReturn(blockHeader); - - final KeyPair nodeKeys = SignatureAlgorithmFactory.getInstance().generateKeyPair(); - // Add the local node as a validator (can't propose a block if node is not a validator). - final Address localAddr = Address.extract(Hash.hash(nodeKeys.getPublicKey().getEncodedBytes())); - final List
initialValidatorList = - Arrays.asList( - Address.fromHexString(String.format("%020d", 1)), - Address.fromHexString(String.format("%020d", 2)), - Address.fromHexString(String.format("%020d", 3)), - Address.fromHexString(String.format("%020d", 4)), - localAddr); - - final ProtocolSchedule protocolSchedule = - IbftProtocolSchedule.create( - GenesisConfigFile.fromConfig("{\"config\": {\"spuriousDragonBlock\":0}}") - .getConfigOptions(), - false, - EvmConfiguration.DEFAULT); - final ProtocolContext protContext = - new ProtocolContext( - blockchain, - createInMemoryWorldStateArchive(), - setupContextWithValidators(initialValidatorList)); - - final IbftBlockCreator blockCreator = - new IbftBlockCreator( - Address.fromHexString(String.format("%020d", 0)), - () -> Optional.of(10_000_000L), - parent -> - new IbftExtraData( - Bytes.wrap(new byte[32]), Lists.newArrayList(), null, initialValidatorList) - .encode(), - new GasPricePendingTransactionsSorter( - ImmutableTransactionPoolConfiguration.builder().txPoolMaxSize(1).build(), - TestClock.system(ZoneId.systemDefault()), - metricsSystem, - blockchain::getChainHeadHeader), - protContext, - protocolSchedule, - nodeKeys, - Wei.ZERO, - 0.8, - parentHeader); - - final Block block = blockCreator.createBlock(Instant.now().getEpochSecond()).getBlock(); - - final BlockHeaderValidator rules = - IbftBlockHeaderValidationRulesetFactory.ibftProposedBlockValidator(0).build(); - - final boolean validationResult = - rules.validateHeader( - block.getHeader(), parentHeader, protContext, HeaderValidationMode.FULL); - - assertThat(validationResult).isTrue(); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/BftExtraDataValidationRuleTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/BftExtraDataValidationRuleTest.java deleted file mode 100644 index a6cae9105b..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/headervalidationrules/BftExtraDataValidationRuleTest.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.headervalidationrules; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.consensus.ibftlegacy.IbftLegacyContextBuilder.setupContextWithValidators; - -import org.hyperledger.besu.consensus.ibftlegacy.IbftBlockHashing; -import org.hyperledger.besu.consensus.ibftlegacy.IbftExtraData; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.core.AddressHelpers; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import com.google.common.collect.Lists; -import org.apache.tuweni.bytes.Bytes; -import org.assertj.core.api.Assertions; -import org.junit.Test; - -public class BftExtraDataValidationRuleTest { - - private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); - - private BlockHeader createProposedBlockHeader( - final KeyPair proposerKeyPair, final List
validators) { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - - // Construct an extraData block and add to a header - final IbftExtraData initialIbftExtraData = - new IbftExtraData( - Bytes.wrap(new byte[IbftExtraData.EXTRA_VANITY_LENGTH]), emptyList(), null, validators); - builder.extraData(initialIbftExtraData.encode()); - final BlockHeader header = builder.buildHeader(); - - // Hash the header (ignoring committer and proposer seals), and create signature - final Hash proposerSealHash = - IbftBlockHashing.calculateDataHashForProposerSeal(header, initialIbftExtraData); - final SECPSignature proposerSignature = - signatureAlgorithm.sign(proposerSealHash, proposerKeyPair); - - // Construct a new extraData block, containing the constructed proposer signature - final IbftExtraData proposedData = - new IbftExtraData( - Bytes.wrap(new byte[IbftExtraData.EXTRA_VANITY_LENGTH]), - emptyList(), - proposerSignature, - validators); - - // insert the signed ExtraData into the block - builder.extraData(proposedData.encode()); - return builder.buildHeader(); - } - - private IbftExtraData createExtraDataWithCommitSeals( - final BlockHeader header, final Collection committerKeyPairs) { - final IbftExtraData extraDataInHeader = IbftExtraData.decode(header); - - final Hash headerHashForCommitters = - IbftBlockHashing.calculateDataHashForCommittedSeal(header, extraDataInHeader); - - final List commitSeals = - committerKeyPairs.stream() - .map(keys -> signatureAlgorithm.sign(headerHashForCommitters, keys)) - .collect(Collectors.toList()); - - return new IbftExtraData( - extraDataInHeader.getVanityData(), - commitSeals, - extraDataInHeader.getProposerSeal(), - extraDataInHeader.getValidators()); - } - - @Test - public void correctlyConstructedHeaderPassesValidation() { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = singletonList(proposerAddress); - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, 0); - - BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators); - - // Insert an extraData block with committer seals. - final IbftExtraData commitedExtraData = - createExtraDataWithCommitSeals(header, singletonList(proposerKeyPair)); - builder.extraData(commitedExtraData.encode()); - header = builder.buildHeader(); - - assertThat(extraDataValidationRule.validate(header, null, context)).isTrue(); - } - - @Test - public void insufficientCommitSealsFailsValidation() { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = singletonList(proposerAddress); - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, 0); - - final BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators); - - // Note that no committer seals are in the header's IBFT extra data. - final IbftExtraData headerExtraData = IbftExtraData.decode(header); - Assertions.assertThat(headerExtraData.getSeals().size()).isEqualTo(0); - - assertThat(extraDataValidationRule.validate(header, null, context)).isFalse(); - } - - @Test - public void outOfOrderValidatorListFailsValidation() { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = - Lists.newArrayList( - AddressHelpers.calculateAddressWithRespectTo(proposerAddress, 1), proposerAddress); - - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, 0); - - BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators); - - // Insert an extraData block with committer seals. - final IbftExtraData commitedExtraData = - createExtraDataWithCommitSeals(header, singletonList(proposerKeyPair)); - builder.extraData(commitedExtraData.encode()); - header = builder.buildHeader(); - - assertThat(extraDataValidationRule.validate(header, null, context)).isFalse(); - } - - @Test - public void proposerNotInValidatorListFailsValidation() { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = - Lists.newArrayList( - AddressHelpers.calculateAddressWithRespectTo(proposerAddress, 1), proposerAddress); - - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, 0); - - BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators); - - // Insert an extraData block with committer seals. - final IbftExtraData commitedExtraData = - createExtraDataWithCommitSeals(header, singletonList(proposerKeyPair)); - builder.extraData(commitedExtraData.encode()); - header = builder.buildHeader(); - - assertThat(extraDataValidationRule.validate(header, null, context)).isFalse(); - } - - @Test - public void mismatchingReportedValidatorsVsLocallyStoredListFailsValidation() { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = Lists.newArrayList(proposerAddress); - - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, 0); - - // Add another validator to the list reported in the IbftExtraData (note, as the - final List
extraDataValidators = - Lists.newArrayList( - proposerAddress, AddressHelpers.calculateAddressWithRespectTo(proposerAddress, 1)); - BlockHeader header = createProposedBlockHeader(proposerKeyPair, extraDataValidators); - - // Insert an extraData block with committer seals. - final IbftExtraData commitedExtraData = - createExtraDataWithCommitSeals(header, singletonList(proposerKeyPair)); - builder.extraData(commitedExtraData.encode()); - header = builder.buildHeader(); - - assertThat(extraDataValidationRule.validate(header, null, context)).isFalse(); - } - - @Test - public void committerNotInValidatorListFailsValidation() { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = singletonList(proposerAddress); - - BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators); - - // Insert an extraData block with committer seals. - final KeyPair nonValidatorKeyPair = signatureAlgorithm.generateKeyPair(); - final IbftExtraData commitedExtraData = - createExtraDataWithCommitSeals(header, singletonList(nonValidatorKeyPair)); - builder.extraData(commitedExtraData.encode()); - header = builder.buildHeader(); - - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, 0); - - assertThat(extraDataValidationRule.validate(header, null, context)).isFalse(); - } - - @Test - public void ratioOfCommittersToValidatorsAffectValidation() { - assertThat(subExecution(4, 4, false)).isEqualTo(true); - assertThat(subExecution(4, 3, false)).isEqualTo(true); - assertThat(subExecution(4, 2, false)).isEqualTo(false); - - assertThat(subExecution(5, 3, false)).isEqualTo(true); - assertThat(subExecution(5, 2, false)).isEqualTo(false); - - assertThat(subExecution(6, 4, false)).isEqualTo(true); - assertThat(subExecution(6, 3, false)).isEqualTo(true); - assertThat(subExecution(6, 2, false)).isEqualTo(false); - - assertThat(subExecution(7, 5, false)).isEqualTo(true); - assertThat(subExecution(7, 4, false)).isEqualTo(false); - - assertThat(subExecution(9, 5, false)).isEqualTo(true); - assertThat(subExecution(9, 4, false)).isEqualTo(false); - - assertThat(subExecution(10, 7, false)).isEqualTo(true); - assertThat(subExecution(10, 6, false)).isEqualTo(false); - - assertThat(subExecution(12, 7, false)).isEqualTo(true); - assertThat(subExecution(12, 6, false)).isEqualTo(false); - - // The concern in the above is that when using 6 validators, only 1/2 the validators are - // required to seal a block. All other combinations appear to be safe they always have >50% - // validators sealing the block. - - } - - private boolean subExecution( - final int validatorCount, final int committerCount, final boolean useTwoThirds) { - final BlockHeaderTestFixture builder = new BlockHeaderTestFixture(); - builder.number(1); // must NOT be block 0, as that should not contain seals at all - final KeyPair proposerKeyPair = signatureAlgorithm.generateKeyPair(); - - final Address proposerAddress = - Address.extract(Hash.hash(proposerKeyPair.getPublicKey().getEncodedBytes())); - - final List
validators = Lists.newArrayList(); - final List committerKeys = Lists.newArrayList(); - validators.add(proposerAddress); - committerKeys.add(proposerKeyPair); - for (int i = 0; i < validatorCount - 1; i++) { // need -1 to account for proposer - final KeyPair committerKeyPair = signatureAlgorithm.generateKeyPair(); - committerKeys.add(committerKeyPair); - validators.add(Address.extract(Hash.hash(committerKeyPair.getPublicKey().getEncodedBytes()))); - } - - Collections.sort(validators); - BlockHeader header = createProposedBlockHeader(proposerKeyPair, validators); - final IbftExtraData commitedExtraData = - createExtraDataWithCommitSeals(header, committerKeys.subList(0, committerCount)); - - builder.extraData(commitedExtraData.encode()); - header = builder.buildHeader(); - - final ProtocolContext context = - new ProtocolContext(null, null, setupContextWithValidators(validators)); - final IbftExtraDataValidationRule extraDataValidationRule = - new IbftExtraDataValidationRule(true, useTwoThirds ? 0 : 2); - - return extraDataValidationRule.validate(header, null, context); - } -} diff --git a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManagerTest.java b/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManagerTest.java deleted file mode 100644 index aba5681818..0000000000 --- a/consensus/ibftlegacy/src/test/java/org/hyperledger/besu/consensus/ibftlegacy/protocol/Istanbul99ProtocolManagerTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * 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.ibftlegacy.protocol; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -import org.hyperledger.besu.ethereum.ProtocolContext; -import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.BlockchainSetupUtil; -import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration; -import org.hyperledger.besu.ethereum.eth.EthProtocolVersion; -import org.hyperledger.besu.ethereum.eth.manager.DeterministicEthScheduler; -import org.hyperledger.besu.ethereum.eth.manager.EthContext; -import org.hyperledger.besu.ethereum.eth.manager.EthMessages; -import org.hyperledger.besu.ethereum.eth.manager.EthPeers; -import org.hyperledger.besu.ethereum.eth.manager.EthProtocolManager; -import org.hyperledger.besu.ethereum.eth.manager.EthScheduler; -import org.hyperledger.besu.ethereum.eth.manager.MockPeerConnection; -import org.hyperledger.besu.ethereum.eth.manager.MockPeerConnection.PeerSendHandler; -import org.hyperledger.besu.ethereum.eth.messages.BlockHeadersMessage; -import org.hyperledger.besu.ethereum.eth.messages.EthPV62; -import org.hyperledger.besu.ethereum.eth.messages.GetBlockHeadersMessage; -import org.hyperledger.besu.ethereum.eth.messages.StatusMessage; -import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; -import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; -import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.Capability; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.DefaultMessage; -import org.hyperledger.besu.ethereum.p2p.rlpx.wire.MessageData; -import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat; -import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; -import org.hyperledger.besu.testutil.TestClock; - -import java.math.BigInteger; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import com.google.common.collect.Lists; -import org.junit.BeforeClass; -import org.junit.Test; - -public class Istanbul99ProtocolManagerTest { - - private static Blockchain blockchain; - private static TransactionPool transactionPool; - private static ProtocolSchedule protocolSchedule; - private static ProtocolContext protocolContext; - - @BeforeClass - public static void setup() { - final BlockchainSetupUtil blockchainSetupUtil = - BlockchainSetupUtil.forTesting(DataStorageFormat.FOREST); - blockchainSetupUtil.importAllBlocks(); - blockchain = blockchainSetupUtil.getBlockchain(); - transactionPool = blockchainSetupUtil.getTransactionPool(); - protocolSchedule = blockchainSetupUtil.getProtocolSchedule(); - protocolContext = blockchainSetupUtil.getProtocolContext(); - assertThat(blockchainSetupUtil.getMaxBlockNumber()).isGreaterThanOrEqualTo(20L); - } - - private MockPeerConnection setupPeer( - final EthProtocolManager ethManager, final PeerSendHandler onSend) { - final MockPeerConnection peer = setupPeerWithoutStatusExchange(ethManager, onSend); - final StatusMessage statusMessage = - StatusMessage.create( - EthProtocolVersion.V63, - BigInteger.ONE, - blockchain.getChainHead().getTotalDifficulty(), - blockchain.getChainHeadHash(), - blockchain.getBlockHeader(BlockHeader.GENESIS_BLOCK_NUMBER).get().getHash()); - ethManager.processMessage( - Istanbul99Protocol.ISTANBUL99, new DefaultMessage(peer, statusMessage)); - return peer; - } - - private MockPeerConnection setupPeerWithoutStatusExchange( - final EthProtocolManager ethManager, final PeerSendHandler onSend) { - final Set caps = - new HashSet<>(Collections.singletonList(Istanbul99Protocol.ISTANBUL99)); - final MockPeerConnection peer = new MockPeerConnection(caps, onSend); - ethManager.handleNewConnection(peer); - return peer; - } - - @Test - public void respondToEth65GetHeadersUsingIstanbul99() - throws ExecutionException, InterruptedException, TimeoutException { - final CompletableFuture done = new CompletableFuture<>(); - final EthScheduler ethScheduler = new DeterministicEthScheduler(() -> false); - EthPeers peers = - new EthPeers( - Istanbul99Protocol.NAME, - () -> protocolSchedule.getByBlockHeader(blockchain.getChainHeadHeader()), - TestClock.fixed(), - new NoOpMetricsSystem(), - 25, - EthProtocolConfiguration.DEFAULT_MAX_MESSAGE_SIZE); - EthMessages messages = new EthMessages(); - - final BigInteger networkId = BigInteger.ONE; - try (final EthProtocolManager ethManager = - new Istanbul99ProtocolManager( - blockchain, - networkId, - protocolContext.getWorldStateArchive(), - transactionPool, - EthProtocolConfiguration.defaultConfig(), - peers, - messages, - new EthContext(peers, messages, ethScheduler), - Collections.emptyList(), - mock(SynchronizerConfiguration.class), - ethScheduler)) { - - final long startBlock = blockchain.getChainHeadBlockNumber() + 1; - final int blockCount = 5; - final MessageData messageData = - GetBlockHeadersMessage.create(startBlock, blockCount, 0, false); - final PeerSendHandler onSend = - (cap, message, conn) -> { - if (message.getCode() == EthPV62.STATUS) { - // Ignore status message - return; - } - assertThat(message.getCode()).isEqualTo(EthPV62.BLOCK_HEADERS); - final BlockHeadersMessage headersMsg = BlockHeadersMessage.readFrom(message); - final List headers = - Lists.newArrayList(headersMsg.getHeaders(protocolSchedule)); - assertThat(headers.size()).isEqualTo(0); - done.complete(null); - }; - final PeerConnection peer = setupPeer(ethManager, onSend); - ethManager.processMessage( - Istanbul99Protocol.ISTANBUL99, new DefaultMessage(peer, messageData)); - done.get(10, TimeUnit.SECONDS); - } - } -} diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java index bf6bca3d39..d7330d5b61 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java @@ -99,7 +99,7 @@ public class GenesisFileModule { private static GenesisFileModule createGenesisModule(final String genesisConfig) { final JsonObject genesis = new JsonObject(genesisConfig); final JsonObject config = genesis.getJsonObject("config"); - if (config.containsKey("ibft") || config.containsKey("clique") || config.containsKey("qbft")) { + if (config.containsKey("clique") || config.containsKey("qbft")) { throw new RuntimeException("Only Ethash and Merge configs accepted as genesis files"); } return new MainnetGenesisFileModule(genesisConfig); diff --git a/settings.gradle b/settings.gradle index 2e553ce860..4d954498ed 100644 --- a/settings.gradle +++ b/settings.gradle @@ -41,7 +41,6 @@ include 'config' include 'consensus:clique' include 'consensus:common' include 'consensus:ibft' -include 'consensus:ibftlegacy' include 'consensus:merge' include 'consensus:qbft' include 'datatypes'