diff --git a/.gitattributes b/.gitattributes index 79522fa32..2e408995e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,4 +17,5 @@ *.p12 binary *.db binary *.woff2 binary +*.era1 binary goss-linux-amd64 binary diff --git a/CHANGELOG.md b/CHANGELOG.md index 161183d55..3e3680354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,28 +1,71 @@ # Changelog ## Unreleased + ### Breaking Changes +NOTE: This release breaks native Windows compatibility for mainnet ethereum configurations. As the prague(pectra) hardfork require +BLS12-381 precompiles and besu does not currently have a pure java implementation of bls12-381, only platforms which +have support in besu-native can run mainnet ethereum configurations. Windows support via WSL should still continue to work. + +- k8s (KUBERNETES) Nat method is removed. Use docker or none instead. [#8289](https://github.com/hyperledger/besu/pull/8289) +- Change `Invalid block, unable to parse RLP` RPC error message to `Invalid block param (block not found)` [#8328](https://github.com/hyperledger/besu/pull/8328) +- Mainnet ethereum now REQUIRES native crypto libraries, so only linux and macos(darwin) are supported mainnet configurations [#8418](https://github.com/hyperledger/besu/pull/8418) ### Upcoming Breaking Changes - `MetricSystem::createLabelledGauge` is deprecated and will be removed in a future release, replace it with `MetricSystem::createLabelledSuppliedGauge` -- k8s (KUBERNETES) Nat method is now deprecated and will be removed in a future release. Use docker or none instead. - `--Xsnapsync-synchronizer-flat-db-healing-enabled` is deprecated, use `--Xbonsai-full-flat-db-enabled` instead. - `--Xbonsai-limit-trie-logs-enabled` is deprecated, use `--bonsai-limit-trie-logs-enabled` instead. - `--Xbonsai-trie-log-pruning-enabled` is deprecated, use `--bonsai-limit-trie-logs-enabled` instead. - `--Xbonsai-trie-logs-pruning-window-size` is deprecated, use `--bonsai-trie-logs-pruning-window-size` instead. +- `--Xsnapsync-bft-enabled` is deprecated and will be removed in a future release. SNAP sync is supported for BFT networks. +- `--tx-pool-disable-locals` has been deprecated, use `--tx-pool-no-local-priority`, instead. - Sunsetting features - for more context on the reasoning behind the deprecation of these features, including alternative options, read [this blog post](https://www.lfdecentralizedtrust.org/blog/sunsetting-tessera-and-simplifying-hyperledger-besu) - Tessera privacy - Smart-contract-based (onchain) permissioning - Proof of Work consensus - Fast Sync - Transaction indexing will be disabled by default in a future release for snap sync and checkpoint sync modes. This will break RPCs that use transaction hash for historical queries. +- Support for block creation on networks running a pre-Byzantium fork is deprecated for removal in a future release, after that in order to update Besu on nodes that build blocks, your network needs to be upgraded at least to the Byzantium fork. The main reason is to simplify world state management during block creation, since before Byzantium for each selected transaction, the receipt must contain the root hash of the modified world state, and this does not play well with the new plugin features and future work on parallelism. + ### Additions and Improvements -- Add TLS/mTLS options and configure the GraphQL HTTP service[#7910](https://github.com/hyperledger/besu/pull/7910) +#### Prague +- Increase mainnet and Sepolia gas limit to 36M [#8249](https://github.com/hyperledger/besu/pull/8249) +- Update Holesky and Sepolia deposit contract addresses [#8346](https://github.com/hyperledger/besu/pull/8346) +#### Plugins - Allow plugins to propose transactions during block creation [#8268](https://github.com/hyperledger/besu/pull/8268) -- Update `eth_getLogs` to return a `Block not found` error when the requested block is not found. [#8290](https://github.com/hyperledger/besu/pull/8290) -### Bug fixes +- Add support for transaction permissioning rules in Plugin API [#8365](https://github.com/hyperledger/besu/pull/8365) +#### Parallelization +- Improve conflict detection by considering slots to reduce false positives [#7923](https://github.com/hyperledger/besu/pull/7923) +#### Dependencies - Upgrade Netty to version 4.1.118 to fix CVE-2025-24970 [#8275](https://github.com/hyperledger/besu/pull/8275) -- Add missing RPC method `debug_accountRange` to `RpcMethod.java` and implemented its handler. [#8153](https://github.com/hyperledger/besu/issues/8153) +- Update the jc-kzg-4844 dependency from 1.0.0 to 2.0.0, which is now available on Maven Central [#7849](https://github.com/hyperledger/besu/pull/7849) +- Other dependency updates [#8293](https://github.com/hyperledger/besu/pull/8293) [#8315](https://github.com/hyperledger/besu/pull/8315) [#8350](https://github.com/hyperledger/besu/pull/8350) +- Update to gradle 8.11 [#8294](https://github.com/hyperledger/besu/pull/8294) and update usage of some deprecated features [#8295](https://github.com/hyperledger/besu/pull/8295) [#8340](https://github.com/hyperledger/besu/pull/8340) +- Update gradle plugins [#8296](https://github.com/hyperledger/besu/pull/8296) [#8333](https://github.com/hyperledger/besu/pull/8333) [#8334](https://github.com/hyperledger/besu/pull/8334) +#### Other improvements +- Add TLS/mTLS options and configure the GraphQL HTTP service[#7910](https://github.com/hyperledger/besu/pull/7910) +- Update `eth_getLogs` to return a `Block not found` error when the requested block is not found. [#8290](https://github.com/hyperledger/besu/pull/8290) +- Change `Invalid block, unable to parse RLP` RPC error message to `Invalid block param (block not found)` [#8328](https://github.com/hyperledger/besu/pull/8328) +- Add IBFT1 to QBFT migration capability [#8262](https://github.com/hyperledger/besu/pull/8262) +- Support pending transaction score when saving and restoring txpool [#8363](https://github.com/hyperledger/besu/pull/8363) +- Upgrade to execution-spec-tests v4.1.0 including better EIP-2537 coverage for BLS [#8402](https://github.com/hyperledger/besu/pull/8402) +- Add era1 format to blocks import subcommand [#7935](https://github.com/hyperledger/besu/issues/7935) +- Replace tuweni libs with https://github.com/Consensys/tuweni +- Performance: Consensys/tuweni 2.6.0 reduces boxing/unboxing overhead on some EVM opcodes, like PushX and Caller +- Add Hoodi as new named testnet [#8428](https://github.com/hyperledger/besu/issues/8428) + +### Bug fixes +- Add missing RPC method `debug_accountRange` to `RpcMethod.java` so this method can be used with `--rpc-http-api-method-no-auth` [#8153](https://github.com/hyperledger/besu/issues/8153) +- Add a fallback pivot strategy when the safe block does not change for a long time, to make possible to complete the initial sync in case the chain is not finalizing [#8395](https://github.com/hyperledger/besu/pull/8395) +- Fix issue with new QBFT/IBFT blocks being produced under certain circumstances. [#8308](https://github.com/hyperledger/besu/issues/8308) +- Fix QBFT and IBFT transitions that change the mining beneficiary [#8387](https://github.com/hyperledger/besu/issues/8387) +- `eth_getLogs` - empty topic is a wildcard match [#8420](https://github.com/hyperledger/besu/pull/8420) + +## 25.2.2 hotfix +- Pectra - Sepolia: Fix for deposit contract log decoding [#8383](https://github.com/hyperledger/besu/pull/8383) + +## 25.2.1 hotfix +- Pectra - update Holesky and Sepolia deposit contract addresses [#8346](https://github.com/hyperledger/besu/pull/8346) ## 25.2.0 @@ -40,6 +83,7 @@ - Smart-contract-based (onchain) permissioning - Proof of Work consensus - Fast Sync +- Support for block creation on networks running a pre-Byzantium fork is deprecated for removal in a future release, after that in order to update Besu on nodes that build blocks, your network needs to be upgraded at least to the Byzantium fork. The main reason is to simplify world state management during block creation, since before Byzantium for each selected transaction, the receipt must contain the root hash of the modified world state, and this does not play well with the new plugin features and future work on parallelism. ### Additions and Improvements - Add a tx selector to skip txs from the same sender after the first not selected [#8216](https://github.com/hyperledger/besu/pull/8216) - `rpc-gas-cap` default value has changed from 0 (unlimited) to 50M [#8251](https://github.com/hyperledger/besu/issues/8251) @@ -76,6 +120,8 @@ - Smart-contract-based (onchain) permissioning - Proof of Work consensus - Fast Sync +- Plugins + - `BesuConfiguration` methods `getRpcHttpHost` and `getRpcHttpPort` (which return Optionals) have been deprecated in favour of `getConfiguredRpcHttpHost` and `getConfiguredRpcHttpPort` which return the actual values, which will always be populated since these options have defaults. [#8127](https://github.com/hyperledger/besu/pull/8127) ### Additions and Improvements - Add RPC HTTP options to specify custom truststore and its password [#7978](https://github.com/hyperledger/besu/pull/7978) @@ -142,7 +188,6 @@ This is a hotfix to address publishing besu maven artifacts. There are no issue - Smart-contract-based (onchain) permissioning - Proof of Work consensus - Fast Sync - ### Additions and Improvements - Fine tune already seen txs tracker when a tx is removed from the pool [#7755](https://github.com/hyperledger/besu/pull/7755) - Support for enabling and configuring TLS/mTLS in WebSocket service. [#7854](https://github.com/hyperledger/besu/pull/7854) @@ -667,7 +712,7 @@ https://hyperledger.jfrog.io/artifactory/besu-binaries/besu/23.10.3/besu-23.10.3 - Implement new `miner_setMinPriorityFee` and `miner_getMinPriorityFee` RPC methods [#6080](https://github.com/hyperledger/besu/pull/6080) - Clique config option `createemptyblocks` to not create empty blocks [#6082](https://github.com/hyperledger/besu/pull/6082) - Upgrade EVM Reference Tests to v13 (Cancun) [#6114](https://github.com/hyperledger/besu/pull/6114) -- Add `yParity` to GraphQL and JSON-RPC for relevant querise. [6119](https://github.com/hyperledger/besu/pull/6119) +- Add `yParity` to GraphQL and JSON-RPC for relevant queries. [6119](https://github.com/hyperledger/besu/pull/6119) - Force tx replacement price bump to zero when zero base fee market is configured or `--min-gas-price` is set to 0. This allows for easier tx replacement in networks where there is not gas price. [#6079](https://github.com/hyperledger/besu/pull/6079) - Introduce the possibility to limit the time spent selecting pending transactions during block creation, using the new experimental option `Xblock-txs-selection-max-time` on PoS and PoW networks (by default set to 5000ms) or `Xpoa-block-txs-selection-max-time` on PoA networks (by default 75% of the min block time) [#6044](https://github.com/hyperledger/besu/pull/6044) - Remove LowestInvalidNonceCache from `legacy` transaction pool to make it more private networks friendly [#6148](https://github.com/hyperledger/besu/pull/6148) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 6c17df882..f0feb1acd 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -27,6 +27,7 @@ | Matthew Whitehead| matthew1001 | matthew.whitehead | | Meredith Baxter | mbaxter | mbaxter | | Stefan Pingel | pinges | pinges | +| Bhanu Pulluri | pullurib | bpulluri | | Simon Dudley | siladu | siladu | | Usman Saleem | usmansaleem | usmansaleem | diff --git a/acceptance-tests/dsl/build.gradle b/acceptance-tests/dsl/build.gradle index 6602fda58..db66e2960 100644 --- a/acceptance-tests/dsl/build.gradle +++ b/acceptance-tests/dsl/build.gradle @@ -32,16 +32,15 @@ dependencies { implementation 'io.reactivex.rxjava2:rxjava' implementation 'io.vertx:vertx-core' implementation 'io.opentelemetry:opentelemetry-api' - implementation 'io.tmio:tuweni-bytes' - implementation 'io.tmio:tuweni-io' - implementation 'io.tmio:tuweni-units' + implementation 'io.consensys.protocols:tuweni-bytes' + implementation 'io.consensys.protocols:tuweni-io' + implementation 'io.consensys.protocols:tuweni-units' implementation 'org.assertj:assertj-core' implementation 'org.awaitility:awaitility' implementation 'org.java-websocket:Java-WebSocket' implementation 'org.web3j:abi' implementation 'org.web3j:besu' implementation 'org.web3j:crypto' - implementation 'org.wiremock:wiremock' implementation 'org.junit.jupiter:junit-jupiter' } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/blockchain/Blockchain.java index 328bbf105..8c64b518e 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/blockchain/Blockchain.java @@ -45,6 +45,10 @@ public class Blockchain { return new ExpectBlockNumberAbove(eth, BigInteger.valueOf(blockNumber)); } + public Condition minimumHeight(final long blockNumber, final int timeout) { + return new ExpectBlockNumberAbove(eth, BigInteger.valueOf(blockNumber), timeout); + } + public Condition reachesHeight(final BesuNode node, final int blocksAheadOfLatest) { return new ExpectBlockNumberAbove(eth, futureHeight(node, blocksAheadOfLatest)); } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/AwaitNetPeerCount.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/AwaitNetPeerCount.java index b8e40c6c4..52e3dea1e 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/AwaitNetPeerCount.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/AwaitNetPeerCount.java @@ -27,15 +27,25 @@ public class AwaitNetPeerCount implements Condition { private final NetPeerCountTransaction transaction; private final BigInteger expectedPeerCount; + private final int timeout; public AwaitNetPeerCount( final NetPeerCountTransaction transaction, final BigInteger expectedPeerCount) { + this(transaction, expectedPeerCount, 30); + } + + public AwaitNetPeerCount( + final NetPeerCountTransaction transaction, + final BigInteger expectedPeerCount, + final int timeout) { this.transaction = transaction; this.expectedPeerCount = expectedPeerCount; + this.timeout = timeout; } @Override public void verify(final Node node) { - WaitUtils.waitFor(() -> assertThat(node.execute(transaction)).isEqualTo(expectedPeerCount)); + WaitUtils.waitFor( + timeout, () -> assertThat(node.execute(transaction)).isEqualTo(expectedPeerCount)); } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/NetConditions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/NetConditions.java index 004b12b91..c9b669e7f 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/NetConditions.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/net/NetConditions.java @@ -47,6 +47,11 @@ public class NetConditions { return new AwaitNetPeerCount(transactions.peerCount(), BigInteger.valueOf(awaitPeerCount)); } + public Condition awaitPeerCount(final int awaitPeerCount, final int timeout) { + return new AwaitNetPeerCount( + transactions.peerCount(), BigInteger.valueOf(awaitPeerCount), timeout); + } + public Condition netVersionExceptional(final String expectedMessage) { return new ExpectNetVersionConnectionException(transactions.netVersion(), expectedMessage); } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AccountSmartContractPermissioningConditions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AccountSmartContractPermissioningConditions.java deleted file mode 100644 index a265a304a..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AccountSmartContractPermissioningConditions.java +++ /dev/null @@ -1,37 +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.tests.acceptance.dsl.condition.perm; - -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.AccountSmartContractPermissioningTransactions; - -public class AccountSmartContractPermissioningConditions { - - private final AccountSmartContractPermissioningTransactions transactions; - - public AccountSmartContractPermissioningConditions( - final AccountSmartContractPermissioningTransactions transactions) { - this.transactions = transactions; - } - - public Condition accountIsAllowed(final String address, final Account account) { - return new WaitForTrueResponse(transactions.isAccountAllowed(address, account)); - } - - public Condition accountIsForbidden(final String address, final Account account) { - return new WaitForFalseResponse(transactions.isAccountAllowed(address, account)); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/NodeSmartContractPermissioningConditions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/NodeSmartContractPermissioningConditions.java deleted file mode 100644 index c2897504f..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/NodeSmartContractPermissioningConditions.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.condition.perm; - -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningTransactions; - -public class NodeSmartContractPermissioningConditions { - - private final NodeSmartContractPermissioningTransactions transactions; - - public NodeSmartContractPermissioningConditions( - final NodeSmartContractPermissioningTransactions transactions) { - this.transactions = transactions; - } - - public Condition nodeIsAllowed(final String address, final Node node) { - return new WaitForTrueResponse(transactions.isNodeAllowed(address, node)); - } - - public Condition nodeIsForbidden(final String address, final Node node) { - return new WaitForFalseResponse(transactions.isNodeAllowed(address, node)); - } - - public Condition connectionIsAllowed(final String address, final Node source, final Node target) { - return new WaitForTrueResponse(transactions.isConnectionAllowed(address, source, target)); - } - - public Condition connectionIsForbidden( - final String address, final Node source, final Node target) { - return new WaitForFalseResponse(transactions.isConnectionAllowed(address, source, target)); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/NodeSmartContractPermissioningV2Conditions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/NodeSmartContractPermissioningV2Conditions.java deleted file mode 100644 index 1ef293ec3..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/NodeSmartContractPermissioningV2Conditions.java +++ /dev/null @@ -1,46 +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.tests.acceptance.dsl.condition.perm; - -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningV2Transactions; - -public class NodeSmartContractPermissioningV2Conditions { - - private final NodeSmartContractPermissioningV2Transactions transactions; - - public NodeSmartContractPermissioningV2Conditions( - final NodeSmartContractPermissioningV2Transactions transactions) { - this.transactions = transactions; - } - - public Condition connectionIsAllowed(final String address, final Node node) { - return new WaitForTrueResponse(transactions.isConnectionAllowed(address, node)); - } - - public Condition connectionIsAllowed(final String address, final EnodeURL enodeURL) { - return new WaitForTrueResponse(transactions.isConnectionAllowed(address, enodeURL)); - } - - public Condition connectionIsForbidden(final String address, final Node node) { - return new WaitForFalseResponse(transactions.isConnectionAllowed(address, node)); - } - - public Condition connectionIsForbidden(final String address, final EnodeURL enodeURL) { - return new WaitForFalseResponse(transactions.isConnectionAllowed(address, enodeURL)); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java index 0724ee51a..b251b1ec1 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java @@ -30,6 +30,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguratio import org.hyperledger.besu.ethereum.core.MiningConfiguration; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.Util; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; @@ -134,6 +135,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable private Optional exitCode = Optional.empty(); private final boolean isStrictTxReplayProtectionEnabled; private final Map environment; + private SynchronizerConfiguration synchronizerConfiguration; private final Optional storageFactory; public BesuNode( @@ -234,6 +236,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable this.isDnsEnabled = isDnsEnabled; privacyParameters.ifPresent(this::setPrivacyParameters); this.environment = environment; + this.synchronizerConfiguration = SynchronizerConfiguration.builder().build(); // Default config LOG.info("Created BesuNode {}", this); } @@ -790,6 +793,20 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable nodeRequests.shutdown(); nodeRequests = null; } + deleteRuntimeFiles(); + } + + private void deleteRuntimeFiles() { + try { + Files.deleteIfExists(homeDirectory.resolve("besu.networks")); + } catch (IOException e) { + LOG.error("Failed to clean up besu.networks file in {}", homeDirectory, e); + } + try { + Files.deleteIfExists(homeDirectory.resolve("besu.ports")); + } catch (IOException e) { + LOG.error("Failed to clean up besu.ports file in {}", homeDirectory, e); + } } @Override @@ -841,6 +858,15 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable return apiConfiguration; } + public SynchronizerConfiguration getSynchronizerConfiguration() { + return synchronizerConfiguration; + } + + public BesuNode setSynchronizerConfiguration(final SynchronizerConfiguration config) { + this.synchronizerConfiguration = config; + return this; + } + public Optional getStorageFactory() { return storageFactory; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java index 33a9a1cfb..8e9d4c80c 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java @@ -48,6 +48,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -152,8 +153,20 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner { params.add(node.getNetwork().name()); } - params.add("--sync-mode"); - params.add("FULL"); + if (node.getSynchronizerConfiguration() != null) { + + if (node.getSynchronizerConfiguration().getSyncMode() != null) { + params.add("--sync-mode"); + params.add(node.getSynchronizerConfiguration().getSyncMode().toString()); + } + params.add("--sync-min-peers"); + params.add(Integer.toString(node.getSynchronizerConfiguration().getSyncMinimumPeerCount())); + } else { + params.add("--sync-mode"); + params.add("FULL"); + } + + params.add("--Xsnapsync-server-enabled"); params.add("--discovery-enabled"); params.add(Boolean.toString(node.isDiscoveryEnabled())); @@ -529,9 +542,11 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner { return; } - LOG.info("Killing {} process, pid {}", name, process.pid()); - - process.destroy(); + Stream.concat(process.descendants(), Stream.of(process.toHandle())) + .peek( + processHandle -> + LOG.info("Killing {} process, pid {}", processHandle.info(), processHandle.pid())) + .forEach(ProcessHandle::destroy); try { process.waitFor(30, TimeUnit.SECONDS); } catch (final InterruptedException e) { diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index 865326e91..29a021ea8 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -19,6 +19,7 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; import org.hyperledger.besu.chainexport.RlpBlockExporter; +import org.hyperledger.besu.chainimport.Era1BlockImporter; import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.BesuCommand; @@ -31,7 +32,6 @@ import org.hyperledger.besu.controller.BesuControllerBuilder; import org.hyperledger.besu.crypto.KeyPairUtil; import org.hyperledger.besu.cryptoservices.KeyPairSecurityModule; import org.hyperledger.besu.cryptoservices.NodeKey; -import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; @@ -50,7 +50,7 @@ import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder; import org.hyperledger.besu.ethereum.transaction.TransactionSimulator; -import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; +import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.internal.EvmConfiguration; @@ -480,7 +480,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { .ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig()) .clock(Clock.systemUTC()) .storageProvider(storageProvider) - .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .maxPeers(25) .maxRemotelyInitiatedPeers(15) @@ -634,6 +633,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner { new BesuCommand( RlpBlockImporter::new, JsonBlockImporter::new, + Era1BlockImporter::new, RlpBlockExporter::new, new RunnerBuilder(), new BesuController.Builder(), diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/Cluster.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/Cluster.java index b454894e0..acd0ac37f 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/Cluster.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/Cluster.java @@ -91,12 +91,14 @@ public class Cluster implements AutoCloseable { .forEach(this::startNode); if (clusterConfiguration.isAwaitPeerDiscovery()) { + int timeoutSeconds = clusterConfiguration.getPeerDiscoveryTimeoutSeconds(); for (final RunnableNode node : nodes) { LOG.info( - "Awaiting peer discovery for node {}, expecting {} peers", + "Awaiting peer discovery for node {}, expecting {} peers, timeout {} seconds", node.getName(), - nodes.size() - 1); - node.awaitPeerDiscovery(net.awaitPeerCount(nodes.size() - 1)); + nodes.size() - 1, + timeoutSeconds); + node.awaitPeerDiscovery(net.awaitPeerCount(nodes.size() - 1, timeoutSeconds)); } } LOG.info("Cluster startup complete."); diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfiguration.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfiguration.java index 4d0505478..232ecd8ef 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfiguration.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfiguration.java @@ -17,12 +17,18 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.cluster; public class ClusterConfiguration { private final boolean awaitPeerDiscovery; + private final int peerDiscoveryTimeoutSeconds; - ClusterConfiguration(final boolean awaitPeerDiscovery) { + ClusterConfiguration(final boolean awaitPeerDiscovery, final int peerDiscoveryTimeoutSeconds) { this.awaitPeerDiscovery = awaitPeerDiscovery; + this.peerDiscoveryTimeoutSeconds = peerDiscoveryTimeoutSeconds; } public boolean isAwaitPeerDiscovery() { return awaitPeerDiscovery; } + + public int getPeerDiscoveryTimeoutSeconds() { + return peerDiscoveryTimeoutSeconds; + } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfigurationBuilder.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfigurationBuilder.java index 1e434e54c..75ddad988 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfigurationBuilder.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/cluster/ClusterConfigurationBuilder.java @@ -16,13 +16,19 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.cluster; public class ClusterConfigurationBuilder { private boolean awaitPeerDiscovery = true; + private int peerDiscoveryTimeoutSeconds = 60; // Default 60 second timeout public ClusterConfigurationBuilder awaitPeerDiscovery(final boolean awaitPeerDiscovery) { this.awaitPeerDiscovery = awaitPeerDiscovery; return this; } + public ClusterConfigurationBuilder peerDiscoveryTimeout(final int timeoutSeconds) { + this.peerDiscoveryTimeoutSeconds = timeoutSeconds; + return this; + } + public ClusterConfiguration build() { - return new ClusterConfiguration(awaitPeerDiscovery); + return new ClusterConfiguration(awaitPeerDiscovery, peerDiscoveryTimeoutSeconds); } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java index 9ec9ae340..ce29b22e2 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration; import org.hyperledger.besu.ethereum.core.MiningConfiguration; import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; @@ -73,6 +74,7 @@ public class BesuNodeConfiguration { private final Optional keyPair; private final boolean strictTxReplayProtectionEnabled; private final Map environment; + private final SynchronizerConfiguration synchronizerConfiguration; private final Optional storageFactory; BesuNodeConfiguration( @@ -111,6 +113,7 @@ public class BesuNodeConfiguration { final Optional keyPair, final boolean strictTxReplayProtectionEnabled, final Map environment, + final SynchronizerConfiguration synchronizerConfiguration, final Optional storageFactory) { this.name = name; this.miningConfiguration = miningConfiguration; @@ -147,6 +150,7 @@ public class BesuNodeConfiguration { this.keyPair = keyPair; this.strictTxReplayProtectionEnabled = strictTxReplayProtectionEnabled; this.environment = environment; + this.synchronizerConfiguration = synchronizerConfiguration; this.storageFactory = storageFactory; } @@ -290,6 +294,10 @@ public class BesuNodeConfiguration { return environment; } + public SynchronizerConfiguration getSynchronizerConfiguration() { + return synchronizerConfiguration; + } + public Optional storageImplementation() { return storageFactory; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java index 1222f73b6..5031153aa 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java @@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration; import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration.MutableInitValues; import org.hyperledger.besu.ethereum.core.MiningConfiguration; import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration; import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; @@ -96,6 +97,7 @@ public class BesuNodeConfigurationBuilder { private Optional keyPair = Optional.empty(); private Boolean strictTxReplayProtectionEnabled = false; private Map environment = new HashMap<>(); + private SynchronizerConfiguration synchronizerConfiguration; private Optional storageImplementation = Optional.empty(); public BesuNodeConfigurationBuilder() { @@ -467,7 +469,17 @@ public class BesuNodeConfigurationBuilder { return this; } + public BesuNodeConfigurationBuilder synchronizerConfiguration( + final SynchronizerConfiguration config) { + this.synchronizerConfiguration = config; + return this; + } + public BesuNodeConfiguration build() { + if (name == null) { + throw new IllegalStateException("Name is required"); + } + return new BesuNodeConfiguration( name, dataPath, @@ -504,6 +516,7 @@ public class BesuNodeConfigurationBuilder { keyPair, strictTxReplayProtectionEnabled, environment, + synchronizerConfiguration, storageImplementation); } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java index 9974adf6f..17b28490c 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java @@ -490,6 +490,39 @@ public class BesuNodeFactory { return create(builder.build()); } + public BesuNode createQbftMigrationNode( + final String name, final boolean fixedPort, final DataStorageFormat storageFormat) + throws IOException { + JsonRpcConfiguration rpcConfig = node.createJsonRpcWithQbftEnabledConfig(false); + rpcConfig.addRpcApi("ADMIN,TXPOOL"); + if (fixedPort) { + rpcConfig.setPort( + Math.abs(name.hashCode() % 60000) + + 1024); // Generate a consistent port for p2p based on node name + } + + BesuNodeConfigurationBuilder builder = + new BesuNodeConfigurationBuilder() + .name(name) + .miningEnabled() + .jsonRpcConfiguration(rpcConfig) + .webSocketConfiguration(node.createWebSocketEnabledConfig()) + .devMode(false) + .dataStorageConfiguration( + storageFormat == DataStorageFormat.FOREST + ? DataStorageConfiguration.DEFAULT_FOREST_CONFIG + : DataStorageConfiguration.DEFAULT_BONSAI_CONFIG) + .genesisConfigProvider(GenesisConfigurationFactory::createQbftMigrationGenesisConfig); + if (fixedPort) { + builder.p2pPort( + Math.abs(name.hashCode() % 60000) + + 1024 + + 500); // Generate a consistent port for p2p based on node name (+ 500 to avoid + // clashing with RPC port or other nodes with a similar name) + } + return create(builder.build()); + } + public BesuNode createCustomGenesisNode( final String name, final String genesisPath, final boolean canBeBootnode) throws IOException { return createCustomGenesisNode(name, genesisPath, canBeBootnode, false); @@ -539,6 +572,12 @@ public class BesuNodeFactory { public BesuNode createCliqueNodeWithValidators(final String name, final String... validators) throws IOException { + return createCliqueNodeWithValidators(name, CliqueOptions.DEFAULT, validators); + } + + public BesuNode createCliqueNodeWithValidators( + final String name, final CliqueOptions cliqueOptions, final String... validators) + throws IOException { return create( new BesuNodeConfigurationBuilder() @@ -553,7 +592,9 @@ public class BesuNodeFactory { node.createGenesisConfigForValidators( asList(validators), nodes, - GenesisConfigurationFactory::createCliqueGenesisConfig)) + vs -> + GenesisConfigurationFactory.createCliqueGenesisConfig( + vs, cliqueOptions))) .build()); } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/genesis/GenesisConfigurationFactory.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/genesis/GenesisConfigurationFactory.java index 80bbf4c92..ac63202b5 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/genesis/GenesisConfigurationFactory.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/genesis/GenesisConfigurationFactory.java @@ -96,6 +96,13 @@ public class GenesisConfigurationFactory { validators, template, QbftExtraDataCodec::createGenesisExtraDataString); } + public static Optional createQbftMigrationGenesisConfig( + final Collection validators) { + final String template = readGenesisFile("/qbft/migration-ibft1/qbft-migration.json"); + return updateGenesisExtraData( + validators, template, QbftExtraDataCodec::createGenesisExtraDataString); + } + @SuppressWarnings("unchecked") public static Optional createQbftValidatorContractGenesisConfig( final Collection validators) throws UncheckedIOException { diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningAllowAccountTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningAllowAccountTransaction.java deleted file mode 100644 index 7b0f83b48..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningAllowAccountTransaction.java +++ /dev/null @@ -1,78 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class AccountSmartContractPermissioningAllowAccountTransaction implements Transaction { - - private static final Bytes ADD_ACCOUNT_SIGNATURE = - org.hyperledger.besu.crypto.Hash.keccak256(Bytes.of("addAccount(address)".getBytes(UTF_8))) - .slice(0, 4); - - private final Account sender; - private final Address contractAddress; - private final Address account; - - public AccountSmartContractPermissioningAllowAccountTransaction( - final Account sender, final Address contractAddress, final Address account) { - this.sender = sender; - this.contractAddress = contractAddress; - this.account = account; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final Bytes payload = - Bytes.concatenate( - ADD_ACCOUNT_SIGNATURE, Bytes.fromHexString("0x000000000000000000000000"), account); - - final RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1000), - BigInteger.valueOf(100_000), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningForbidAccountTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningForbidAccountTransaction.java deleted file mode 100644 index 2856ec396..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningForbidAccountTransaction.java +++ /dev/null @@ -1,79 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class AccountSmartContractPermissioningForbidAccountTransaction - implements Transaction { - - private static final Bytes REMOVE_ACCOUNT_SIGNATURE = - org.hyperledger.besu.crypto.Hash.keccak256(Bytes.of("removeAccount(address)".getBytes(UTF_8))) - .slice(0, 4); - - private final Account sender; - private final Address contractAddress; - private final Address account; - - public AccountSmartContractPermissioningForbidAccountTransaction( - final Account sender, final Address contractAddress, final Address account) { - this.sender = sender; - this.contractAddress = contractAddress; - this.account = account; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final Bytes payload = - Bytes.concatenate( - REMOVE_ACCOUNT_SIGNATURE, Bytes.fromHexString("0x000000000000000000000000"), account); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1000), - BigInteger.valueOf(100_000), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningIsAllowedTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningIsAllowedTransaction.java deleted file mode 100644 index 6faa72cb0..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningIsAllowedTransaction.java +++ /dev/null @@ -1,88 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.besu.crypto.Hash; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.protocol.core.DefaultBlockParameterName; - -public class AccountSmartContractPermissioningIsAllowedTransaction implements Transaction { - - private static final Bytes IS_ACCOUNT_ALLOWED_SIGNATURE = - Hash.keccak256(Bytes.of("whitelistContains(address)".getBytes(UTF_8))).slice(0, 4); - - private final Address contractAddress; - private final Address account; - - public AccountSmartContractPermissioningIsAllowedTransaction( - final Address contractAddress, final Address account) { - this.contractAddress = contractAddress; - this.account = account; - } - - @Override - public Boolean execute(final NodeRequests node) { - try { - final String value = - node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue(); - return checkTransactionResult(Bytes.fromHexString(value)); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - // Checks the returned bytes from the permissioning contract call to see if it's a value we - // understand - static Boolean checkTransactionResult(final Bytes result) { - // booleans are padded to 32 bytes - if (result.size() != 32) { - throw new IllegalArgumentException("Unexpected result size"); - } - - // 0 is false - if (result.equals( - Bytes.fromHexString( - "0x0000000000000000000000000000000000000000000000000000000000000000"))) { - return false; - // 1 filled to 32 bytes is true - } else if (result.equals( - Bytes.fromHexString( - "0x0000000000000000000000000000000000000000000000000000000000000001"))) { - return true; - // Anything else is wrong - } else { - throw new IllegalStateException("Unexpected result form"); - } - } - - private org.web3j.protocol.core.methods.request.Transaction payload() { - final Bytes payload = - Bytes.concatenate( - IS_ACCOUNT_ALLOWED_SIGNATURE, - Bytes.fromHexString("0x000000000000000000000000"), - account); - - return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction( - null, null, null, null, contractAddress.toString(), payload.toString()); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningTransactions.java deleted file mode 100644 index 86dbd900b..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/AccountSmartContractPermissioningTransactions.java +++ /dev/null @@ -1,50 +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.tests.acceptance.dsl.transaction.perm; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -public class AccountSmartContractPermissioningTransactions { - - private final Accounts accounts; - - public AccountSmartContractPermissioningTransactions(final Accounts accounts) { - this.accounts = accounts; - } - - public Transaction allowAccount(final String contractAddress, final Account account) { - return new AccountSmartContractPermissioningAllowAccountTransaction( - accounts.getPrimaryBenefactor(), - Address.fromHexString(contractAddress), - Address.fromHexString(account.getAddress())); - } - - public Transaction forbidAccount(final String contractAddress, final Account account) { - return new AccountSmartContractPermissioningForbidAccountTransaction( - accounts.getPrimaryBenefactor(), - Address.fromHexString(contractAddress), - Address.fromHexString(account.getAddress())); - } - - public Transaction isAccountAllowed( - final String contractAddress, final Account account) { - return new AccountSmartContractPermissioningIsAllowedTransaction( - Address.fromHexString(contractAddress), Address.fromHexString(account.getAddress())); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeByURLV2Transaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeByURLV2Transaction.java deleted file mode 100644 index 6cfd2af95..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeByURLV2Transaction.java +++ /dev/null @@ -1,95 +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.tests.acceptance.dsl.transaction.perm; - -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.datatypes.Function; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class NodeSmartContractPermissioningAllowNodeByURLV2Transaction - implements Transaction { - - private final Account sender; - private final Address contractAddress; - private final EnodeURL enodeUrl; - - public NodeSmartContractPermissioningAllowNodeByURLV2Transaction( - final Account sender, final Address contractAddress, final EnodeURL enodeUrl) { - this.sender = sender; - this.contractAddress = contractAddress; - this.enodeUrl = enodeUrl; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final Bytes payload = createPayload(enodeUrl); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1_000L), - BigInteger.valueOf(3_000_000L), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } - - private Bytes createPayload(final EnodeURL enodeUrl) { - try { - final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString(); - final String address = enodeUrl.toURI().getHost(); - final int port = enodeUrl.getListeningPortOrZero(); - - final Function addNodeFunction = - FunctionEncoder.makeFunction( - "addEnode", - List.of("string", "string", "uint16"), - List.of(hexNodeIdString, address, port), - Collections.emptyList()); - return Bytes.fromHexString(FunctionEncoder.encode(addNodeFunction)); - } catch (Exception e) { - throw new RuntimeException("Error adding node to allowlist", e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeTransaction.java deleted file mode 100644 index 2579dc114..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeTransaction.java +++ /dev/null @@ -1,84 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class NodeSmartContractPermissioningAllowNodeTransaction implements Transaction { - - private static final Bytes ADD_ENODE_SIGNATURE = - org.hyperledger.besu.crypto.Hash.keccak256( - Bytes.of("addEnode(bytes32,bytes32,bytes16,uint16)".getBytes(UTF_8))) - .slice(0, 4); - - private final Account sender; - private final Address contractAddress; - private final Node node; - - public NodeSmartContractPermissioningAllowNodeTransaction( - final Account sender, final Address contractAddress, final Node node) { - this.sender = sender; - this.contractAddress = contractAddress; - this.node = node; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final String enodeURL = ((RunnableNode) node).enodeUrl().toASCIIString(); - final Bytes payload = - NodeSmartContractPermissioningController.createPayload( - ADD_ENODE_SIGNATURE, EnodeURLImpl.fromString(enodeURL)); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1000), - BigInteger.valueOf(100_000), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeV2Transaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeV2Transaction.java deleted file mode 100644 index 6cfee3f10..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningAllowNodeV2Transaction.java +++ /dev/null @@ -1,98 +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.tests.acceptance.dsl.transaction.perm; - -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.datatypes.Function; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class NodeSmartContractPermissioningAllowNodeV2Transaction implements Transaction { - - private final Account sender; - private final Address contractAddress; - private final Node node; - - public NodeSmartContractPermissioningAllowNodeV2Transaction( - final Account sender, final Address contractAddress, final Node node) { - this.sender = sender; - this.contractAddress = contractAddress; - this.node = node; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final EnodeURL enodeURL = EnodeURLImpl.fromURI(((RunnableNode) node).enodeUrl()); - final Bytes payload = createPayload(enodeURL); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1_000L), - BigInteger.valueOf(3_000_000L), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } - - private Bytes createPayload(final EnodeURL enodeUrl) { - try { - final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString(); - final String address = enodeUrl.getIp().getHostAddress(); - final int port = enodeUrl.getListeningPortOrZero(); - - final Function addNodeFunction = - FunctionEncoder.makeFunction( - "addEnode", - List.of("string", "string", "uint16"), - List.of(hexNodeIdString, address, port), - Collections.emptyList()); - return Bytes.fromHexString(FunctionEncoder.encode(addNodeFunction)); - } catch (Exception e) { - throw new RuntimeException("Error adding node to allowlist", e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction.java deleted file mode 100644 index af6d753d0..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction.java +++ /dev/null @@ -1,80 +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.tests.acceptance.dsl.transaction.perm; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractV2PermissioningController; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.datatypes.Function; -import org.web3j.protocol.core.DefaultBlockParameterName; - -public class NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction - implements Transaction { - - private final Address contractAddress; - private final EnodeURL enodeUrl; - - public NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction( - final Address contractAddress, final EnodeURL enodeUrl) { - this.contractAddress = contractAddress; - this.enodeUrl = enodeUrl; - } - - @Override - public Boolean execute(final NodeRequests node) { - try { - final String value = - node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue(); - return Bytes.fromHexString(value) - .equals(NodeSmartContractV2PermissioningController.TRUE_RESPONSE); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private org.web3j.protocol.core.methods.request.Transaction payload() { - final Bytes payload = createPayload(this.enodeUrl); - - return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction( - null, null, null, null, contractAddress.toString(), payload.toString()); - } - - private Bytes createPayload(final EnodeURL enodeUrl) { - try { - final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString(); - final String address = enodeUrl.toURI().getHost(); - final int port = enodeUrl.getListeningPortOrZero(); - - final Function connectionAllowedFunction = - FunctionEncoder.makeFunction( - "connectionAllowed", - List.of("string", "string", "uint16"), - List.of(hexNodeIdString, address, port), - Collections.emptyList()); - return Bytes.fromHexString(FunctionEncoder.encode(connectionAllowedFunction)); - } catch (Exception e) { - throw new RuntimeException("Error calling connectionAllowed", e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedTransaction.java deleted file mode 100644 index 80b08e954..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedTransaction.java +++ /dev/null @@ -1,78 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController.checkTransactionResult; - -import org.hyperledger.besu.crypto.Hash; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.protocol.core.DefaultBlockParameterName; - -public class NodeSmartContractPermissioningConnectionIsAllowedTransaction - implements Transaction { - - private static final Bytes IS_CONNECTION_ALLOWED_SIGNATURE = - Hash.keccak256( - Bytes.of( - "connectionAllowed(bytes32,bytes32,bytes16,uint16,bytes32,bytes32,bytes16,uint16)" - .getBytes(UTF_8))) - .slice(0, 4); - - private final Address contractAddress; - private final Node source; - private final Node target; - - public NodeSmartContractPermissioningConnectionIsAllowedTransaction( - final Address contractAddress, final Node source, final Node target) { - this.contractAddress = contractAddress; - this.source = source; - this.target = target; - } - - @Override - public Boolean execute(final NodeRequests node) { - try { - final String value = - node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue(); - return checkTransactionResult(Bytes.fromHexString(value)); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private org.web3j.protocol.core.methods.request.Transaction payload() { - final String sourceEnodeURL = ((RunnableNode) source).enodeUrl().toASCIIString(); - final String targetEnodeURL = ((RunnableNode) target).enodeUrl().toASCIIString(); - final Bytes payload = - NodeSmartContractPermissioningController.createPayload( - IS_CONNECTION_ALLOWED_SIGNATURE, - EnodeURLImpl.fromString(sourceEnodeURL), - EnodeURLImpl.fromString(targetEnodeURL)); - - return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction( - null, null, null, null, contractAddress.toString(), payload.toString()); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedV2Transaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedV2Transaction.java deleted file mode 100644 index 1eeadb52a..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningConnectionIsAllowedV2Transaction.java +++ /dev/null @@ -1,84 +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.tests.acceptance.dsl.transaction.perm; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractV2PermissioningController; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.datatypes.Function; -import org.web3j.protocol.core.DefaultBlockParameterName; - -public class NodeSmartContractPermissioningConnectionIsAllowedV2Transaction - implements Transaction { - - private final Address contractAddress; - private final Node node; - - public NodeSmartContractPermissioningConnectionIsAllowedV2Transaction( - final Address contractAddress, final Node node) { - this.contractAddress = contractAddress; - this.node = node; - } - - @Override - public Boolean execute(final NodeRequests node) { - try { - final String value = - node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue(); - return Bytes.fromHexString(value) - .equals(NodeSmartContractV2PermissioningController.TRUE_RESPONSE); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private org.web3j.protocol.core.methods.request.Transaction payload() { - final EnodeURL enodeURL = EnodeURLImpl.fromURI(((RunnableNode) node).enodeUrl()); - final Bytes payload = createPayload(enodeURL); - - return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction( - null, null, null, null, contractAddress.toString(), payload.toString()); - } - - private Bytes createPayload(final EnodeURL enodeUrl) { - try { - final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString(); - final String address = enodeUrl.getIp().getHostAddress(); - final int port = enodeUrl.getListeningPortOrZero(); - - final Function connectionAllowedFunction = - FunctionEncoder.makeFunction( - "connectionAllowed", - List.of("string", "string", "uint16"), - List.of(hexNodeIdString, address, port), - Collections.emptyList()); - return Bytes.fromHexString(FunctionEncoder.encode(connectionAllowedFunction)); - } catch (Exception e) { - throw new RuntimeException("Error calling connectionAllowed", e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeByURLV2Transaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeByURLV2Transaction.java deleted file mode 100644 index d36f6b699..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeByURLV2Transaction.java +++ /dev/null @@ -1,95 +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.tests.acceptance.dsl.transaction.perm; - -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.datatypes.Function; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class NodeSmartContractPermissioningForbidNodeByURLV2Transaction - implements Transaction { - - private final Account sender; - private final Address contractAddress; - private final EnodeURL enodeUrl; - - public NodeSmartContractPermissioningForbidNodeByURLV2Transaction( - final Account sender, final Address contractAddress, final EnodeURL enodeUrl) { - this.sender = sender; - this.contractAddress = contractAddress; - this.enodeUrl = enodeUrl; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final Bytes payload = createPayload(this.enodeUrl); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1000), - BigInteger.valueOf(3_000_000L), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } - - private Bytes createPayload(final EnodeURL enodeUrl) { - try { - final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString(); - final String address = enodeUrl.toURI().getHost(); - final int port = enodeUrl.getListeningPortOrZero(); - - final Function removeNodeFunction = - FunctionEncoder.makeFunction( - "removeEnode", - List.of("string", "string", "uint16"), - List.of(hexNodeIdString, address, port), - Collections.emptyList()); - return Bytes.fromHexString(FunctionEncoder.encode(removeNodeFunction)); - } catch (Exception e) { - throw new RuntimeException("Error removing node from allowlist", e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeTransaction.java deleted file mode 100644 index 787cb9752..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeTransaction.java +++ /dev/null @@ -1,84 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class NodeSmartContractPermissioningForbidNodeTransaction implements Transaction { - - private static final Bytes REMOVE_ENODE_SIGNATURE = - org.hyperledger.besu.crypto.Hash.keccak256( - Bytes.of("removeEnode(bytes32,bytes32,bytes16,uint16)".getBytes(UTF_8))) - .slice(0, 4); - - private final Account sender; - private final Address contractAddress; - private final Node node; - - public NodeSmartContractPermissioningForbidNodeTransaction( - final Account sender, final Address contractAddress, final Node node) { - this.sender = sender; - this.contractAddress = contractAddress; - this.node = node; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final String enodeURL = ((RunnableNode) node).enodeUrl().toASCIIString(); - final Bytes payload = - NodeSmartContractPermissioningController.createPayload( - REMOVE_ENODE_SIGNATURE, EnodeURLImpl.fromString(enodeURL)); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1000), - BigInteger.valueOf(100_000), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeV2Transaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeV2Transaction.java deleted file mode 100644 index e5c39d69a..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningForbidNodeV2Transaction.java +++ /dev/null @@ -1,98 +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.tests.acceptance.dsl.transaction.perm; - -import static org.web3j.utils.Numeric.toHexString; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; -import java.math.BigInteger; -import java.util.Collections; -import java.util.List; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.abi.FunctionEncoder; -import org.web3j.abi.datatypes.Function; -import org.web3j.crypto.RawTransaction; -import org.web3j.crypto.TransactionEncoder; - -public class NodeSmartContractPermissioningForbidNodeV2Transaction implements Transaction { - - private final Account sender; - private final Address contractAddress; - private final Node node; - - public NodeSmartContractPermissioningForbidNodeV2Transaction( - final Account sender, final Address contractAddress, final Node node) { - this.sender = sender; - this.contractAddress = contractAddress; - this.node = node; - } - - @Override - public Hash execute(final NodeRequests node) { - final String signedTransactionData = signedTransactionData(); - try { - String hash = - node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash(); - return Hash.fromHexString(hash); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private String signedTransactionData() { - final EnodeURL enodeURL = EnodeURLImpl.fromURI(((RunnableNode) node).enodeUrl()); - final Bytes payload = createPayload(enodeURL); - - RawTransaction transaction = - RawTransaction.createTransaction( - sender.getNextNonce(), - BigInteger.valueOf(1000), - BigInteger.valueOf(3_000_000L), - contractAddress.toString(), - payload.toString()); - - return toHexString( - TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow())); - } - - private Bytes createPayload(final EnodeURL enodeUrl) { - try { - final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString(); - final String address = enodeUrl.getIp().getHostAddress(); - final int port = enodeUrl.getListeningPortOrZero(); - - final Function removeNodeFunction = - FunctionEncoder.makeFunction( - "removeEnode", - List.of("string", "string", "uint16"), - List.of(hexNodeIdString, address, port), - Collections.emptyList()); - return Bytes.fromHexString(FunctionEncoder.encode(removeNodeFunction)); - } catch (Exception e) { - throw new RuntimeException("Error removing node from allowlist", e); - } - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningIsAllowedTransaction.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningIsAllowedTransaction.java deleted file mode 100644 index d72d6ffab..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningIsAllowedTransaction.java +++ /dev/null @@ -1,92 +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.tests.acceptance.dsl.transaction.perm; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import org.hyperledger.besu.crypto.Hash; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -import java.io.IOException; - -import org.apache.tuweni.bytes.Bytes; -import org.web3j.protocol.core.DefaultBlockParameterName; - -public class NodeSmartContractPermissioningIsAllowedTransaction implements Transaction { - - private static final Bytes IS_NODE_ALLOWED_SIGNATURE = - Hash.keccak256(Bytes.of("enodeAllowed(bytes32,bytes32,bytes16,uint16)".getBytes(UTF_8))) - .slice(0, 4); - - private final Address contractAddress; - private final Node node; - - public NodeSmartContractPermissioningIsAllowedTransaction( - final Address contractAddress, final Node node) { - this.contractAddress = contractAddress; - this.node = node; - } - - @Override - public Boolean execute(final NodeRequests node) { - try { - final String value = - node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue(); - return checkTransactionResult(Bytes.fromHexString(value)); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - - // Checks the returned bytes from the permissioning contract call to see if it's a value we - // understand - static Boolean checkTransactionResult(final Bytes result) { - // booleans are padded to 32 bytes - if (result.size() != 32) { - throw new IllegalArgumentException("Unexpected result size"); - } - - // 0 is false - if (result.equals( - Bytes.fromHexString( - "0x0000000000000000000000000000000000000000000000000000000000000000"))) { - return false; - // 1 filled to 32 bytes is true - } else if (result.equals( - Bytes.fromHexString( - "0x0000000000000000000000000000000000000000000000000000000000000001"))) { - return true; - // Anything else is wrong - } else { - throw new IllegalStateException("Unexpected result form"); - } - } - - private org.web3j.protocol.core.methods.request.Transaction payload() { - final String sourceEnodeURL = ((RunnableNode) node).enodeUrl().toASCIIString(); - final Bytes payload = - NodeSmartContractPermissioningController.createPayload( - IS_NODE_ALLOWED_SIGNATURE, EnodeURLImpl.fromString(sourceEnodeURL)); - - return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction( - null, null, null, null, contractAddress.toString(), payload.toString()); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningTransactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningTransactions.java deleted file mode 100644 index 8de39e930..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningTransactions.java +++ /dev/null @@ -1,51 +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.tests.acceptance.dsl.transaction.perm; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -public class NodeSmartContractPermissioningTransactions { - - private final Accounts accounts; - - public NodeSmartContractPermissioningTransactions(final Accounts accounts) { - this.accounts = accounts; - } - - public Transaction allowNode(final String contractAddress, final Node node) { - return new NodeSmartContractPermissioningAllowNodeTransaction( - accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node); - } - - public Transaction forbidNode(final String contractAddress, final Node node) { - return new NodeSmartContractPermissioningForbidNodeTransaction( - accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node); - } - - public Transaction isNodeAllowed(final String contractAddress, final Node node) { - return new NodeSmartContractPermissioningIsAllowedTransaction( - Address.fromHexString(contractAddress), node); - } - - public Transaction isConnectionAllowed( - final String contractAddress, final Node source, final Node target) { - return new NodeSmartContractPermissioningConnectionIsAllowedTransaction( - Address.fromHexString(contractAddress), source, target); - } -} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningV2Transactions.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningV2Transactions.java deleted file mode 100644 index 51d4d4466..000000000 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/perm/NodeSmartContractPermissioningV2Transactions.java +++ /dev/null @@ -1,62 +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.tests.acceptance.dsl.transaction.perm; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; - -public class NodeSmartContractPermissioningV2Transactions { - - private final Accounts accounts; - - public NodeSmartContractPermissioningV2Transactions(final Accounts accounts) { - this.accounts = accounts; - } - - public Transaction allowNode(final String contractAddress, final Node node) { - return new NodeSmartContractPermissioningAllowNodeV2Transaction( - accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node); - } - - public Transaction allowNode(final String contractAddress, final EnodeURL enodeURL) { - return new NodeSmartContractPermissioningAllowNodeByURLV2Transaction( - accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), enodeURL); - } - - public Transaction forbidNode(final String contractAddress, final Node node) { - return new NodeSmartContractPermissioningForbidNodeV2Transaction( - accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node); - } - - public Transaction forbidNode(final String contractAddress, final EnodeURL enodeURL) { - return new NodeSmartContractPermissioningForbidNodeByURLV2Transaction( - accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), enodeURL); - } - - public Transaction isConnectionAllowed(final String contractAddress, final Node node) { - return new NodeSmartContractPermissioningConnectionIsAllowedV2Transaction( - Address.fromHexString(contractAddress), node); - } - - public Transaction isConnectionAllowed( - final String contractAddress, final EnodeURL enodeURL) { - return new NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction( - Address.fromHexString(contractAddress), enodeURL); - } -} diff --git a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java index c2503ed81..6d59f2dfd 100644 --- a/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java +++ b/acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestPermissioningPlugin.java @@ -75,6 +75,20 @@ public class TestPermissioningPlugin implements BesuPlugin { } return true; }); + + service.registerTransactionPermissioningProvider( + transaction -> { + long configuredGasLimitThreshold = 22000L; + long gasLimit = transaction.getGasLimit(); + LOG.info( + "Transaction gas limit: {} | Configured threshold: {} ", + gasLimit, + configuredGasLimitThreshold); + // Sample logic to testing. If the gas limit is exactly 21000 (intrinsic gas limit) + // we let the transaction pass. This is helpful for not making additional configuration + // options in PermssioningPluginTest + return gasLimit > configuredGasLimitThreshold || gasLimit == 21000; + }); } } diff --git a/acceptance-tests/tests/build.gradle b/acceptance-tests/tests/build.gradle index 126dcb070..7d252e624 100644 --- a/acceptance-tests/tests/build.gradle +++ b/acceptance-tests/tests/build.gradle @@ -12,8 +12,8 @@ */ plugins { - id 'org.web3j' version '4.11.3' - id 'org.web3j.solidity' version '0.4.1' + id 'org.web3j' version '4.12.2' + id 'org.web3j.solidity' version '0.5.2' } web3j { generatedPackageName = 'org.hyperledger.besu.tests.web3j.generated' } @@ -73,14 +73,13 @@ dependencies { testImplementation 'io.vertx:vertx-core' testImplementation 'org.apache.commons:commons-compress' testImplementation 'org.apache.logging.log4j:log4j-core' - testImplementation 'io.tmio:tuweni-crypto' + testImplementation 'io.consensys.protocols:tuweni-crypto' testImplementation 'org.assertj:assertj-core' testImplementation 'org.awaitility:awaitility' testImplementation 'org.junit.jupiter:junit-jupiter' testImplementation 'org.web3j:abi' testImplementation 'org.web3j:besu' testImplementation 'org.web3j:core' - testImplementation 'org.wiremock:wiremock' testImplementation 'com.google.dagger:dagger' testAnnotationProcessor 'com.google.dagger:dagger-compiler' testImplementation project(path: ':acceptance-tests:tests:shanghai') diff --git a/acceptance-tests/tests/shanghai/build.gradle b/acceptance-tests/tests/shanghai/build.gradle index c309d9e99..660650dc3 100644 --- a/acceptance-tests/tests/shanghai/build.gradle +++ b/acceptance-tests/tests/shanghai/build.gradle @@ -1,7 +1,7 @@ plugins { - id 'org.web3j' version '4.11.3' - id 'org.web3j.solidity' version '0.4.1' + id 'org.web3j' version '4.12.2' + id 'org.web3j.solidity' version '0.5.2' } jar { enabled = true } diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/AbstractPreexistingNodeTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/AbstractPreexistingNodeTest.java index fe1489210..d0b6b4570 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/AbstractPreexistingNodeTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/AbstractPreexistingNodeTest.java @@ -48,7 +48,7 @@ public class AbstractPreexistingNodeTest extends AcceptanceTestBase { new TarArchiveInputStream( new GzipCompressorInputStream(new FileInputStream(path.toAbsolutePath().toString())))) { TarArchiveEntry entry; - while ((entry = fin.getNextTarEntry()) != null) { + while ((entry = fin.getNextEntry()) != null) { if (entry.isDirectory()) { continue; } diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/QuorumIBFTMigrationTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/QuorumIBFTMigrationTest.java new file mode 100644 index 000000000..8423bfdf2 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/QuorumIBFTMigrationTest.java @@ -0,0 +1,118 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.tests.acceptance; + +import static org.apache.logging.log4j.util.LoaderUtil.getClassLoader; + +import org.hyperledger.besu.plugin.services.storage.DataStorageFormat; +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +import org.junit.jupiter.api.Test; + +public class QuorumIBFTMigrationTest extends AcceptanceTestBase { + + public static void copyKeyFilesToNodeDataDirs(final BesuNode... nodes) throws IOException { + for (BesuNode node : nodes) { + copyKeyFile(node, "key"); + copyKeyFile(node, "key.pub"); + } + } + + private static void copyKeyFile(final BesuNode node, final String keyFileName) + throws IOException { + String resourceFileName = "qbft/migration-ibft1/" + node.getName() + keyFileName; + try (InputStream keyFileStream = getClassLoader().getResourceAsStream(resourceFileName)) { + if (keyFileStream == null) { + throw new IOException("Resource not found: " + resourceFileName); + } + Path targetPath = node.homeDirectory().resolve(keyFileName); + Files.createDirectories(targetPath.getParent()); + Files.copy(keyFileStream, targetPath, StandardCopyOption.REPLACE_EXISTING); + } + } + + public static void runBesuCommand(final Path dataPath) throws IOException, InterruptedException { + ProcessBuilder processBuilder = + new ProcessBuilder( + "../../build/install/besu/bin/besu", + "--genesis-file", + "src/test/resources/qbft/migration-ibft1/qbft-migration.json", + "--data-path", + dataPath.toString(), + "--data-storage-format", + "FOREST", + "blocks", + "import", + "src/test/resources/qbft/migration-ibft1/ibft.blocks"); + + processBuilder.directory(new File(System.getProperty("user.dir"))); + processBuilder.inheritIO(); // This will redirect the output to the console + + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + if (exitCode == 0) { + System.out.println("Import command executed successfully."); + } else { + throw new RuntimeException("Import command execution failed with exit code: " + exitCode); + } + } + + @Test + public void shouldImportIBFTBlocksAndTransitionToQBFT() throws Exception { + + // Create a mix of Bonsai and Forest DB nodes + final BesuNode minerNode1 = + besu.createQbftMigrationNode("miner1", false, DataStorageFormat.FOREST); + final BesuNode minerNode2 = + besu.createQbftMigrationNode("miner2", false, DataStorageFormat.FOREST); + final BesuNode minerNode3 = + besu.createQbftMigrationNode("miner3", false, DataStorageFormat.FOREST); + final BesuNode minerNode4 = + besu.createQbftMigrationNode("miner4", false, DataStorageFormat.FOREST); + final BesuNode minerNode5 = + besu.createQbftMigrationNode("miner5", false, DataStorageFormat.FOREST); + + // Copy key files to the node datadirs + // Use the key files saved in resources directory + copyKeyFilesToNodeDataDirs(minerNode1, minerNode2, minerNode3, minerNode4, minerNode5); + + // start one node and import blocks from import file + // Use import file, genesis saved in resources directory + + runBesuCommand(minerNode1.homeDirectory()); + + // After the import is done, start the rest of the nodes using the same genesis and respective + // node keys + + cluster.start(minerNode1, minerNode2, minerNode3, minerNode4, minerNode5); + + // Check that the chain is progressing as expected + cluster.verify(blockchain.reachesHeight(minerNode2, 1, 120)); + } + + @Override + public void tearDownAcceptanceTestBase() { + cluster.stop(); + super.tearDownAcceptanceTestBase(); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest.java deleted file mode 100644 index 177987aaa..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest.java +++ /dev/null @@ -1,290 +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.tests.acceptance.bft; - -import org.hyperledger.besu.config.JsonUtil; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.core.AddressHelpers; -import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration; -import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration.MutableInitValues; -import org.hyperledger.besu.ethereum.core.MiningConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Amount; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; - -import java.util.List; -import java.util.Optional; - -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -public class BftMiningAcceptanceTest extends ParameterizedBftTestBase { - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnSingleNodeWithPaidGas_Berlin( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); - cluster.start(minerNode); - - cluster.verify(blockchain.reachesHeight(minerNode, 1)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - minerNode.execute(accountTransactions.createTransfer(sender, 50)); - cluster.verify(sender.balanceEquals(50)); - - minerNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); - cluster.verify(receiver.balanceEquals(1)); - - minerNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 2)); - cluster.verify(receiver.balanceEquals(3)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnSingleNodeWithFreeGas_Berlin( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); - final MiningConfiguration zeroGasMiningParams = - ImmutableMiningConfiguration.builder() - .mutableInitValues( - MutableInitValues.builder() - .isMiningEnabled(true) - .minTransactionGasPrice(Wei.ZERO) - .coinbase(AddressHelpers.ofValue(1)) - .build()) - .build(); - minerNode.setMiningParameters(zeroGasMiningParams); - - cluster.start(minerNode); - - cluster.verify(blockchain.reachesHeight(minerNode, 1)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - minerNode.execute(accountTransactions.createTransfer(sender, 50, Amount.ZERO)); - cluster.verify(sender.balanceEquals(50)); - - minerNode.execute( - accountTransactions.createIncrementalTransfers(sender, receiver, 1, Amount.ZERO)); - cluster.verify(receiver.balanceEquals(1)); - - minerNode.execute( - accountTransactions.createIncrementalTransfers(sender, receiver, 2, Amount.ZERO)); - cluster.verify(receiver.balanceEquals(3)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnSingleNodeWithPaidGas_London( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); - updateGenesisConfigToLondon(minerNode, false); - - cluster.start(minerNode); - - cluster.verify(blockchain.reachesHeight(minerNode, 1)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - minerNode.execute(accountTransactions.createTransfer(sender, 50)); - cluster.verify(sender.balanceEquals(50)); - - minerNode.execute(accountTransactions.create1559Transfer(sender, 50, 4)); - cluster.verify(sender.balanceEquals(100)); - - minerNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); - cluster.verify(receiver.balanceEquals(1)); - - minerNode.execute(accountTransactions.create1559IncrementalTransfers(sender, receiver, 2, 4)); - cluster.verify(receiver.balanceEquals(3)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnSingleNodeWithFreeGas_London( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); - updateGenesisConfigToLondon(minerNode, true); - - cluster.start(minerNode); - - cluster.verify(blockchain.reachesHeight(minerNode, 1)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - minerNode.execute(accountTransactions.createTransfer(sender, 50, Amount.ZERO)); - cluster.verify(sender.balanceEquals(50)); - - minerNode.execute(accountTransactions.create1559Transfer(sender, 50, 4, Amount.ZERO)); - cluster.verify(sender.balanceEquals(100)); - - minerNode.execute( - accountTransactions.createIncrementalTransfers(sender, receiver, 1, Amount.ZERO)); - cluster.verify(receiver.balanceEquals(1)); - - minerNode.execute( - accountTransactions.create1559IncrementalTransfers(sender, receiver, 2, 4, Amount.ZERO)); - cluster.verify(receiver.balanceEquals(3)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnSingleNodeWithFreeGas_Shanghai( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); - updateGenesisConfigToShanghai(minerNode, true); - - cluster.start(minerNode); - - cluster.verify(blockchain.reachesHeight(minerNode, 1)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - minerNode.execute(accountTransactions.createTransfer(sender, 50, Amount.ZERO)); - cluster.verify(sender.balanceEquals(50)); - - minerNode.execute(accountTransactions.create1559Transfer(sender, 50, 4, Amount.ZERO)); - cluster.verify(sender.balanceEquals(100)); - - minerNode.execute( - accountTransactions.createIncrementalTransfers(sender, receiver, 1, Amount.ZERO)); - cluster.verify(receiver.balanceEquals(1)); - - minerNode.execute( - accountTransactions.create1559IncrementalTransfers(sender, receiver, 2, 4, Amount.ZERO)); - cluster.verify(receiver.balanceEquals(3)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnMultipleNodes( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode1 = nodeFactory.createNode(besu, "miner1"); - final BesuNode minerNode2 = nodeFactory.createNode(besu, "miner2"); - final BesuNode minerNode3 = nodeFactory.createNode(besu, "miner3"); - final BesuNode minerNode4 = nodeFactory.createNode(besu, "miner4"); - cluster.start(minerNode1, minerNode2, minerNode3, minerNode4); - - cluster.verify(blockchain.reachesHeight(minerNode1, 1, 85)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - minerNode1.execute(accountTransactions.createTransfer(sender, 50)); - cluster.verify(sender.balanceEquals(50)); - - minerNode2.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); - cluster.verify(receiver.balanceEquals(1)); - - minerNode3.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 2)); - cluster.verify(receiver.balanceEquals(3)); - - minerNode4.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 3)); - cluster.verify(receiver.balanceEquals(6)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldMineOnMultipleNodesEvenWhenClusterContainsNonValidator( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final String[] validators = {"validator1", "validator2", "validator3"}; - final BesuNode validator1 = - nodeFactory.createNodeWithValidators(besu, "validator1", validators); - final BesuNode validator2 = - nodeFactory.createNodeWithValidators(besu, "validator2", validators); - final BesuNode validator3 = - nodeFactory.createNodeWithValidators(besu, "validator3", validators); - final BesuNode nonValidatorNode = - nodeFactory.createNodeWithValidators(besu, "non-validator", validators); - cluster.start(validator1, validator2, validator3, nonValidatorNode); - - cluster.verify(blockchain.reachesHeight(validator1, 1, 85)); - - final Account sender = accounts.createAccount("account1"); - final Account receiver = accounts.createAccount("account2"); - - validator1.execute(accountTransactions.createTransfer(sender, 50)); - cluster.verify(sender.balanceEquals(50)); - - validator2.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); - cluster.verify(receiver.balanceEquals(1)); - - nonValidatorNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 2)); - cluster.verify(receiver.balanceEquals(3)); - } - - @ParameterizedTest(name = "{index}: {0}") - @MethodSource("factoryFunctions") - public void shouldStillMineWhenANonProposerNodeFailsAndHasSufficientValidators( - final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { - setUp(testName, nodeFactory); - final BesuNode minerNode1 = nodeFactory.createNode(besu, "miner1"); - final BesuNode minerNode2 = nodeFactory.createNode(besu, "miner2"); - final BesuNode minerNode3 = nodeFactory.createNode(besu, "miner3"); - final BesuNode minerNode4 = nodeFactory.createNode(besu, "miner4"); - final List validators = - bft.validators(new BesuNode[] {minerNode1, minerNode2, minerNode3, minerNode4}); - final BesuNode nonProposerNode = validators.get(validators.size() - 1); - cluster.start(validators); - - cluster.verify(blockchain.reachesHeight(minerNode1, 1, 85)); - - final Account receiver = accounts.createAccount("account2"); - - cluster.stopNode(nonProposerNode); - validators.get(0).execute(accountTransactions.createTransfer(receiver, 80)); - - cluster.verifyOnActiveNodes(receiver.balanceEquals(80)); - } - - private static void updateGenesisConfigToLondon( - final BesuNode minerNode, final boolean zeroBaseFeeEnabled) { - final Optional genesisConfig = - minerNode.getGenesisConfigProvider().create(List.of(minerNode)); - final ObjectNode genesisConfigNode = JsonUtil.objectNodeFromString(genesisConfig.orElseThrow()); - final ObjectNode config = (ObjectNode) genesisConfigNode.get("config"); - config.remove("berlinBlock"); - config.put("londonBlock", 0); - config.put("zeroBaseFee", zeroBaseFeeEnabled); - minerNode.setGenesisConfig(genesisConfigNode.toString()); - } - - private static void updateGenesisConfigToShanghai( - final BesuNode minerNode, final boolean zeroBaseFeeEnabled) { - final Optional genesisConfig = - minerNode.getGenesisConfigProvider().create(List.of(minerNode)); - final ObjectNode genesisConfigNode = JsonUtil.objectNodeFromString(genesisConfig.orElseThrow()); - final ObjectNode config = (ObjectNode) genesisConfigNode.get("config"); - config.remove("berlinBlock"); - config.put("shanghaiTime", 100); - config.put("zeroBaseFee", zeroBaseFeeEnabled); - minerNode.setGenesisConfig(genesisConfigNode.toString()); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part1.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part1.java new file mode 100644 index 000000000..4d38accc6 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part1.java @@ -0,0 +1,117 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.tests.acceptance.bft; + +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.AddressHelpers; +import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration; +import org.hyperledger.besu.ethereum.core.ImmutableMiningConfiguration.MutableInitValues; +import org.hyperledger.besu.ethereum.core.MiningConfiguration; +import org.hyperledger.besu.tests.acceptance.dsl.account.Account; +import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Amount; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public class BftMiningAcceptanceTest_Part1 extends ParameterizedBftTestBase { + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnSingleNodeWithPaidGas_Berlin( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); + cluster.start(minerNode); + + cluster.verify(blockchain.reachesHeight(minerNode, 1)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode.execute(accountTransactions.createTransfer(sender, 50)); + cluster.verify(sender.balanceEquals(50)); + + minerNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 2)); + cluster.verify(receiver.balanceEquals(3)); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnSingleNodeWithFreeGas_Berlin( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); + final MiningConfiguration zeroGasMiningParams = + ImmutableMiningConfiguration.builder() + .mutableInitValues( + MutableInitValues.builder() + .isMiningEnabled(true) + .minTransactionGasPrice(Wei.ZERO) + .coinbase(AddressHelpers.ofValue(1)) + .build()) + .build(); + minerNode.setMiningParameters(zeroGasMiningParams); + + cluster.start(minerNode); + + cluster.verify(blockchain.reachesHeight(minerNode, 1)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode.execute(accountTransactions.createTransfer(sender, 50, Amount.ZERO)); + cluster.verify(sender.balanceEquals(50)); + + minerNode.execute( + accountTransactions.createIncrementalTransfers(sender, receiver, 1, Amount.ZERO)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode.execute( + accountTransactions.createIncrementalTransfers(sender, receiver, 2, Amount.ZERO)); + cluster.verify(receiver.balanceEquals(3)); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnSingleNodeWithPaidGas_London( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); + updateGenesisConfigToLondon(minerNode, false); + + cluster.start(minerNode); + + cluster.verify(blockchain.reachesHeight(minerNode, 1)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode.execute(accountTransactions.createTransfer(sender, 50)); + cluster.verify(sender.balanceEquals(50)); + + minerNode.execute(accountTransactions.create1559Transfer(sender, 50, 4)); + cluster.verify(sender.balanceEquals(100)); + + minerNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode.execute(accountTransactions.create1559IncrementalTransfers(sender, receiver, 2, 4)); + cluster.verify(receiver.balanceEquals(3)); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part2.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part2.java new file mode 100644 index 000000000..9c04405f3 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part2.java @@ -0,0 +1,114 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.tests.acceptance.bft; + +import org.hyperledger.besu.tests.acceptance.dsl.account.Account; +import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Amount; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public class BftMiningAcceptanceTest_Part2 extends ParameterizedBftTestBase { + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnSingleNodeWithFreeGas_London( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); + updateGenesisConfigToLondon(minerNode, true); + + cluster.start(minerNode); + + cluster.verify(blockchain.reachesHeight(minerNode, 1)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode.execute(accountTransactions.createTransfer(sender, 50, Amount.ZERO)); + cluster.verify(sender.balanceEquals(50)); + + minerNode.execute(accountTransactions.create1559Transfer(sender, 50, 4, Amount.ZERO)); + cluster.verify(sender.balanceEquals(100)); + + minerNode.execute( + accountTransactions.createIncrementalTransfers(sender, receiver, 1, Amount.ZERO)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode.execute( + accountTransactions.create1559IncrementalTransfers(sender, receiver, 2, 4, Amount.ZERO)); + cluster.verify(receiver.balanceEquals(3)); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnSingleNodeWithFreeGas_Shanghai( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode = nodeFactory.createNode(besu, "miner1"); + updateGenesisConfigToShanghai(minerNode, true); + + cluster.start(minerNode); + + cluster.verify(blockchain.reachesHeight(minerNode, 1)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode.execute(accountTransactions.createTransfer(sender, 50, Amount.ZERO)); + cluster.verify(sender.balanceEquals(50)); + + minerNode.execute(accountTransactions.create1559Transfer(sender, 50, 4, Amount.ZERO)); + cluster.verify(sender.balanceEquals(100)); + + minerNode.execute( + accountTransactions.createIncrementalTransfers(sender, receiver, 1, Amount.ZERO)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode.execute( + accountTransactions.create1559IncrementalTransfers(sender, receiver, 2, 4, Amount.ZERO)); + cluster.verify(receiver.balanceEquals(3)); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnMultipleNodes( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode1 = nodeFactory.createNode(besu, "miner1"); + final BesuNode minerNode2 = nodeFactory.createNode(besu, "miner2"); + final BesuNode minerNode3 = nodeFactory.createNode(besu, "miner3"); + final BesuNode minerNode4 = nodeFactory.createNode(besu, "miner4"); + cluster.start(minerNode1, minerNode2, minerNode3, minerNode4); + + cluster.verify(blockchain.reachesHeight(minerNode1, 1, 85)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode1.execute(accountTransactions.createTransfer(sender, 50)); + cluster.verify(sender.balanceEquals(50)); + + minerNode2.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode3.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 2)); + cluster.verify(receiver.balanceEquals(3)); + + minerNode4.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 3)); + cluster.verify(receiver.balanceEquals(6)); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part3.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part3.java new file mode 100644 index 000000000..bae672de0 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftMiningAcceptanceTest_Part3.java @@ -0,0 +1,81 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.tests.acceptance.bft; + +import org.hyperledger.besu.tests.acceptance.dsl.account.Account; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import java.util.List; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public class BftMiningAcceptanceTest_Part3 extends ParameterizedBftTestBase { + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldMineOnMultipleNodesEvenWhenClusterContainsNonValidator( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final String[] validators = {"validator1", "validator2", "validator3"}; + final BesuNode validator1 = + nodeFactory.createNodeWithValidators(besu, "validator1", validators); + final BesuNode validator2 = + nodeFactory.createNodeWithValidators(besu, "validator2", validators); + final BesuNode validator3 = + nodeFactory.createNodeWithValidators(besu, "validator3", validators); + final BesuNode nonValidatorNode = + nodeFactory.createNodeWithValidators(besu, "non-validator", validators); + cluster.start(validator1, validator2, validator3, nonValidatorNode); + + cluster.verify(blockchain.reachesHeight(validator1, 1, 85)); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + validator1.execute(accountTransactions.createTransfer(sender, 50)); + cluster.verify(sender.balanceEquals(50)); + + validator2.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 1)); + cluster.verify(receiver.balanceEquals(1)); + + nonValidatorNode.execute(accountTransactions.createIncrementalTransfers(sender, receiver, 2)); + cluster.verify(receiver.balanceEquals(3)); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("factoryFunctions") + public void shouldStillMineWhenANonProposerNodeFailsAndHasSufficientValidators( + final String testName, final BftAcceptanceTestParameterization nodeFactory) throws Exception { + setUp(testName, nodeFactory); + final BesuNode minerNode1 = nodeFactory.createNode(besu, "miner1"); + final BesuNode minerNode2 = nodeFactory.createNode(besu, "miner2"); + final BesuNode minerNode3 = nodeFactory.createNode(besu, "miner3"); + final BesuNode minerNode4 = nodeFactory.createNode(besu, "miner4"); + final List validators = + bft.validators(new BesuNode[] {minerNode1, minerNode2, minerNode3, minerNode4}); + final BesuNode nonProposerNode = validators.get(validators.size() - 1); + cluster.start(validators); + + cluster.verify(blockchain.reachesHeight(minerNode1, 1, 85)); + + final Account receiver = accounts.createAccount("account2"); + + cluster.stopNode(nonProposerNode); + validators.get(0).execute(accountTransactions.createTransfer(receiver, 80)); + + cluster.verifyOnActiveNodes(receiver.balanceEquals(80)); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftSyncAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftSyncAcceptanceTest.java new file mode 100644 index 000000000..ff85c2279 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/BftSyncAcceptanceTest.java @@ -0,0 +1,69 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.tests.acceptance.bft; + +import org.hyperledger.besu.ethereum.eth.sync.SyncMode; +import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; + +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class BftSyncAcceptanceTest extends ParameterizedBftTestBase { + + private static final int TARGET_BLOCK_HEIGHT = 70; + + static Stream syncModeTestParameters() { + return Stream.of(SyncMode.FULL, SyncMode.SNAP, SyncMode.CHECKPOINT) + .flatMap( + syncMode -> + factoryFunctions() + .map(args -> Arguments.of(args.get()[0], args.get()[1], syncMode))); + } + + @ParameterizedTest(name = "{index}: {0} with {2} sync") + @MethodSource("syncModeTestParameters") + public void shouldSyncValidatorNode( + final String testName, + final BftAcceptanceTestParameterization nodeFactory, + final SyncMode syncMode) + throws Exception { + setUp(testName, nodeFactory); + + // Create validator network with 4 validators + final BesuNode validator1 = nodeFactory.createBonsaiNodeFixedPort(besu, "validator1"); + final BesuNode validator2 = nodeFactory.createBonsaiNodeFixedPort(besu, "validator2"); + final BesuNode validator3 = nodeFactory.createBonsaiNodeFixedPort(besu, "validator3"); + final BesuNode validator4 = nodeFactory.createBonsaiNodeFixedPort(besu, "validator4"); + + // Configure validators with specified sync mode + final SynchronizerConfiguration syncConfig = + SynchronizerConfiguration.builder().syncMode(syncMode).syncMinimumPeerCount(1).build(); + + validator4.setSynchronizerConfiguration(syncConfig); + + // Start first three validators + cluster.start(validator1, validator2, validator3); + + validator1.verify(blockchain.minimumHeight(TARGET_BLOCK_HEIGHT, TARGET_BLOCK_HEIGHT)); + // Add validator4 to cluster and start + cluster.addNode(validator4); + + validator4.verify(blockchain.minimumHeight(TARGET_BLOCK_HEIGHT, 60)); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java index 76a1a4a6b..29e06c28c 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bft/ParameterizedBftTestBase.java @@ -14,10 +14,15 @@ */ package org.hyperledger.besu.tests.acceptance.bft; +import org.hyperledger.besu.config.JsonUtil; import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; +import java.util.List; +import java.util.Optional; import java.util.stream.Stream; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.provider.Arguments; @@ -30,6 +35,30 @@ public abstract class ParameterizedBftTestBase extends AcceptanceTestBase { return BftAcceptanceTestParameterization.getFactories(); } + protected static void updateGenesisConfigToLondon( + final BesuNode minerNode, final boolean zeroBaseFeeEnabled) { + final Optional genesisConfig = + minerNode.getGenesisConfigProvider().create(List.of(minerNode)); + final ObjectNode genesisConfigNode = JsonUtil.objectNodeFromString(genesisConfig.orElseThrow()); + final ObjectNode config = (ObjectNode) genesisConfigNode.get("config"); + config.remove("berlinBlock"); + config.put("londonBlock", 0); + config.put("zeroBaseFee", zeroBaseFeeEnabled); + minerNode.setGenesisConfig(genesisConfigNode.toString()); + } + + static void updateGenesisConfigToShanghai( + final BesuNode minerNode, final boolean zeroBaseFeeEnabled) { + final Optional genesisConfig = + minerNode.getGenesisConfigProvider().create(List.of(minerNode)); + final ObjectNode genesisConfigNode = JsonUtil.objectNodeFromString(genesisConfig.orElseThrow()); + final ObjectNode config = (ObjectNode) genesisConfigNode.get("config"); + config.remove("berlinBlock"); + config.put("shanghaiTime", 100); + config.put("zeroBaseFee", zeroBaseFeeEnabled); + minerNode.setGenesisConfig(genesisConfigNode.toString()); + } + protected void setUp(final String bftType, final BftAcceptanceTestParameterization input) { this.bftType = bftType; this.nodeFactory = input; diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java index 7d19a5be0..6c050dd97 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bftsoak/BftMiningSoakTest.java @@ -30,6 +30,7 @@ import java.time.temporal.ChronoUnit; import com.fasterxml.jackson.databind.node.ObjectNode; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -41,8 +42,6 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { private static final long ONE_MINUTE = Duration.of(1, ChronoUnit.MINUTES).toMillis(); - private static final long THREE_MINUTES = Duration.of(3, ChronoUnit.MINUTES).toMillis(); - private static final long TEN_SECONDS = Duration.of(10, ChronoUnit.SECONDS).toMillis(); static int getTestDurationMins() { @@ -156,9 +155,9 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { chainHeight = minerNode1.execute(ethTransactions.blockNumber()); lastChainHeight = chainHeight; - // Leave the chain stalled for 3 minutes. Check no new blocks are mined. Then + // Leave the chain stalled for 1 minute. Check no new blocks are mined. Then // resume the other validators. - nextStepEndTime = previousStepEndTime.plus(3, ChronoUnit.MINUTES); + nextStepEndTime = previousStepEndTime.plus(1, ChronoUnit.MINUTES); while (System.currentTimeMillis() < nextStepEndTime.toEpochMilli()) { Thread.sleep(ONE_MINUTE); chainHeight = minerNode1.execute(ethTransactions.blockNumber()); @@ -212,6 +211,8 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { upgradeToLondon( minerNode1, minerNode2, minerNode3, minerNode4, lastChainHeight.intValue() + 120); + cluster.verify(blockchain.reachesHeight(minerNode4, 1, 180)); + previousStepEndTime = Instant.now(); chainHeight = minerNode1.execute(ethTransactions.blockNumber()); @@ -240,7 +241,7 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { upgradeToShanghai( minerNode1, minerNode2, minerNode3, minerNode4, Instant.now().getEpochSecond() + 120); - Thread.sleep(THREE_MINUTES); + cluster.verify(blockchain.reachesHeight(minerNode4, 1, 180)); SimpleStorageShanghai simpleStorageContractShanghai = minerNode1.execute(contractTransactions.createSmartContract(SimpleStorageShanghai.class)); @@ -344,6 +345,7 @@ public class BftMiningSoakTest extends ParameterizedBftTestBase { Thread.sleep(TEN_SECONDS); } + @AfterEach @Override public void tearDownAcceptanceTestBase() { cluster.stop(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterNoDiscoveryAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterNoDiscoveryAcceptanceTest.java index 3a7da4f47..5aba3dc10 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterNoDiscoveryAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterNoDiscoveryAcceptanceTest.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -44,6 +45,7 @@ public class ClusterNoDiscoveryAcceptanceTest extends AcceptanceTestBase { fullNode.verify(net.awaitPeerCount(0)); } + @AfterEach @Override public void tearDownAcceptanceTestBase() { noDiscoveryCluster.stop(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java index e13fbc2f1..832d69af7 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurati import java.util.List; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -79,6 +80,7 @@ public class ClusterThreadNodeRunnerAcceptanceTest extends AcceptanceTestBase { miner.verify(recipient.balanceEquals(2)); } + @AfterEach @Override public void tearDownAcceptanceTestBase() { noDiscoveryCluster.stop(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/P2pDisabledAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/P2pDisabledAcceptanceTest.java index 67a9bf275..4ef57e181 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/P2pDisabledAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/P2pDisabledAcceptanceTest.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,6 +38,7 @@ public class P2pDisabledAcceptanceTest extends AcceptanceTestBase { p2pDisabledCluster.start(node); } + @AfterEach @Override public void tearDownAcceptanceTestBase() { p2pDisabledCluster.stop(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 262eef7be..fc179925a 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -18,61 +18,60 @@ import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; import org.hyperledger.besu.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; +import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory; import java.io.IOException; +import java.util.Arrays; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -@Disabled("flaky see https://github.com/hyperledger/besu/issues/7973") public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { + private static final GenesisConfigurationFactory.CliqueOptions CLIQUE_OPTIONS = + new GenesisConfigurationFactory.CliqueOptions(5, 30000, true); @Test - public void shouldAddValidators() throws IOException { - final String[] initialValidators = {"miner1", "miner2"}; - final BesuNode minerNode1 = besu.createCliqueNodeWithValidators("miner1", initialValidators); - final BesuNode minerNode2 = besu.createCliqueNodeWithValidators("miner2", initialValidators); - final BesuNode minerNode3 = besu.createCliqueNodeWithValidators("miner3", initialValidators); + public void shouldAddAndRemoveValidators() throws IOException { + final String[] initialValidators = {"miner1"}; + final BesuNode minerNode1 = + besu.createCliqueNodeWithValidators("miner1", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode2 = + besu.createCliqueNodeWithValidators("miner2", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode3 = + besu.createCliqueNodeWithValidators("miner3", CLIQUE_OPTIONS, initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); waitForNodesConnectedAndInSync(minerNode1, minerNode2, minerNode3); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode2)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - } - @Test - public void shouldRemoveValidators() throws IOException { - final String[] initialValidators = {"miner1", "miner2", "miner3"}; - final BesuNode minerNode1 = besu.createCliqueNodeWithValidators("miner1", initialValidators); - final BesuNode minerNode2 = besu.createCliqueNodeWithValidators("miner2", initialValidators); - final BesuNode minerNode3 = besu.createCliqueNodeWithValidators("miner3", initialValidators); - cluster.start(minerNode1, minerNode2, minerNode3); - - waitForNodesConnectedAndInSync(minerNode1, minerNode2, minerNode3); - - cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - final Condition cliqueValidatorsChanged = clique.awaitSignerSetChange(minerNode1); - minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode3)); - minerNode2.execute(cliqueTransactions.createRemoveProposal(minerNode3)); + final Condition cliqueValidatorsChanged = clique.awaitSignerSetChange(minerNode2); + minerNode2.execute(cliqueTransactions.createRemoveProposal(minerNode1)); + minerNode3.execute(cliqueTransactions.createRemoveProposal(minerNode1)); + cluster.verify(clique.validatorsEqual(minerNode2, minerNode3)); cluster.verify(cliqueValidatorsChanged); - cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } - @Disabled @Test public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { - final String[] initialValidators = {"miner1", "miner2"}; - final BesuNode minerNode1 = besu.createCliqueNodeWithValidators("miner1", initialValidators); - final BesuNode minerNode2 = besu.createCliqueNodeWithValidators("miner2", initialValidators); - final BesuNode minerNode3 = besu.createCliqueNodeWithValidators("miner3", initialValidators); + final String[] initialValidators = {"miner1"}; + final BesuNode minerNode1 = + besu.createCliqueNodeWithValidators("miner1", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode2 = + besu.createCliqueNodeWithValidators("miner2", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode3 = + besu.createCliqueNodeWithValidators("miner3", CLIQUE_OPTIONS, initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); waitForNodesConnectedAndInSync(minerNode1, minerNode2, minerNode3); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode2)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode1.verify(blockchain.reachesHeight(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); @@ -80,34 +79,57 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { @Test public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { - final BesuNode minerNode1 = besu.createCliqueNode("miner1"); - final BesuNode minerNode2 = besu.createCliqueNode("miner2"); - final BesuNode minerNode3 = besu.createCliqueNode("miner3"); + final String[] initialValidators = {"miner1"}; + final BesuNode minerNode1 = + besu.createCliqueNodeWithValidators("miner1", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode2 = + besu.createCliqueNodeWithValidators("miner2", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode3 = + besu.createCliqueNodeWithValidators("miner3", CLIQUE_OPTIONS, initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); waitForNodesConnectedAndInSync(minerNode1, minerNode2, minerNode3); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode2)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode3)); minerNode1.verify(blockchain.reachesHeight(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } - @Disabled @Test public void shouldIncludeVoteInBlockHeader() throws IOException { - final String[] initialValidators = {"miner1", "miner2"}; - final BesuNode minerNode1 = besu.createCliqueNodeWithValidators("miner1", initialValidators); - final BesuNode minerNode2 = besu.createCliqueNodeWithValidators("miner2", initialValidators); - final BesuNode minerNode3 = besu.createCliqueNodeWithValidators("miner3", initialValidators); + final String[] initialValidators = {"miner1"}; + final BesuNode minerNode1 = + besu.createCliqueNodeWithValidators("miner1", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode2 = + besu.createCliqueNodeWithValidators("miner2", CLIQUE_OPTIONS, initialValidators); + final BesuNode minerNode3 = + besu.createCliqueNodeWithValidators("miner3", CLIQUE_OPTIONS, initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); waitForNodesConnectedAndInSync(minerNode1, minerNode2, minerNode3); - minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode2)); minerNode1.verify(blockchain.reachesHeight(minerNode1, 1)); - minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); + minerNode1.verify(blockchain.beneficiaryEquals(minerNode2)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode1.verify(blockchain.reachesHeight(minerNode1, 1)); + minerNode2.verify(blockchain.reachesHeight(minerNode1, 1)); + minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); + minerNode2.verify(blockchain.beneficiaryEquals(minerNode3)); + minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); + minerNode2.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode2)); minerNode1.verify(blockchain.reachesHeight(minerNode1, 1)); @@ -115,17 +137,15 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); } - private void waitForNodesConnectedAndInSync( - final BesuNode minerNode1, final BesuNode minerNode2, final BesuNode minerNode3) { + private void waitForNodesConnectedAndInSync(final BesuNode... nodes) { // verify nodes are fully connected otherwise blocks could not be propagated - minerNode1.verify(net.awaitPeerCount(2)); - minerNode2.verify(net.awaitPeerCount(2)); - minerNode3.verify(net.awaitPeerCount(2)); + Arrays.stream(nodes).forEach(node -> node.verify(net.awaitPeerCount(nodes.length - 1))); // verify that the miner started producing blocks and all other nodes are syncing from it - waitForBlockHeight(minerNode1, 1); - final var minerChainHead = minerNode1.execute(ethTransactions.block()); - minerNode2.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue())); - minerNode3.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue())); + waitForBlockHeight(nodes[0], 1); + final var firstNodeChainHead = nodes[0].execute(ethTransactions.block()); + Arrays.stream(nodes) + .skip(1) + .forEach(node -> waitForBlockHeight(node, firstNodeChainHead.getNumber().longValue())); } } diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java index cc2d1a36b..7b4bd6f5d 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/crypto/SECP256R1AcceptanceTest.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurati import java.util.List; import org.apache.tuweni.bytes.Bytes32; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -93,6 +94,7 @@ public class SECP256R1AcceptanceTest extends AcceptanceTestBase { noDiscoveryCluster.verify(recipient.balanceEquals(5)); } + @AfterEach @Override public void tearDownAcceptanceTestBase() { super.tearDownAcceptanceTestBase(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcAuthenticationAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcAuthenticationAcceptanceTest.java new file mode 100644 index 000000000..ffdb65784 --- /dev/null +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/AbstractJsonRpcAuthenticationAcceptanceTest.java @@ -0,0 +1,168 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.tests.acceptance.jsonrpc; + +import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; +import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; +import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +public abstract class AbstractJsonRpcAuthenticationAcceptanceTest extends AcceptanceTestBase { + protected Cluster authenticatedCluster; + protected BesuNode nodeUsingAuthFile; + protected BesuNode nodeUsingRsaJwtPublicKey; + protected BesuNode nodeUsingEcdsaJwtPublicKey; + protected BesuNode nodeUsingAuthFileWithNoAuthApi; + protected static final String AUTH_FILE = "authentication/auth.toml"; + + // token with payload{"iat": 1516239022,"exp": 4729363200,"permissions": ["net:peerCount"]} + protected static final String RSA_TOKEN_ALLOWING_NET_PEER_COUNT = + "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6NDcyOTM2MzIwMCwicGVybWl" + + "zc2lvbnMiOlsibmV0OnBlZXJDb3VudCJdfQ.Y6mNV0nvjzOdqAgMgxknFAOUTKoeRAo4aifNgNrWtuXbJJgz6-" + + "H_0GvLgjlToohPiDZbBJXJJlgb4zzLLB-sRtFnGoPaMgz_d_6z958GjFD7x_Fl0HW-WrTjRNenZNfTyD86OEAf" + + "XHy-7N3OYY2a5yeDbppTJy6nnHTq9hY-ad22-oWL1RbK3T_hnUJII_uXCZ9bJggSfu5m-NNUrm3TeqdnQzIaIz" + + "DqHlL0wNZwVPB4cFGN7zKghReBpkRJ8OFlxexQ491Q5eSpuYquhef-yGCIaMfy7GVtpDSD3Y-hjOErr7gUNCUh" + + "1wlc3Rb7ru_0qNgCWTBPJeRK32GppYotwQ"; + + protected static final String ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT = + "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6NDcyOTM2MzIwMCwicGVybWlz" + + "c2lvbnMiOlsibmV0OnBlZXJDb3VudCJdfQ.pWXniN6XQ7G8b1nawy8sviPCMxrfbcI6c7UFzeXm26CMGMUEZxiC" + + "JjRntB8ueuZcsxnGlEhCHt-KngpFEmx5TA"; + + protected static final List NO_AUTH_API_METHODS = Arrays.asList("net_services"); + + @Test + public void shouldFailLoginWithWrongCredentials() { + nodeUsingAuthFile.verify(login.failure("user", "badpassword")); + nodeUsingAuthFileWithNoAuthApi.verify(login.failure("user", "badpassword")); + } + + @Test + public void shouldSucceedLoginWithCorrectCredentials() { + nodeUsingAuthFile.verify(login.success("user", "pegasys")); + nodeUsingAuthFileWithNoAuthApi.verify(login.success("user", "pegasys")); + } + + @Test + public void jsonRpcMethodShouldSucceedWithAuthenticatedUserAndPermission() { + String token = + nodeUsingAuthFile.execute( + permissioningTransactions.createSuccessfulLogin("user", "pegasys")); + nodeUsingAuthFile.useAuthenticationTokenInHeaderForJsonRpc(token); + nodeUsingAuthFile.verify(net.awaitPeerCount(3)); + + token = + nodeUsingAuthFileWithNoAuthApi.execute( + permissioningTransactions.createSuccessfulLogin("user", "pegasys")); + nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); + nodeUsingAuthFileWithNoAuthApi.verify(net.awaitPeerCount(3)); + } + + @Test + public void jsonRpcMethodShouldFailOnNonPermittedMethod() { + String token = + nodeUsingAuthFile.execute( + permissioningTransactions.createSuccessfulLogin("user", "pegasys")); + nodeUsingAuthFile.useAuthenticationTokenInHeaderForJsonRpc(token); + nodeUsingAuthFile.verify(net.netVersionUnauthorized()); + nodeUsingAuthFile.verify(net.netServicesUnauthorized()); + + token = + nodeUsingAuthFileWithNoAuthApi.execute( + permissioningTransactions.createSuccessfulLogin("user", "pegasys")); + nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); + nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); + } + + @Test + public void jsonRpcMethodsNotIncludedInNoAuthListShouldFailWithoutToken() { + nodeUsingAuthFile.verify(net.netVersionUnauthorized()); + nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); + } + + @Test + public void noAuthJsonRpcMethodShouldSucceedWithoutToken() { + nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); + } + + @Test + public void noAuthJsonRpcConfiguredNodeShouldWorkAsIntended() { + // No token -> all methods other than specified no auth methods should fail + nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); + nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); + + // Should behave the same with valid token + String token = + nodeUsingAuthFileWithNoAuthApi.execute( + permissioningTransactions.createSuccessfulLogin("user", "pegasys")); + nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); + nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); + nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); + nodeUsingAuthFileWithNoAuthApi.verify(net.awaitPeerCount(3)); + } + + @Test + public void externalRsaJwtPublicKeyUsedOnJsonRpcMethodShouldSucceed() { + nodeUsingRsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( + RSA_TOKEN_ALLOWING_NET_PEER_COUNT); + nodeUsingRsaJwtPublicKey.verify(net.awaitPeerCount(3)); + } + + @Test + public void externalRsaJwtPublicKeyUsedOnJsonRpcMethodShouldFailOnNonPermittedMethod() { + nodeUsingRsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( + RSA_TOKEN_ALLOWING_NET_PEER_COUNT); + nodeUsingRsaJwtPublicKey.verify(net.netVersionUnauthorized()); + nodeUsingRsaJwtPublicKey.verify(net.netServicesUnauthorized()); + } + + @Test + public void externalEcdsaJwtPublicKeyUsedOnJsonRpcMethodShouldSucceed() { + nodeUsingEcdsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( + ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT); + nodeUsingEcdsaJwtPublicKey.verify(net.awaitPeerCount(3)); + } + + @Test + public void externalEcdsaJwtPublicKeyUsedOnJsonRpcMethodShouldFailOnNonPermittedMethod() { + nodeUsingEcdsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( + ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT); + nodeUsingEcdsaJwtPublicKey.verify(net.netVersionUnauthorized()); + nodeUsingEcdsaJwtPublicKey.verify(net.netServicesUnauthorized()); + } + + @Test + public void jsonRpcMethodShouldFailWhenThereIsNoToken() { + nodeUsingRsaJwtPublicKey.verify(net.netVersionUnauthorized()); + nodeUsingRsaJwtPublicKey.verify(net.netServicesUnauthorized()); + } + + @Test + public void loginShouldBeDisabledWhenUsingExternalJwtPublicKey() { + nodeUsingRsaJwtPublicKey.verify(login.disabled()); + } + + @AfterEach + @Override + public void tearDownAcceptanceTestBase() { + authenticatedCluster.stop(); + super.tearDownAcceptanceTestBase(); + } +} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcHttpAuthenticationAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcHttpAuthenticationAcceptanceTest.java index 3ef383a52..dc88fdd82 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcHttpAuthenticationAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcHttpAuthenticationAcceptanceTest.java @@ -14,43 +14,17 @@ */ package org.hyperledger.besu.tests.acceptance.jsonrpc; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.List; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -public class JsonRpcHttpAuthenticationAcceptanceTest extends AcceptanceTestBase { - private Cluster authenticatedCluster; - private BesuNode nodeUsingAuthFile; - private BesuNode nodeUsingRsaJwtPublicKey; - private BesuNode nodeUsingEcdsaJwtPublicKey; - private BesuNode nodeUsingAuthFileWithNoAuthApi; - private static final String AUTH_FILE = "authentication/auth.toml"; - - // token with payload{"iat": 1516239022,"exp": 4729363200,"permissions": ["net:peerCount"]} - private static final String RSA_TOKEN_ALLOWING_NET_PEER_COUNT = - "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6NDcyOTM2MzIwMCwicGVybWl" - + "zc2lvbnMiOlsibmV0OnBlZXJDb3VudCJdfQ.Y6mNV0nvjzOdqAgMgxknFAOUTKoeRAo4aifNgNrWtuXbJJgz6-" - + "H_0GvLgjlToohPiDZbBJXJJlgb4zzLLB-sRtFnGoPaMgz_d_6z958GjFD7x_Fl0HW-WrTjRNenZNfTyD86OEAf" - + "XHy-7N3OYY2a5yeDbppTJy6nnHTq9hY-ad22-oWL1RbK3T_hnUJII_uXCZ9bJggSfu5m-NNUrm3TeqdnQzIaIz" - + "DqHlL0wNZwVPB4cFGN7zKghReBpkRJ8OFlxexQ491Q5eSpuYquhef-yGCIaMfy7GVtpDSD3Y-hjOErr7gUNCUh" - + "1wlc3Rb7ru_0qNgCWTBPJeRK32GppYotwQ"; - - private static final String ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT = - "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6NDcyOTM2MzIwMCwicGVybWlz" - + "c2lvbnMiOlsibmV0OnBlZXJDb3VudCJdfQ.pWXniN6XQ7G8b1nawy8sviPCMxrfbcI6c7UFzeXm26CMGMUEZxiC" - + "JjRntB8ueuZcsxnGlEhCHt-KngpFEmx5TA"; - - private static final List NO_AUTH_API_METHODS = Arrays.asList("net_services"); +public class JsonRpcHttpAuthenticationAcceptanceTest + extends AbstractJsonRpcAuthenticationAcceptanceTest { @BeforeEach public void setUp() throws IOException, URISyntaxException { @@ -75,121 +49,4 @@ public class JsonRpcHttpAuthenticationAcceptanceTest extends AcceptanceTestBase nodeUsingEcdsaJwtPublicKey.verify(login.awaitResponse("user", "badpassword")); nodeUsingAuthFileWithNoAuthApi.verify(login.awaitResponse("user", "badpassword")); } - - @Test - public void shouldFailLoginWithWrongCredentials() { - nodeUsingAuthFile.verify(login.failure("user", "badpassword")); - nodeUsingAuthFileWithNoAuthApi.verify(login.failure("user", "badpassword")); - } - - @Test - public void shouldSucceedLoginWithCorrectCredentials() { - nodeUsingAuthFile.verify(login.success("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.verify(login.success("user", "pegasys")); - } - - @Test - public void jsonRpcMethodShouldSucceedWithAuthenticatedUserAndPermission() { - String token = - nodeUsingAuthFile.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFile.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFile.verify(net.awaitPeerCount(3)); - - token = - nodeUsingAuthFileWithNoAuthApi.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFileWithNoAuthApi.verify(net.awaitPeerCount(3)); - } - - @Test - public void jsonRpcMethodShouldFailOnNonPermittedMethod() { - String token = - nodeUsingAuthFile.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFile.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFile.verify(net.netVersionUnauthorized()); - nodeUsingAuthFile.verify(net.netServicesUnauthorized()); - - token = - nodeUsingAuthFileWithNoAuthApi.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - } - - @Test - public void jsonRpcMethodsNotIncludedInNoAuthListShouldFailWithoutToken() { - nodeUsingAuthFile.verify(net.netVersionUnauthorized()); - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - } - - @Test - public void noAuthJsonRpcMethodShouldSucceedWithoutToken() { - nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); - } - - @Test - public void noAuthJsonRpcConfiguredNodeShouldWorkAsIntended() { - // No token -> all methods other than specified no auth methods should fail - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); - - // Should behave the same with valid token - String token = - nodeUsingAuthFileWithNoAuthApi.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); - nodeUsingAuthFileWithNoAuthApi.verify(net.awaitPeerCount(3)); - } - - @Test - public void externalRsaJwtPublicKeyUsedOnJsonRpcMethodShouldSucceed() { - nodeUsingRsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - RSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingRsaJwtPublicKey.verify(net.awaitPeerCount(3)); - } - - @Test - public void externalRsaJwtPublicKeyUsedOnJsonRpcMethodShouldFailOnNonPermittedMethod() { - nodeUsingRsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - RSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingRsaJwtPublicKey.verify(net.netVersionUnauthorized()); - nodeUsingRsaJwtPublicKey.verify(net.netServicesUnauthorized()); - } - - @Test - public void externalEcdsaJwtPublicKeyUsedOnJsonRpcMethodShouldSucceed() { - nodeUsingEcdsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingEcdsaJwtPublicKey.verify(net.awaitPeerCount(3)); - } - - @Test - public void externalEcdsaJwtPublicKeyUsedOnJsonRpcMethodShouldFailOnNonPermittedMethod() { - nodeUsingEcdsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingEcdsaJwtPublicKey.verify(net.netVersionUnauthorized()); - nodeUsingEcdsaJwtPublicKey.verify(net.netServicesUnauthorized()); - } - - @Test - public void jsonRpcMethodShouldFailWhenThereIsNoToken() { - nodeUsingRsaJwtPublicKey.verify(net.netVersionUnauthorized()); - nodeUsingRsaJwtPublicKey.verify(net.netServicesUnauthorized()); - } - - @Test - public void loginShouldBeDisabledWhenUsingExternalJwtPublicKey() { - nodeUsingRsaJwtPublicKey.verify(login.disabled()); - } - - @Override - public void tearDownAcceptanceTestBase() { - authenticatedCluster.stop(); - super.tearDownAcceptanceTestBase(); - } } diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcWebsocketAuthenticationAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcWebsocketAuthenticationAcceptanceTest.java index 47d236e5b..72d9dedc3 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcWebsocketAuthenticationAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/jsonrpc/JsonRpcWebsocketAuthenticationAcceptanceTest.java @@ -14,43 +14,17 @@ */ package org.hyperledger.besu.tests.acceptance.jsonrpc; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.List; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -public class JsonRpcWebsocketAuthenticationAcceptanceTest extends AcceptanceTestBase { - private BesuNode nodeUsingAuthFile; - private BesuNode nodeUsingRsaJwtPublicKey; - private BesuNode nodeUsingEcdsaJwtPublicKey; - private BesuNode nodeUsingAuthFileWithNoAuthApi; - private Cluster authenticatedCluster; - private static final String AUTH_FILE = "authentication/auth.toml"; - - private static final List NO_AUTH_API_METHODS = Arrays.asList("net_services"); - - // token with payload{"iat": 1516239022,"exp": 4729363200,"permissions": ["net:peerCount"]} - private static final String RSA_TOKEN_ALLOWING_NET_PEER_COUNT = - "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6NDcyOTM2MzIwMCwicGVybWl" - + "zc2lvbnMiOlsibmV0OnBlZXJDb3VudCJdfQ.Y6mNV0nvjzOdqAgMgxknFAOUTKoeRAo4aifNgNrWtuXbJJgz6-" - + "H_0GvLgjlToohPiDZbBJXJJlgb4zzLLB-sRtFnGoPaMgz_d_6z958GjFD7x_Fl0HW-WrTjRNenZNfTyD86OEAf" - + "XHy-7N3OYY2a5yeDbppTJy6nnHTq9hY-ad22-oWL1RbK3T_hnUJII_uXCZ9bJggSfu5m-NNUrm3TeqdnQzIaIz" - + "DqHlL0wNZwVPB4cFGN7zKghReBpkRJ8OFlxexQ491Q5eSpuYquhef-yGCIaMfy7GVtpDSD3Y-hjOErr7gUNCUh" - + "1wlc3Rb7ru_0qNgCWTBPJeRK32GppYotwQ"; - - private static final String ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT = - "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6NDcyOTM2MzIwMCwicGVybWlz" - + "c2lvbnMiOlsibmV0OnBlZXJDb3VudCJdfQ.pWXniN6XQ7G8b1nawy8sviPCMxrfbcI6c7UFzeXm26CMGMUEZxiC" - + "JjRntB8ueuZcsxnGlEhCHt-KngpFEmx5TA"; +public class JsonRpcWebsocketAuthenticationAcceptanceTest + extends AbstractJsonRpcAuthenticationAcceptanceTest { @BeforeEach public void setUp() throws IOException, URISyntaxException { @@ -78,121 +52,4 @@ public class JsonRpcWebsocketAuthenticationAcceptanceTest extends AcceptanceTest nodeUsingEcdsaJwtPublicKey.verify(login.awaitResponse("user", "badpassword")); nodeUsingAuthFileWithNoAuthApi.verify(login.awaitResponse("user", "badpassword")); } - - @Test - public void shouldFailLoginWithWrongCredentials() { - nodeUsingAuthFile.verify(login.failure("user", "badpassword")); - nodeUsingAuthFileWithNoAuthApi.verify(login.failure("user", "badpassword")); - } - - @Test - public void shouldSucceedLoginWithCorrectCredentials() { - nodeUsingAuthFile.verify(login.success("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.verify(login.success("user", "pegasys")); - } - - @Test - public void jsonRpcMethodShouldSucceedWithAuthenticatedUserAndPermission() { - String token = - nodeUsingAuthFile.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFile.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFile.verify(net.awaitPeerCount(3)); - - token = - nodeUsingAuthFileWithNoAuthApi.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFileWithNoAuthApi.verify(net.awaitPeerCount(3)); - } - - @Test - public void jsonRpcMethodShouldFailOnNonPermittedMethod() { - String token = - nodeUsingAuthFile.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFile.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFile.verify(net.netVersionUnauthorized()); - nodeUsingAuthFile.verify(net.netServicesUnauthorized()); - - token = - nodeUsingAuthFileWithNoAuthApi.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - } - - @Test - public void jsonRpcMethodsNotIncludedInNoAuthListShouldFailWithoutToken() { - nodeUsingAuthFile.verify(net.netVersionUnauthorized()); - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - } - - @Test - public void noAuthJsonRpcMethodShouldSucceedWithoutToken() { - nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); - } - - @Test - public void noAuthJsonRpcConfiguredNodeShouldWorkAsIntended() { - // No token -> all methods other than specified no auth methods should fail - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); - - // Should behave the same with valid token - String token = - nodeUsingAuthFileWithNoAuthApi.execute( - permissioningTransactions.createSuccessfulLogin("user", "pegasys")); - nodeUsingAuthFileWithNoAuthApi.useAuthenticationTokenInHeaderForJsonRpc(token); - nodeUsingAuthFileWithNoAuthApi.verify(net.netVersionUnauthorized()); - nodeUsingAuthFileWithNoAuthApi.verify(net.netServicesAllActive()); - nodeUsingAuthFileWithNoAuthApi.verify(net.awaitPeerCount(3)); - } - - @Test - public void externalRsaJwtPublicKeyUsedOnJsonRpcMethodShouldSucceed() { - nodeUsingRsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - RSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingRsaJwtPublicKey.verify(net.awaitPeerCount(3)); - } - - @Test - public void externalRsaJwtPublicKeyUsedOnJsonRpcMethodShouldFailOnNonPermittedMethod() { - nodeUsingRsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - RSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingRsaJwtPublicKey.verify(net.netVersionUnauthorized()); - nodeUsingAuthFile.verify(net.netServicesUnauthorized()); - } - - @Test - public void externalEcdsaJwtPublicKeyUsedOnJsonRpcMethodShouldSucceed() { - nodeUsingEcdsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingEcdsaJwtPublicKey.verify(net.awaitPeerCount(3)); - } - - @Test - public void externalEcdsaJwtPublicKeyUsedOnJsonRpcMethodShouldFailOnNonPermittedMethod() { - nodeUsingEcdsaJwtPublicKey.useAuthenticationTokenInHeaderForJsonRpc( - ECDSA_TOKEN_ALLOWING_NET_PEER_COUNT); - nodeUsingEcdsaJwtPublicKey.verify(net.netVersionUnauthorized()); - nodeUsingEcdsaJwtPublicKey.verify(net.netServicesUnauthorized()); - } - - @Test - public void jsonRpcMethodShouldFailWhenThereIsNoToken() { - nodeUsingRsaJwtPublicKey.verify(net.netVersionUnauthorized()); - nodeUsingRsaJwtPublicKey.verify(net.netServicesUnauthorized()); - } - - @Test - public void loginShouldBeDisabledWhenUsingExternalJwtPublicKey() { - nodeUsingRsaJwtPublicKey.verify(login.disabled()); - } - - @Override - public void tearDownAcceptanceTestBase() { - authenticatedCluster.stop(); - super.tearDownAcceptanceTestBase(); - } } diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java deleted file mode 100644 index 1bd6d4cf9..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountLocalAndOnchainPermissioningAcceptanceTest.java +++ /dev/null @@ -1,123 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.TransferTransaction; - -import java.math.BigInteger; -import java.util.Arrays; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled("permissioning tests flaky with timeouts") -public class AccountLocalAndOnchainPermissioningAcceptanceTest - extends AccountSmartContractPermissioningAcceptanceTestBase { - - private Account senderC; - - @BeforeEach - public void setUp() { - senderC = accounts.createAccount("Account-C"); - } - - @Test - public void testAccountCannotSendTxWhenNotOnLocalAllowList() { - // Onchain allowlist: Primary, Secondary, C - // Local allowlist: Primary, Secondary - - final Node node = - permissionedNode( - "node1", - Arrays.asList( - accounts.getPrimaryBenefactor().getAddress(), - accounts.getSecondaryBenefactor().getAddress())); - permissionedCluster.start(node); - - // ensure SenderC has got some ether available - node.execute(accountTransactions.createTransfer(senderC, 10)); - node.verify(senderC.balanceEquals(10)); - - // add accounts to onchain allowlist - node.execute(allowAccount(accounts.getPrimaryBenefactor())); - node.verify(accountIsAllowed(accounts.getPrimaryBenefactor())); - - node.execute(allowAccount(accounts.getSecondaryBenefactor())); - node.verify(accountIsAllowed(accounts.getSecondaryBenefactor())); - - node.execute(allowAccount(senderC)); - node.verify(accountIsAllowed(senderC)); - - // sender C should not be able to send Tx - verifyTransferForbidden(node, senderC, accounts.getSecondaryBenefactor()); - } - - @Test - public void testAccountCannotSendTxWhenNotOnOnchainAllowList() { - // Onchain allowlist: Primary, Secondary, Receiver - // Local allowlist: Primary, Secondary, C, Receiver - - final Account receiverAccount = accounts.createAccount("Rec-A"); - - final Node node = - permissionedNode( - "node1", - Arrays.asList( - accounts.getPrimaryBenefactor().getAddress(), - accounts.getSecondaryBenefactor().getAddress(), - senderC.getAddress(), - receiverAccount.getAddress())); - permissionedCluster.start(node); - - // ensure SenderC has got some ether available - node.execute(accountTransactions.createTransfer(senderC, 10)); - node.verify(senderC.balanceEquals(10)); - - // add accounts to onchain allowlist - node.execute(allowAccount(accounts.getPrimaryBenefactor())); - node.verify(accountIsAllowed(accounts.getPrimaryBenefactor())); - - node.execute(allowAccount(accounts.getSecondaryBenefactor())); - node.verify(accountIsAllowed(accounts.getSecondaryBenefactor())); - - node.execute(allowAccount(receiverAccount)); - node.verify(accountIsAllowed(receiverAccount)); - - // verify senderC is forbidden because it is not on Onchain allowlist - node.verify(accountIsForbidden(senderC)); - - // sender C should not be able to send Tx - verifyTransferForbidden(node, senderC, accounts.getSecondaryBenefactor()); - - // final check, other account should be able to send tx - node.execute( - accountTransactions.createTransfer(accounts.getPrimaryBenefactor(), receiverAccount, 5)); - node.verify(receiverAccount.balanceEquals(5)); - } - - private void verifyTransferForbidden( - final Node node, final Account sender, final Account beneficiary) { - final BigInteger nonce = node.execute(ethTransactions.getTransactionCount(sender.getAddress())); - final TransferTransaction transfer = - accountTransactions.createTransfer(sender, beneficiary, 1, nonce); - node.verify( - eth.expectEthSendRawTransactionException( - transfer.signedTransactionData(), - "Sender account not authorized to send transactions")); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountSmartContractPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountSmartContractPermissioningAcceptanceTest.java deleted file mode 100644 index 9009721d9..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountSmartContractPermissioningAcceptanceTest.java +++ /dev/null @@ -1,77 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.TransferTransaction; - -import java.math.BigInteger; -import java.util.Collections; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class AccountSmartContractPermissioningAcceptanceTest - extends AccountSmartContractPermissioningAcceptanceTestBase { - - private Node node; - private Account allowedSender; - private Account otherAccount; - - @BeforeEach - public void setUp() { - node = permissionedNode("node1", Collections.emptyList()); - permissionedCluster.start(node); - - allowedSender = accounts.createAccount("authorized-account"); - otherAccount = accounts.createAccount("other-account"); - - // ensure primary benefactor is permitted (account used to permit/forbid other accounts) - node.execute(allowAccount(accounts.getPrimaryBenefactor())); - node.verify(accountIsAllowed(accounts.getPrimaryBenefactor())); - - // ensure allowedSender has got some ether available - node.execute(accountTransactions.createTransfer(allowedSender, 10)); - node.verify(allowedSender.balanceEquals(10)); - } - - @Test - public void allowedAccountCanTransferValue() { - node.execute(allowAccount(allowedSender)); - node.verify(accountIsAllowed(allowedSender)); - - node.execute(accountTransactions.createTransfer(allowedSender, otherAccount, 5)); - node.verify(otherAccount.balanceEquals(5)); - } - - @Test - public void forbiddenAccountCannotTransferValue() { - node.execute(forbidAccount(allowedSender)); - node.verify(accountIsForbidden(allowedSender)); - - verifyTransferForbidden(allowedSender, otherAccount); - } - - private void verifyTransferForbidden(final Account sender, final Account beneficiary) { - final BigInteger nonce = node.execute(ethTransactions.getTransactionCount(sender.getAddress())); - final TransferTransaction transfer = - accountTransactions.createTransfer(sender, beneficiary, 1, nonce); - node.verify( - eth.expectEthSendRawTransactionException( - transfer.signedTransactionData(), - "Sender account not authorized to send transactions")); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountSmartContractPermissioningAcceptanceTestBase.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountSmartContractPermissioningAcceptanceTestBase.java deleted file mode 100644 index 7cad210dd..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/AccountSmartContractPermissioningAcceptanceTestBase.java +++ /dev/null @@ -1,102 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.account.Account; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.AccountSmartContractPermissioningConditions; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.AccountSmartContractPermissioningTransactions; - -import java.io.IOException; -import java.util.List; - -class AccountSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBase { - - private final AccountSmartContractPermissioningTransactions smartContractAccountPermissioning; - private final AccountSmartContractPermissioningConditions - accountSmartContractPermissioningConditions; - - private static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000008888"; - private static final String GENESIS_FILE = "/permissioning/simple_permissioning_genesis.json"; - - protected final Cluster permissionedCluster; - - protected AccountSmartContractPermissioningAcceptanceTestBase() { - super(); - smartContractAccountPermissioning = new AccountSmartContractPermissioningTransactions(accounts); - accountSmartContractPermissioningConditions = - new AccountSmartContractPermissioningConditions(smartContractAccountPermissioning); - this.permissionedCluster = permissionedCluster(); - } - - private Cluster permissionedCluster() { - final ClusterConfiguration clusterConfiguration = - new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); - return new Cluster(clusterConfiguration, net); - } - - protected Node permissionedNode(final String name, final List accountsPermittedInConfig) { - PermissionedNodeBuilder permissionedNodeBuilder = - this.permissionedNodeBuilder - .name(name) - .genesisFile(GENESIS_FILE) - .accountsContractEnabled(CONTRACT_ADDRESS); - - if (accountsPermittedInConfig != null && !accountsPermittedInConfig.isEmpty()) { - permissionedNodeBuilder.accountsPermittedInConfig(accountsPermittedInConfig); - } - - return permissionedNodeBuilder.build(); - } - - protected Node node(final String name) { - try { - return besu.createCustomGenesisNode(name, GENESIS_FILE, false); - } catch (IOException e) { - throw new RuntimeException("Error creating node", e); - } - } - - @Override - public void tearDownAcceptanceTestBase() { - permissionedCluster.stop(); - super.tearDownAcceptanceTestBase(); - } - - protected Transaction allowAccount(final Account account) { - return smartContractAccountPermissioning.allowAccount(CONTRACT_ADDRESS, account); - } - - protected Transaction forbidAccount(final Account account) { - return smartContractAccountPermissioning.forbidAccount(CONTRACT_ADDRESS, account); - } - - protected Condition accountIsAllowed(final Account account) { - return accountSmartContractPermissioningConditions.accountIsAllowed(CONTRACT_ADDRESS, account); - } - - protected Condition accountIsForbidden(final Account account) { - return accountSmartContractPermissioningConditions.accountIsForbidden( - CONTRACT_ADDRESS, account); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java deleted file mode 100644 index 9271c0d97..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalAndOnchainPermissioningAcceptanceTest.java +++ /dev/null @@ -1,117 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled("permissioning tests flaky with timeouts") -public class NodeLocalAndOnchainPermissioningAcceptanceTest - extends NodeSmartContractPermissioningAcceptanceTestBase { - - private Node bootnode; - private Node permissionedNode; - private Node allowedNode; - private Node forbiddenNode; - - @BeforeEach - public void setUp() { - bootnode = bootnode("bootnode"); - forbiddenNode = node("forbidden-node"); - allowedNode = node("allowed-node"); - - permissionedCluster.start(bootnode, allowedNode, forbiddenNode); - } - - @Test - public void testNodeCannotConnectWhenAllowedOnchainButNotLocally() { - - // add permissioned node after cluster start because we need enode URI for local config - permissionedNode = permissionedNode("permissioned-node", bootnode, allowedNode); - permissionedCluster.addNode(permissionedNode); - - // update Onchain smart contract with allowed nodes - permissionedNode.execute(allowNode(bootnode)); - permissionedNode.verify(nodeIsAllowed(bootnode)); - - permissionedNode.execute(allowNode(allowedNode)); - permissionedNode.verify(nodeIsAllowed(allowedNode)); - - permissionedNode.execute(allowNode(permissionedNode)); - permissionedNode.verify(nodeIsAllowed(permissionedNode)); - - permissionedNode.execute(allowNode(forbiddenNode)); - permissionedNode.verify(nodeIsAllowed(forbiddenNode)); - - permissionedNodeShouldDiscoverOnlyAllowedNodes(); - } - - @Test - public void testNodeCannotConnectWhenAllowedLocallyButNotOnchain() { - // onchain allowlist: A, B - // local allowlist: A, B, C - - // add permissioned node after cluster start because we need enode URI for local config - permissionedNode = permissionedNode("permissioned-node", bootnode, allowedNode, forbiddenNode); - permissionedCluster.addNode(permissionedNode); - - // update Onchain smart contract with allowed nodes - permissionedNode.execute(allowNode(bootnode)); - permissionedNode.verify(nodeIsAllowed(bootnode)); - - permissionedNode.execute(allowNode(allowedNode)); - permissionedNode.verify(nodeIsAllowed(allowedNode)); - - permissionedNode.execute(allowNode(permissionedNode)); - permissionedNode.verify(nodeIsAllowed(permissionedNode)); - - permissionedNodeShouldDiscoverOnlyAllowedNodes(); - } - - @Test - public void testNodesCanConnectWhenAllowedBothOnchainAndLocally() { - // add permissioned node after cluster start because we need enode URI for local config - permissionedNode = permissionedNode("permissioned-node", bootnode, allowedNode, forbiddenNode); - permissionedCluster.addNode(permissionedNode); - - // update Onchain smart contract with allowed nodes - permissionedNode.execute(allowNode(bootnode)); - permissionedNode.verify(nodeIsAllowed(bootnode)); - - permissionedNode.execute(allowNode(allowedNode)); - permissionedNode.verify(nodeIsAllowed(allowedNode)); - - permissionedNode.execute(allowNode(permissionedNode)); - permissionedNode.verify(nodeIsAllowed(permissionedNode)); - - permissionedNode.execute(allowNode(forbiddenNode)); - permissionedNode.verify(nodeIsAllowed(forbiddenNode)); - - bootnode.verify(net.awaitPeerCount(3)); - allowedNode.verify(net.awaitPeerCount(3)); - forbiddenNode.verify(net.awaitPeerCount(3)); - permissionedNode.verify(net.awaitPeerCount(3)); - } - - private void permissionedNodeShouldDiscoverOnlyAllowedNodes() { - bootnode.verify(net.awaitPeerCount(3)); - allowedNode.verify(net.awaitPeerCount(3)); - forbiddenNode.verify(net.awaitPeerCount(2)); - permissionedNode.verify(net.awaitPeerCount(2)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalConfigPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalConfigPermissioningAcceptanceTest.java index d889abb9f..bbc2c9f19 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalConfigPermissioningAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeLocalConfigPermissioningAcceptanceTest.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -80,6 +81,7 @@ public class NodeLocalConfigPermissioningAcceptanceTest extends AcceptanceTestBa permissionedNode.verify(net.awaitPeerCount(3)); } + @AfterEach @Override public void tearDownAcceptanceTestBase() { permissionedCluster.stop(); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java deleted file mode 100644 index f1ed4e149..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTest.java +++ /dev/null @@ -1,98 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -public class NodeSmartContractPermissioningAcceptanceTest - extends NodeSmartContractPermissioningAcceptanceTestBase { - - private Node bootnode; - private Node permissionedNode; - private Node allowedNode; - private Node forbiddenNode; - - @BeforeEach - public void setUp() { - bootnode = bootnode("bootnode"); - forbiddenNode = node("forbidden-node"); - allowedNode = node("allowed-node"); - permissionedNode = permissionedNode("permissioned-node"); - - permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode); - - // updating permissioning smart contract with allowed nodes - permissionedNode.verify(nodeIsForbidden(bootnode)); - permissionedNode.execute(allowNode(bootnode)); - permissionedNode.verify(nodeIsAllowed(bootnode)); - permissionedNode.verify(admin.hasPeer(bootnode)); - - permissionedNode.execute(allowNode(allowedNode)); - permissionedNode.verify(nodeIsAllowed(allowedNode)); - - permissionedNode.execute(allowNode(permissionedNode)); - permissionedNode.verify(nodeIsAllowed(permissionedNode)); - - permissionedNode.verify(admin.addPeer(allowedNode)); - - allowedNode.verify(eth.syncingStatus(false)); - bootnode.verify(eth.syncingStatus(false)); - permissionedNode.verify(eth.syncingStatus(false)); - forbiddenNode.verify(eth.syncingStatus(false)); - } - - @Test - @Disabled("test is flaky") - public void permissionedNodeShouldPeerOnlyWithAllowedNodes() { - bootnode.verify(net.awaitPeerCount(3)); - allowedNode.verify(net.awaitPeerCount(3)); - forbiddenNode.verify(net.awaitPeerCount(2)); - permissionedNode.verify(net.awaitPeerCount(2)); - } - - @Test - public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() { - permissionedNode.execute(forbidNode(allowedNode)); - permissionedNode.verify(connectionIsForbidden(permissionedNode, allowedNode)); - - permissionedNode.verify(net.awaitPeerCount(1)); - } - - @Test - public void permissioningUpdatesPropagateThroughNetwork() { - // connection to newly permitted node is allowed - allowedNode.execute(allowNode(forbiddenNode)); - allowedNode.verify(connectionIsAllowed(permissionedNode, forbiddenNode)); - // permissioning changes in peer should propagate to permissioned node - permissionedNode.verify(connectionIsAllowed(permissionedNode, forbiddenNode)); - - permissionedNode.verify(admin.addPeer(forbiddenNode)); - permissionedNode.verify(net.awaitPeerCount(3)); - } - - @Test - public void onchainPermissioningAllowlistShouldPersistAcrossRestarts() { - permissionedCluster.stop(); - permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode); - - permissionedNode.verify(nodeIsAllowed(allowedNode)); - permissionedNode.verify(nodeIsAllowed(bootnode)); - permissionedNode.verify(nodeIsAllowed(permissionedNode)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.java deleted file mode 100644 index 094dc0886..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.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.tests.acceptance.permissioning; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.NodeSmartContractPermissioningConditions; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningTransactions; - -import java.io.IOException; - -class NodeSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBase { - - private final NodeSmartContractPermissioningTransactions smartContractNodePermissioning; - private final NodeSmartContractPermissioningConditions nodeSmartContractPermissioningConditions; - - protected static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009999"; - protected static final String GENESIS_FILE = "/permissioning/simple_permissioning_genesis.json"; - - protected final Cluster permissionedCluster; - - protected NodeSmartContractPermissioningAcceptanceTestBase() { - super(); - smartContractNodePermissioning = new NodeSmartContractPermissioningTransactions(accounts); - nodeSmartContractPermissioningConditions = - new NodeSmartContractPermissioningConditions(smartContractNodePermissioning); - this.permissionedCluster = permissionedCluster(); - } - - private Cluster permissionedCluster() { - final ClusterConfiguration clusterConfiguration = - new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); - return new Cluster(clusterConfiguration, net); - } - - protected Node permissionedNode(final String name, final Node... localConfigAllowedNodes) { - return permissionedNode(name, GENESIS_FILE, localConfigAllowedNodes); - } - - protected Node permissionedNode( - final String name, final String genesisFile, final Node... localConfigAllowedNodes) { - PermissionedNodeBuilder permissionedNodeBuilder = - this.permissionedNodeBuilder - .name(name) - .genesisFile(genesisFile) - .nodesContractEnabled(CONTRACT_ADDRESS); - if (localConfigAllowedNodes != null && localConfigAllowedNodes.length > 0) { - permissionedNodeBuilder.nodesPermittedInConfig(localConfigAllowedNodes); - } - return permissionedNodeBuilder.build(); - } - - protected Node bootnode(final String name) { - return bootnode(name, GENESIS_FILE); - } - - protected Node bootnode(final String name, final String genesisFile) { - try { - return besu.createCustomGenesisNode(name, genesisFile, true); - } catch (IOException e) { - throw new RuntimeException("Error creating node", e); - } - } - - protected Node node(final String name) { - try { - return besu.createCustomGenesisNode(name, GENESIS_FILE, false); - } catch (IOException e) { - throw new RuntimeException("Error creating node", e); - } - } - - protected Node miner(final String name) { - try { - return besu.createCustomGenesisNode(name, GENESIS_FILE, false, true); - } catch (IOException e) { - throw new RuntimeException("Error creating node", e); - } - } - - @Override - public void tearDownAcceptanceTestBase() { - permissionedCluster.stop(); - super.tearDownAcceptanceTestBase(); - } - - protected Transaction allowNode(final Node node) { - return smartContractNodePermissioning.allowNode(CONTRACT_ADDRESS, node); - } - - protected Condition nodeIsAllowed(final Node node) { - return nodeSmartContractPermissioningConditions.nodeIsAllowed(CONTRACT_ADDRESS, node); - } - - protected Transaction forbidNode(final Node node) { - return smartContractNodePermissioning.forbidNode(CONTRACT_ADDRESS, node); - } - - protected Condition nodeIsForbidden(final Node node) { - return nodeSmartContractPermissioningConditions.nodeIsForbidden(CONTRACT_ADDRESS, node); - } - - protected Condition connectionIsAllowed(final Node source, final Node target) { - return nodeSmartContractPermissioningConditions.connectionIsAllowed( - CONTRACT_ADDRESS, source, target); - } - - protected Condition connectionIsForbidden(final Node source, final Node target) { - return nodeSmartContractPermissioningConditions.connectionIsForbidden( - CONTRACT_ADDRESS, source, target); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbft2StallAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbft2StallAcceptanceTest.java deleted file mode 100644 index ed48ad9db..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningIbft2StallAcceptanceTest.java +++ /dev/null @@ -1,76 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration; -import org.hyperledger.besu.ethereum.permissioning.SmartContractPermissioningConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; - -import java.io.IOException; -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -public class NodeSmartContractPermissioningIbft2StallAcceptanceTest - extends NodeSmartContractPermissioningAcceptanceTestBase { - - private static final String GENESIS_FILE = - "/permissioning/simple_permissioning_ibft_genesis.json"; - - @Test - public void restartedIbftClusterShouldNotStall() throws IOException { - final BesuNode bootnode = besu.createIbft2NonValidatorBootnode("bootnode", GENESIS_FILE); - final BesuNode nodeA = besu.createIbft2Node("nodeA", GENESIS_FILE); - final BesuNode nodeB = besu.createIbft2Node("nodeB", GENESIS_FILE); - - permissionedCluster.start(bootnode, nodeA, nodeB); - - // make sure we are producing blocks before sending any transactions - waitForBlockHeight(bootnode, 1); - - // allow nodes in onchain smart contract - nodeA.execute(allowNode(bootnode)); - nodeA.execute(allowNode(nodeA)); - nodeA.execute(allowNode(nodeB)); - - // verify the nodes are allowed - nodeA.verify(nodeIsAllowed(bootnode)); - nodeA.verify(nodeIsAllowed(nodeA)); - nodeA.verify(nodeIsAllowed(nodeB)); - - permissionedCluster.stop(); - - // Create permissioning config - final SmartContractPermissioningConfiguration smartContractPermissioningConfiguration = - new SmartContractPermissioningConfiguration(); - smartContractPermissioningConfiguration.setSmartContractNodeAllowlistEnabled(true); - smartContractPermissioningConfiguration.setNodeSmartContractAddress( - Address.fromHexString(CONTRACT_ADDRESS)); - final PermissioningConfiguration permissioningConfiguration = - new PermissioningConfiguration( - Optional.empty(), Optional.of(smartContractPermissioningConfiguration)); - - // Set permissioning configurations on nodes - bootnode.setPermissioningConfiguration(permissioningConfiguration); - nodeA.setPermissioningConfiguration(permissioningConfiguration); - nodeB.setPermissioningConfiguration(permissioningConfiguration); - - permissionedCluster.start(bootnode, nodeA, nodeB); - - // Verify blockchain is progressing - permissionedCluster.verify(blockchain.reachesHeight(bootnode, 1, 120)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java deleted file mode 100644 index de888904f..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java +++ /dev/null @@ -1,67 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -public class NodeSmartContractPermissioningOutOfSyncAcceptanceTest - extends NodeSmartContractPermissioningAcceptanceTestBase { - private Node bootnode; - private Node permissionedNodeA; - private Node permissionedNodeB; - - @BeforeEach - public void setUp() throws InterruptedException { - bootnode = bootnode("bootnode"); - permissionedNodeA = permissionedNode("permissioned-node-A"); - permissionedNodeB = permissionedNode("permissioned-node-B"); - - permissionedCluster.start(bootnode, permissionedNodeA); - - // update onchain smart contract to allowlist nodes - permissionedNodeA.execute(allowNode(bootnode)); - permissionedNodeA.verify(nodeIsAllowed(bootnode)); - permissionedNodeA.execute(allowNode(permissionedNodeA)); - permissionedNodeA.verify(nodeIsAllowed(permissionedNodeA)); - permissionedNodeA.verify(admin.addPeer(bootnode)); - } - - @Test - @Disabled("test is flaky #7108") - public void addNodeToClusterAndVerifyNonBootNodePeerConnectionWorksAfterSync() { - final long blockchainHeight = 25L; - waitForBlockHeight(permissionedNodeA, blockchainHeight); - - // verify Node A is in sync with bootnode - final var minerChainHead = bootnode.execute(ethTransactions.block()); - permissionedNodeA.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue())); - - // check that connection is forbidden (before node b is permitted) - permissionedCluster.addNode(permissionedNodeB); - permissionedNodeB.verify(connectionIsForbidden(permissionedNodeA, permissionedNodeB)); - - // Permit Node B - permissionedNodeA.execute(allowNode(permissionedNodeB)); - permissionedNodeA.verify(admin.addPeer(permissionedNodeB)); - - // connection should be allowed after node B syncs - waitForBlockHeight(permissionedNodeB, blockchainHeight); - permissionedNodeB.verify(connectionIsAllowed(permissionedNodeA, permissionedNodeB)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java deleted file mode 100644 index 1f2cc682c..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTest.java +++ /dev/null @@ -1,128 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -public class NodeSmartContractPermissioningV2AcceptanceTest - extends NodeSmartContractPermissioningV2AcceptanceTestBase { - - private Node bootnode; - private Node permissionedNode; - private Node allowedNode; - private Node forbiddenNode; - - @BeforeEach - public void setUp() { - bootnode = bootnode("bootnode"); - forbiddenNode = node("forbidden-node"); - allowedNode = node("allowed-node"); - permissionedNode = permissionedNode("permissioned-node"); - - permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode); - - verifyAllNodesAreInSyncWithMiner(); - - // updating permissioning smart contract with allowed nodes - - permissionedNode.execute(allowNode(bootnode)); - permissionedNode.verify(connectionIsAllowed(bootnode)); - - permissionedNode.execute(allowNode(allowedNode)); - permissionedNode.verify(connectionIsAllowed(allowedNode)); - - permissionedNode.execute(allowNode(permissionedNode)); - permissionedNode.verify(connectionIsAllowed(permissionedNode)); - } - - @Test - @Disabled("test is flaky") - public void permissionedNodeShouldPeerOnlyWithAllowedNodes() { - bootnode.verify(net.awaitPeerCount(3)); - allowedNode.verify(net.awaitPeerCount(3)); - forbiddenNode.verify(net.awaitPeerCount(2)); - permissionedNode.verify(net.awaitPeerCount(2)); - } - - @Test - public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() { - permissionedNode.verify(admin.hasPeer(bootnode)); - permissionedNode.verify(admin.addPeer(allowedNode)); - permissionedNode.verify(net.awaitPeerCount(2)); - - permissionedNode.execute(forbidNode(allowedNode)); - permissionedNode.verify(connectionIsForbidden(allowedNode)); - - permissionedNode.verify(net.awaitPeerCount(1)); - } - - @Test - public void permissionedNodeShouldConnectToNewlyPermittedNode() { - permissionedNode.verify(admin.hasPeer(bootnode)); - permissionedNode.verify(admin.addPeer(allowedNode)); - permissionedNode.verify(net.awaitPeerCount(2)); - - verifyAllNodesAreInSyncWithMiner(); - - permissionedNode.execute(allowNode(forbiddenNode)); - permissionedNode.verify(connectionIsAllowed(forbiddenNode)); - permissionedNode.verify(admin.addPeer(forbiddenNode)); - - permissionedNode.verify(net.awaitPeerCount(3)); - } - - @Test - public void permissioningUpdatesPropagateThroughNetwork() { - permissionedNode.verify(admin.hasPeer(bootnode)); - permissionedNode.verify(admin.addPeer(allowedNode)); - permissionedNode.verify(net.awaitPeerCount(2)); - - verifyAllNodesAreInSyncWithMiner(); - - // permissioning changes in peer should propagate to permissioned node - allowedNode.execute(allowNode(forbiddenNode)); - allowedNode.verify(connectionIsAllowed(forbiddenNode)); - permissionedNode.verify(connectionIsAllowed(forbiddenNode)); - - permissionedNode.verify(admin.addPeer(forbiddenNode)); - permissionedNode.verify(net.awaitPeerCount(3)); - } - - private void verifyAllNodesAreInSyncWithMiner() { - // verify the miner (permissionedNode) started producing blocks and other nodes are syncing - // from it - waitForBlockHeight(permissionedNode, 1); - final var minerChainHead = permissionedNode.execute(ethTransactions.block()); - bootnode.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue())); - allowedNode.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue())); - } - - @Test - public void onchainPermissioningAllowlistShouldPersistAcrossRestarts() { - permissionedCluster.stop(); - permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode); - - verifyAllNodesAreInSyncWithMiner(); - - permissionedNode.verify(connectionIsAllowed(allowedNode)); - permissionedNode.verify(connectionIsAllowed(bootnode)); - permissionedNode.verify(connectionIsAllowed(permissionedNode)); - permissionedNode.verify(connectionIsForbidden(forbiddenNode)); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTestBase.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTestBase.java deleted file mode 100644 index 21afa801d..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2AcceptanceTestBase.java +++ /dev/null @@ -1,135 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; -import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition; -import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.NodeSmartContractPermissioningV2Conditions; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration; -import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction; -import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningV2Transactions; - -import java.io.IOException; - -class NodeSmartContractPermissioningV2AcceptanceTestBase extends AcceptanceTestBase { - - private final NodeSmartContractPermissioningV2Transactions smartContractNodePermissioningV2; - private final NodeSmartContractPermissioningV2Conditions - nodeSmartContractPermissioningConditionsV2; - - protected static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009999"; - protected static final String GENESIS_FILE = - "/permissioning/simple_permissioning_v2_genesis.json"; - - protected final Cluster permissionedCluster; - - protected NodeSmartContractPermissioningV2AcceptanceTestBase() { - super(); - smartContractNodePermissioningV2 = new NodeSmartContractPermissioningV2Transactions(accounts); - nodeSmartContractPermissioningConditionsV2 = - new NodeSmartContractPermissioningV2Conditions(smartContractNodePermissioningV2); - - this.permissionedCluster = permissionedCluster(); - } - - private Cluster permissionedCluster() { - final ClusterConfiguration clusterConfiguration = - new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build(); - return new Cluster(clusterConfiguration, net); - } - - protected Node permissionedNode(final String name, final Node... localConfigAllowedNodes) { - return permissionedNode(name, GENESIS_FILE, localConfigAllowedNodes); - } - - protected Node permissionedNode( - final String name, final String genesisFile, final Node... localConfigAllowedNodes) { - PermissionedNodeBuilder permissionedNodeBuilder = - this.permissionedNodeBuilder - .name(name) - .genesisFile(genesisFile) - .nodesContractV2Enabled(CONTRACT_ADDRESS); - if (localConfigAllowedNodes != null && localConfigAllowedNodes.length > 0) { - permissionedNodeBuilder.nodesPermittedInConfig(localConfigAllowedNodes); - } - return permissionedNodeBuilder.build(); - } - - protected Node bootnode(final String name) { - return bootnode(name, GENESIS_FILE); - } - - protected Node bootnode(final String name, final String genesisFile) { - try { - return besu.createCustomGenesisNode(name, genesisFile, true); - } catch (IOException e) { - throw new RuntimeException("Error creating node", e); - } - } - - protected Node node(final String name) { - try { - return besu.createCustomGenesisNode(name, GENESIS_FILE, false); - } catch (IOException e) { - throw new RuntimeException("Error creating node", e); - } - } - - @Override - public void tearDownAcceptanceTestBase() { - permissionedCluster.stop(); - super.tearDownAcceptanceTestBase(); - } - - protected Transaction allowNode(final Node node) { - return smartContractNodePermissioningV2.allowNode(CONTRACT_ADDRESS, node); - } - - protected Transaction allowNode(final EnodeURL enodeURL) { - return smartContractNodePermissioningV2.allowNode(CONTRACT_ADDRESS, enodeURL); - } - - protected Transaction forbidNode(final Node node) { - return smartContractNodePermissioningV2.forbidNode(CONTRACT_ADDRESS, node); - } - - protected Transaction forbidNode(final EnodeURL enodeURL) { - return smartContractNodePermissioningV2.forbidNode(CONTRACT_ADDRESS, enodeURL); - } - - protected Condition connectionIsForbidden(final Node node) { - return nodeSmartContractPermissioningConditionsV2.connectionIsForbidden(CONTRACT_ADDRESS, node); - } - - protected Condition connectionIsForbidden(final EnodeURL enodeURL) { - return nodeSmartContractPermissioningConditionsV2.connectionIsForbidden( - CONTRACT_ADDRESS, enodeURL); - } - - protected Condition connectionIsAllowed(final Node node) { - return nodeSmartContractPermissioningConditionsV2.connectionIsAllowed(CONTRACT_ADDRESS, node); - } - - protected Condition connectionIsAllowed(final EnodeURL enodeURL) { - return nodeSmartContractPermissioningConditionsV2.connectionIsAllowed( - CONTRACT_ADDRESS, enodeURL); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java deleted file mode 100644 index 435333a77..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningV2DNSAcceptanceTest.java +++ /dev/null @@ -1,107 +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.tests.acceptance.permissioning; - -import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; -import org.hyperledger.besu.ethereum.p2p.peers.ImmutableEnodeDnsConfiguration; -import org.hyperledger.besu.plugin.data.EnodeURL; -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled("test is flaky #7191") -public class NodeSmartContractPermissioningV2DNSAcceptanceTest - extends NodeSmartContractPermissioningV2AcceptanceTestBase { - - private Node bootnode; - private Node permissionedNode; - private Node allowedNode; - private Node forbiddenNode; - - final ImmutableEnodeDnsConfiguration enodeDnsConfiguration = - ImmutableEnodeDnsConfiguration.builder().dnsEnabled(true).updateEnabled(true).build(); - - @BeforeEach - public void setUp() { - bootnode = bootnode("bootnode"); - forbiddenNode = node("forbidden-node"); - allowedNode = node("allowed-node"); - permissionedNode = permissionedNode("permissioned-node"); - - permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode); - - // updating permissioning smart contract with allowed nodes - - permissionedNode.execute(allowNode(bootnode)); - permissionedNode.verify(connectionIsAllowed(bootnode)); - - permissionedNode.execute(allowNode(allowedNode)); - permissionedNode.verify(connectionIsAllowed(allowedNode)); - - permissionedNode.execute(allowNode(permissionedNode)); - permissionedNode.verify(connectionIsAllowed(permissionedNode)); - } - - @Test - public void permissionedNodeShouldAddDnsRuleAndAllowNode() throws UnknownHostException { - final EnodeURL forbiddenEnodeURL = getForbiddenEnodeURL(); - Assertions.assertThat(forbiddenEnodeURL.toURI().getHost()).isEqualTo("127.0.0.1"); - final EnodeURL forbiddenDnsEnodeURL = buildDnsEnodeUrl(forbiddenEnodeURL); - Assertions.assertThat(forbiddenDnsEnodeURL.toURI().getHost()) - .isEqualTo(InetAddress.getLocalHost().getHostName()); - - permissionedNode.verify(connectionIsForbidden(forbiddenNode)); - permissionedNode.verify(connectionIsForbidden(forbiddenDnsEnodeURL)); - permissionedNode.execute(allowNode(forbiddenDnsEnodeURL)); - permissionedNode.verify(connectionIsAllowed(forbiddenDnsEnodeURL)); - permissionedNode.execute(forbidNode(forbiddenEnodeURL)); - } - - @Test - public void permissionedNodeShouldAddDNSRuleAndConnectToNewPeer() throws UnknownHostException { - final EnodeURL forbiddenEnodeURL = getForbiddenEnodeURL(); - Assertions.assertThat(forbiddenEnodeURL.toURI().getHost()).isEqualTo("127.0.0.1"); - final EnodeURL forbiddenDnsEnodeURL = buildDnsEnodeUrl(forbiddenEnodeURL); - Assertions.assertThat(forbiddenDnsEnodeURL.toURI().getHost()) - .isEqualTo(InetAddress.getLocalHost().getHostName()); - - permissionedNode.verify(net.awaitPeerCount(2)); - permissionedNode.verify(connectionIsForbidden(forbiddenNode)); - permissionedNode.verify(connectionIsForbidden(forbiddenDnsEnodeURL)); - permissionedNode.execute(allowNode(forbiddenDnsEnodeURL)); - permissionedNode.verify(connectionIsAllowed(forbiddenDnsEnodeURL)); - permissionedNode.verify(admin.addPeer(forbiddenNode)); - permissionedNode.verify(net.awaitPeerCount(3)); - permissionedNode.execute(forbidNode(forbiddenEnodeURL)); - } - - private EnodeURL getForbiddenEnodeURL() { - return EnodeURLImpl.fromURI(((RunnableNode) forbiddenNode).enodeUrl()); - } - - private EnodeURL buildDnsEnodeUrl(final EnodeURL forbiddenEnodeURL) { - return EnodeURLImpl.builder() - .configureFromEnode(forbiddenEnodeURL) - .ipAddress("localhost", enodeDnsConfiguration) - .build(); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java deleted file mode 100644 index 898f0e47a..000000000 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.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.tests.acceptance.permissioning; - -import static java.util.stream.Collectors.toList; - -import org.hyperledger.besu.tests.acceptance.dsl.node.Node; -import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode; - -import java.net.URI; -import java.util.Arrays; -import java.util.List; -import javax.annotation.Nonnull; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled("flaky test #7155") -public class NodesSmartContractPermissioningStaticNodesAcceptanceTest - extends NodeSmartContractPermissioningAcceptanceTestBase { - - private Node miner; - private Node permissionedNode; - - @BeforeEach - public void setUp() { - miner = miner("miner"); - permissionedCluster.start(miner); - } - - @Test - public void onlyTrustStaticNodesWhileOutOfSync() { - // wait for some blocks so the permissioned node has some syncing to do - waitForBlockHeight(miner, 25); - stopMining(miner); - - // start permissioned node with miner node in the static nodes list - permissionedNode = permissionedNodeWithStaticNodes(Arrays.asList(miner)); - permissionedCluster.addNode(permissionedNode); - - // as soon as we start the node should connect to static nodes - permissionedNode.verify(net.awaitPeerCount(1)); - waitForBlockHeight(permissionedNode, 25); - - // after syncing up with the network the node won't trust static nodes anymore - permissionedNode.verify(net.awaitPeerCount(0)); - } - - private void stopMining(final Node node) { - node.execute(minerTransactions.minerStop()); - node.verify(eth.miningStatus(false)); - } - - private Node permissionedNodeWithStaticNodes(final List staticNodes) { - return permissionedNodeBuilder - .name("node-with-static-nodes") - .genesisFile(GENESIS_FILE) - .nodesContractEnabled(CONTRACT_ADDRESS) - .staticNodes(mapNodesToEnodeURLs(staticNodes)) - .disableMining() - .build(); - } - - @Nonnull - private List mapNodesToEnodeURLs(final List staticNodes) { - return staticNodes.stream() - .map(node -> (RunnableNode) node) - .map(RunnableNode::enodeUrl) - .map(URI::toASCIIString) - .collect(toList()); - } -} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java index c469802fc..6c3a8661c 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/PermissioningPluginTest.java @@ -14,18 +14,27 @@ */ package org.hyperledger.besu.tests.acceptance.plugins; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +import org.hyperledger.besu.crypto.SECP256K1; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase; import org.hyperledger.besu.tests.acceptance.dsl.account.Account; import org.hyperledger.besu.tests.acceptance.dsl.blockchain.Amount; import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode; import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfigurationBuilder; +import org.hyperledger.besu.tests.acceptance.dsl.transaction.SignUtil; import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.TransferTransaction; +import java.math.BigInteger; import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.web3j.crypto.RawTransaction; +import org.web3j.utils.Convert; +import org.web3j.utils.Numeric; public class PermissioningPluginTest extends AcceptanceTestBase { private BesuNode minerNode; @@ -34,6 +43,8 @@ public class PermissioningPluginTest extends AcceptanceTestBase { private BesuNode bobNode; private BesuNode charlieNode; + private static final long GAS_LIMIT_THRESHOLD = 22000L; + @BeforeEach public void setUp() throws Exception { minerNode = besu.create(createNodeBuilder().name("miner").build()); @@ -96,4 +107,54 @@ public class PermissioningPluginTest extends AcceptanceTestBase { charlieNode.verify(txPoolConditions.notInTransactionPool(txHash)); minerNode.verify(txPoolConditions.inTransactionPool(txHash)); } + + @Test + public void allowFilteredByGasLimit() { + + final Account sender = accounts.getPrimaryBenefactor(); + final Account recipient = accounts.createAccount("account-two"); + final BigInteger GAS_LIMIT = BigInteger.valueOf(GAS_LIMIT_THRESHOLD + 100); + final BigInteger GAS_PRICE = BigInteger.valueOf(1000); + final Amount amount = Amount.wei(BigInteger.valueOf(29)); + + final RawTransaction tx = + RawTransaction.createEtherTransaction( + sender.getNextNonce(), + GAS_PRICE, + GAS_LIMIT, + recipient.getAddress(), + Convert.toWei(amount.getValue(), amount.getUnit()).toBigIntegerExact()); + + final String rawSigned = + Numeric.toHexString( + SignUtil.signTransaction(tx, sender, new SECP256K1(), Optional.empty())); + final String txHash = aliceNode.execute(ethTransactions.sendRawTransaction(rawSigned)); + + aliceNode.verify(txPoolConditions.inTransactionPool(Hash.fromHexString(txHash))); + } + + @Test + public void blockedFilteredByGasLimit() { + final Account sender = accounts.getPrimaryBenefactor(); + final Account recipient = accounts.createAccount("account-two"); + final BigInteger GAS_LIMIT = BigInteger.valueOf(GAS_LIMIT_THRESHOLD - 100); + final BigInteger GAS_PRICE = BigInteger.valueOf(1000); + final Amount amount = Amount.wei(BigInteger.valueOf(29)); + + final RawTransaction tx = + RawTransaction.createEtherTransaction( + sender.getNextNonce(), + GAS_PRICE, + GAS_LIMIT, + recipient.getAddress(), + Convert.toWei(amount.getValue(), amount.getUnit()).toBigIntegerExact()); + + final String rawSigned = + Numeric.toHexString( + SignUtil.signTransaction(tx, sender, new SECP256K1(), Optional.empty())); + + assertThatThrownBy(() -> aliceNode.execute(ethTransactions.sendRawTransaction(rawSigned))) + .isInstanceOf(RuntimeException.class) + .hasMessageContaining("not authorized"); + } } diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/paris/test-cases/02_get_payload.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/paris/test-cases/02_get_payload.json index e52570905..82b226f7a 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/paris/test-cases/02_get_payload.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/paris/test-cases/02_get_payload.json @@ -18,12 +18,12 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1", - "gasLimit": "0x1c9c380", + "gasLimit": "0x1ca35ef", "gasUsed": "0x0", "timestamp": "0x5", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", + "blockHash": "0x48513c8021d27d6555aacf2a3a124952c5514f80ab280de32da330f528ad1a11", "transactions": [] } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/02_paris_getPayloadV1.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/02_paris_getPayloadV1.json index 9a6d96f88..cb407256f 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/02_paris_getPayloadV1.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/02_paris_getPayloadV1.json @@ -18,12 +18,12 @@ "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1", - "gasLimit": "0x1c9c380", + "gasLimit": "0x1ca35ef", "gasUsed": "0x0", "timestamp": "0x5", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf4a1d287dd3bb7e877c57476912e6a6052bc4eed8ea70d032b55d77f26ee985f", + "blockHash": "0xcdda91dbfe90c051ab1bdb703c9996fdb8cebaa7b9e7bc9e430e7e743e1b9682", "transactions": [] } }, diff --git a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/08_shanghai_getPayloadV2.json b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/08_shanghai_getPayloadV2.json index 072e5146d..a43d276a8 100644 --- a/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/08_shanghai_getPayloadV2.json +++ b/acceptance-tests/tests/src/test/resources/jsonrpc/engine/shanghai/test-cases/08_shanghai_getPayloadV2.json @@ -17,7 +17,7 @@ "stateRoot": "0xa61c2a422a4f7d7d7f456c1a83d5484eaf0d49e2b6b6d5716f875e782c66a9f0", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x1c9c380", + "gasLimit": "0x1ca35ef", "gasUsed": "0x0", "timestamp": "0x10", "extraData": "0x", @@ -38,7 +38,7 @@ } ], "blockNumber": "0x2", - "blockHash": "0x612abd8615f544759d4aeb3dbab32f5f198a8b818e9c5436e9f7a674ef3b0f20", + "blockHash": "0xc7f79c3547adc7886a1607bfd1efb9de3d277991037dba01cffdd67e298aa2bf", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" }, "blockValue": "0x0" diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/ibft.blocks b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/ibft.blocks new file mode 100755 index 000000000..3e04a5441 Binary files /dev/null and b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/ibft.blocks differ diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner1key b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner1key new file mode 100644 index 000000000..cd51abdc8 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner1key @@ -0,0 +1 @@ +0a46b91fe0c770a4355d1fec9ccd72d39264f46a74ed67a69a12ed4c265aa768 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner1key.pub b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner1key.pub new file mode 100644 index 000000000..bd7912f9c --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner1key.pub @@ -0,0 +1 @@ +8093fb3200c783555ed487b8b5210ef3369b062a1f3ce5762d83d7a62205693d1e4f253e840ca48ec98d8f20c5b41bbbd43f34f87a1f68324ab51afe73732b96 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner2key b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner2key new file mode 100644 index 000000000..225990f04 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner2key @@ -0,0 +1 @@ +17c2aacfdf1f6defde20e6ae7132c6d3991e758af3799a307a75b38135678a48 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner2key.pub b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner2key.pub new file mode 100644 index 000000000..5a93124a1 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner2key.pub @@ -0,0 +1 @@ +d81f65976ccc44c5e7e6ca859c5ede06b0f484f72c52d35dd8f7bd7581a8b7020d9ef45878696b4593daf5575b48dda5259f78f192a3445d5cc97c032660642f \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner3key b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner3key new file mode 100644 index 000000000..5abdb3440 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner3key @@ -0,0 +1 @@ +917fb1b03034e5d7156b89bc2a3bc2aae1d146d2640d75e095f07110b0871bc1 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner3key.pub b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner3key.pub new file mode 100644 index 000000000..905ea256a --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner3key.pub @@ -0,0 +1 @@ +67785a2ac328648d94245abb25bdcfab853d06e68c70026d90f2fd5c8338b65c19235398eac205e4bbdb3fc1de9669ad6309e43ab203c8e7430664cea6451f56 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner4key b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner4key new file mode 100644 index 000000000..0c185203a --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner4key @@ -0,0 +1 @@ +3b3cbae8c034c4ba2d5f4df44faa013888216a6eabb7fffa0b224003ea770ba7 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner4key.pub b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner4key.pub new file mode 100644 index 000000000..0821e84cb --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner4key.pub @@ -0,0 +1 @@ +ec403552908986b5d9e4def3be9ddcb26d5b03def3b44ef2d5d728bb9a3028603405e7379c3e185cb2bc3e784548fcdd0e7616162029c3f407155b2fb25ba0ca \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner5key b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner5key new file mode 100644 index 000000000..ad59591a1 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner5key @@ -0,0 +1 @@ +4ddfb30d4fcd6f5a9f959961f734e4c1469af223bc16b217eef0d3796e64973d \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner5key.pub b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner5key.pub new file mode 100644 index 000000000..f259f681d --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/miner5key.pub @@ -0,0 +1 @@ +28c02b375d62b0adef8213b76882dfec264d5dcbb0a8ba73f167bc718a6d02f1833af80ab9f51a5f007e5f3b8320e8fc5ab287d4bd59ad497f8949bf4abb9e80 \ No newline at end of file diff --git a/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/qbft-migration.json b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/qbft-migration.json new file mode 100644 index 000000000..e51a65828 --- /dev/null +++ b/acceptance-tests/tests/src/test/resources/qbft/migration-ibft1/qbft-migration.json @@ -0,0 +1,63 @@ +{ + "nonce": "0x0", + "timestamp": "0x58ee40ba", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f86df86994a18182ee8ca476f2f0fb8170a1d4620edb39c5e194065541903bf3bb8c088a18046b441f5d286288c994d1e106d68cac92668b100f6f43791ddcb2c7588094d156777a1e1539fe654fc82266f41fd5d4aa548494efbbd8900222d7b2f75d081c3e7446a1f4fe10ce80c0", + "gasLimit": "700000000", + "gasUsed": "0x0", + "number": "0x0", + "difficulty": "0x1", + "coinbase": "0x0000000000000000000000000000000000000000", + "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "config": { + "chainId": 1337, + "homesteadBlock": 10, + "eip150Block": 20, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 25, + "eip158Block": 30, + "byzantiumBlock": 50, + "constantinopleBlock": 60, + "petersburgBlock": 70, + "istanbulBlock": 80, + "ibft": { + "epochlength": 100, + "blockperiodseconds": 5, + "requesttimeoutseconds": 10, + "policy": 0, + "ceil2Nby3Block": 0, + "validatorcontractaddress": "0x0000000000000000000000000000000000000000" + }, + "qbft": { + "epochLength": 30000, + "blockPeriodSeconds" : 1, + "requestTimeoutSeconds": 10, + "startBlock": 101 + }, + "txnSizeLimit": 64, + "maxCodeSize": 0, + "maxCodeSizeConfig": [ + { + "block": 0, + "size": 64 + } + ] + }, + "alloc": { + "0xde8e2ae09f2ee2c6c282c054b2384f8b5f9debee": { + "balance": "1000000000000000000000000000" + }, + "0x23bcbca17fc4978909ab44ac82559c7d379aa006": { + "balance": "1000000000000000000000000000" + }, + "0x870276532cca9f33e66273cfa494cf41e04b5a66": { + "balance": "1000000000000000000000000000" + }, + "0x7d7fc9fdfa49e2db22fc6ebab593dcf3aeffbde8": { + "balance": "1000000000000000000000000000" + }, + "0x4df76ad0678513846699056e0070c5f587580eb5": { + "balance": "1000000000000000000000000000" + } + } +} diff --git a/acceptance-tests/tests/src/test/resources/qbft/qbft.json b/acceptance-tests/tests/src/test/resources/qbft/qbft.json index b614538b6..88b4f1926 100644 --- a/acceptance-tests/tests/src/test/resources/qbft/qbft.json +++ b/acceptance-tests/tests/src/test/resources/qbft/qbft.json @@ -36,4 +36,4 @@ "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} +} \ No newline at end of file diff --git a/besu/build.gradle b/besu/build.gradle index d1230b697..c6b99b27f 100644 --- a/besu/build.gradle +++ b/besu/build.gradle @@ -37,6 +37,7 @@ 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(':consensus:qbft-core') @@ -71,17 +72,17 @@ dependencies { implementation 'info.picocli:picocli' implementation 'io.vertx:vertx-core' implementation 'io.vertx:vertx-web' - implementation 'io.tmio:tuweni-bytes' - implementation 'io.tmio:tuweni-config' - implementation 'io.tmio:tuweni-toml' - implementation 'io.tmio:tuweni-units' + implementation 'io.consensys.protocols:tuweni-bytes' + implementation 'io.consensys.protocols:tuweni-config' + implementation 'io.consensys.protocols:tuweni-toml' + implementation 'io.consensys.protocols:tuweni-units' implementation 'org.apache.commons:commons-lang3' implementation 'org.apache.logging.log4j:log4j-core' implementation 'org.hibernate.validator:hibernate-validator' implementation 'org.rocksdb:rocksdbjni' implementation 'org.springframework.security:spring-security-crypto' implementation 'org.xerial.snappy:snappy-java' - implementation 'tech.pegasys:jc-kzg-4844' + implementation 'io.consensys.protocols:jc-kzg-4844' runtimeOnly 'org.apache.logging.log4j:log4j-jul' runtimeOnly 'com.splunk.logging:splunk-library-javalogging' @@ -97,8 +98,8 @@ dependencies { testImplementation 'io.opentelemetry:opentelemetry-api' testImplementation 'org.mockito:mockito-junit-jupiter' testImplementation 'org.apache.commons:commons-text' - testImplementation 'io.tmio:tuweni-bytes' - testImplementation 'io.tmio:tuweni-units' + testImplementation 'io.consensys.protocols:tuweni-bytes' + testImplementation 'io.consensys.protocols:tuweni-units' testImplementation 'org.assertj:assertj-core' testImplementation 'org.awaitility:awaitility' testImplementation 'org.junit.jupiter:junit-jupiter' diff --git a/besu/src/main/java/org/hyperledger/besu/Runner.java b/besu/src/main/java/org/hyperledger/besu/Runner.java index 609dab117..5fdb80f8a 100644 --- a/besu/src/main/java/org/hyperledger/besu/Runner.java +++ b/besu/src/main/java/org/hyperledger/besu/Runner.java @@ -173,6 +173,7 @@ public class Runner implements AutoCloseable { LOG.info("Starting Ethereum main loop ... "); natService.start(); networkRunner.start(); + besuController.getMiningCoordinator().subscribe(); if (networkRunner.getNetwork().isP2pEnabled()) { besuController.getSynchronizer().start(); } diff --git a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java index b843430e5..3dc01ed8b 100644 --- a/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -118,8 +118,6 @@ import org.hyperledger.besu.nat.NatService; import org.hyperledger.besu.nat.core.NatManager; import org.hyperledger.besu.nat.docker.DockerDetector; import org.hyperledger.besu.nat.docker.DockerNatManager; -import org.hyperledger.besu.nat.kubernetes.KubernetesDetector; -import org.hyperledger.besu.nat.kubernetes.KubernetesNatManager; import org.hyperledger.besu.nat.upnp.UpnpNatManager; import org.hyperledger.besu.plugin.BesuPlugin; import org.hyperledger.besu.plugin.data.EnodeURL; @@ -170,7 +168,6 @@ public class RunnerBuilder { private String p2pListenInterface = NetworkUtility.INADDR_ANY; private int p2pListenPort; private NatMethod natMethod = NatMethod.AUTO; - private String natManagerServiceName; private boolean natMethodFallbackEnabled; private EthNetworkConfig ethNetworkConfig; private EthstatsOptions ethstatsOptions; @@ -313,17 +310,6 @@ public class RunnerBuilder { return this; } - /** - * Add Nat manager service name. - * - * @param natManagerServiceName the nat manager service name - * @return the runner builder - */ - public RunnerBuilder natManagerServiceName(final String natManagerServiceName) { - this.natManagerServiceName = natManagerServiceName; - return this; - } - /** * Enable Nat method fallback. * @@ -1191,10 +1177,17 @@ public class RunnerBuilder { final BesuController besuController, final TransactionSimulator transactionSimulator) { - if (permissioningConfiguration.isPresent()) { + if (permissioningConfiguration.isPresent() + || permissioningService.getTransactionPermissioningProviders().size() > 0) { + final PermissioningConfiguration configuration = + permissioningConfiguration.orElse( + new PermissioningConfiguration(Optional.empty(), Optional.empty())); final Optional accountPermissioningController = AccountPermissioningControllerFactory.create( - permissioningConfiguration.get(), transactionSimulator, metricsSystem); + configuration, + transactionSimulator, + metricsSystem, + permissioningService.getTransactionPermissioningProviders()); accountPermissioningController.ifPresent( permissioningController -> @@ -1213,15 +1206,13 @@ public class RunnerBuilder { final NatMethod detectedNatMethod = Optional.of(natMethod) .filter(not(isEqual(NatMethod.AUTO))) - .orElse(NatService.autoDetectNatMethod(new KubernetesDetector(), new DockerDetector())); + .orElse(NatService.autoDetectNatMethod(new DockerDetector())); switch (detectedNatMethod) { case UPNP: return Optional.of(new UpnpNatManager()); case DOCKER: return Optional.of( new DockerNatManager(p2pAdvertisedHost, p2pListenPort, jsonRpcConfiguration.getPort())); - case KUBERNETES: - return Optional.of(new KubernetesNatManager(natManagerServiceName)); case NONE: default: return Optional.empty(); diff --git a/besu/src/main/java/org/hyperledger/besu/chainimport/Era1BlockImporter.java b/besu/src/main/java/org/hyperledger/besu/chainimport/Era1BlockImporter.java new file mode 100644 index 000000000..cead4e229 --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/chainimport/Era1BlockImporter.java @@ -0,0 +1,171 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.chainimport; + +import org.hyperledger.besu.controller.BesuController; +import org.hyperledger.besu.ethereum.ProtocolContext; +import org.hyperledger.besu.ethereum.core.Block; +import org.hyperledger.besu.ethereum.core.BlockBody; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; +import org.hyperledger.besu.ethereum.core.BlockImporter; +import org.hyperledger.besu.ethereum.core.TransactionReceipt; +import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; +import org.hyperledger.besu.ethereum.mainnet.BodyValidationMode; +import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; +import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; +import org.hyperledger.besu.ethereum.mainnet.ScheduleBasedBlockHeaderFunctions; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; +import org.hyperledger.besu.ethereum.rlp.RLPInput; +import org.hyperledger.besu.util.era1.Era1BlockIndex; +import org.hyperledger.besu.util.era1.Era1ExecutionBlockBody; +import org.hyperledger.besu.util.era1.Era1ExecutionBlockHeader; +import org.hyperledger.besu.util.era1.Era1ExecutionBlockReceipts; +import org.hyperledger.besu.util.era1.Era1Reader; +import org.hyperledger.besu.util.era1.Era1ReaderListener; +import org.hyperledger.besu.util.snappy.SnappyFactory; + +import java.io.Closeable; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.tuweni.bytes.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tool for importing era1-encoded block data, headers, and transaction receipts from era1 files. + */ +public class Era1BlockImporter implements Closeable { + private static final Logger LOG = LoggerFactory.getLogger(Era1BlockImporter.class); + + private static final int ERA1_BLOCK_COUNT_MAX = 8192; + private static final int IMPORT_COUNT_FOR_LOG_UPDATE = 1000; + + /** Default Constructor. */ + public Era1BlockImporter() {} + + /** + * Imports the blocks, headers, and transaction receipts from the file found at the supplied path + * + * @param controller The BesuController + * @param path The path + * @throws IOException IOException + * @throws ExecutionException ExecutionException + * @throws InterruptedException InterruptedException + * @throws TimeoutException TimeoutException + */ + public void importBlocks(final BesuController controller, final Path path) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + final ProtocolSchedule protocolSchedule = controller.getProtocolSchedule(); + final BlockHeaderFunctions blockHeaderFunctions = + ScheduleBasedBlockHeaderFunctions.create(protocolSchedule); + final ProtocolContext context = controller.getProtocolContext(); + + Era1Reader reader = new Era1Reader(new SnappyFactory()); + + final List> headersFutures = new ArrayList<>(ERA1_BLOCK_COUNT_MAX); + final List> bodiesFutures = new ArrayList<>(ERA1_BLOCK_COUNT_MAX); + final List>> receiptsFutures = + new ArrayList<>(ERA1_BLOCK_COUNT_MAX); + reader.read( + new FileInputStream(path.toFile()), + new Era1ReaderListener() { + + @Override + public void handleExecutionBlockHeader( + final Era1ExecutionBlockHeader executionBlockHeader) { + headersFutures.add( + CompletableFuture.supplyAsync( + () -> + BlockHeader.readFrom( + new BytesValueRLPInput( + Bytes.wrap(executionBlockHeader.header()), false), + blockHeaderFunctions))); + } + + @Override + public void handleExecutionBlockBody(final Era1ExecutionBlockBody executionBlockBody) { + bodiesFutures.add( + CompletableFuture.supplyAsync( + () -> + BlockBody.readWrappedBodyFrom( + new BytesValueRLPInput(Bytes.wrap(executionBlockBody.block()), false), + blockHeaderFunctions, + true))); + } + + @Override + public void handleExecutionBlockReceipts( + final Era1ExecutionBlockReceipts executionBlockReceipts) { + receiptsFutures.add( + CompletableFuture.supplyAsync( + () -> { + RLPInput input = + new BytesValueRLPInput( + Bytes.wrap(executionBlockReceipts.receipts()), false); + final List receiptsForBlock = new ArrayList<>(); + input.readList((in) -> receiptsForBlock.add(TransactionReceipt.readFrom(in))); + return receiptsForBlock; + })); + } + + @Override + public void handleBlockIndex(final Era1BlockIndex blockIndex) { + // not really necessary, do nothing + } + }); + + LOG.info("Read {} blocks, now importing", headersFutures.size()); + + Block block = null; + for (int i = 0; i < headersFutures.size(); i++) { + BlockHeader blockHeader = headersFutures.get(i).get(10, TimeUnit.SECONDS); + BlockImporter blockImporter = + protocolSchedule.getByBlockHeader(blockHeader).getBlockImporter(); + block = new Block(blockHeader, bodiesFutures.get(i).get(10, TimeUnit.SECONDS)); + + BlockImportResult importResult = + blockImporter.importBlockForSyncing( + context, + block, + receiptsFutures.get(i).get(10, TimeUnit.SECONDS), + HeaderValidationMode.NONE, + HeaderValidationMode.NONE, + BodyValidationMode.NONE, + false); + if (importResult.getStatus() != BlockImportResult.BlockImportStatus.IMPORTED) { + LOG.warn( + "Failed to import block {} due to {}", + blockHeader.getNumber(), + importResult.getStatus()); + } else if (i % IMPORT_COUNT_FOR_LOG_UPDATE == 0) { + LOG.info("{}/{} blocks imported", i, headersFutures.size()); + } + } + LOG.info("Done importing {} blocks", headersFutures.size()); + } + + @Override + public void close() throws IOException {} +} diff --git a/besu/src/main/java/org/hyperledger/besu/chainimport/RlpBlockImporter.java b/besu/src/main/java/org/hyperledger/besu/chainimport/RlpBlockImporter.java index d006f4201..febccbe1c 100644 --- a/besu/src/main/java/org/hyperledger/besu/chainimport/RlpBlockImporter.java +++ b/besu/src/main/java/org/hyperledger/besu/chainimport/RlpBlockImporter.java @@ -267,14 +267,19 @@ public class RlpBlockImporter implements Closeable { private BlockHeader lookupPreviousHeader( final MutableBlockchain blockchain, final BlockHeader header) { - return blockchain - .getBlockHeader(header.getParentHash()) - .orElseThrow( - () -> - new IllegalStateException( - String.format( - "Block %s does not connect to the existing chain. Current chain head %s", - header.getNumber(), blockchain.getChainHeadBlockNumber()))); + try { + return blockchain + .getBlockHeader(header.getParentHash()) + .orElseThrow( + () -> + new IllegalStateException( + String.format( + "Block %s does not connect to the existing chain. Current chain head %s", + header.getNumber(), blockchain.getChainHeadBlockNumber()))); + } catch (IllegalStateException e) { + LOG.info("Block {} does not connect to the existing chain.", header.getNumber()); + } + return null; } @Override diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index b628e420c..87312489f 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -26,15 +26,16 @@ import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPENDENCY_WARNING_ import static org.hyperledger.besu.cli.util.CommandLineUtils.isOptionSet; import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH; import static org.hyperledger.besu.ethereum.api.jsonrpc.authentication.EngineAuthService.EPHEMERAL_JWT_FILE; -import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; import org.hyperledger.besu.chainexport.RlpBlockExporter; +import org.hyperledger.besu.chainimport.Era1BlockImporter; import org.hyperledger.besu.chainimport.JsonBlockImporter; import org.hyperledger.besu.chainimport.RlpBlockImporter; import org.hyperledger.besu.cli.config.EthNetworkConfig; +import org.hyperledger.besu.cli.config.NativeRequirement.NativeRequirementResult; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.cli.config.ProfilesCompletionCandidates; import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; @@ -68,7 +69,7 @@ import org.hyperledger.besu.cli.options.RpcWebsocketOptions; import org.hyperledger.besu.cli.options.SynchronizerOptions; import org.hyperledger.besu.cli.options.TransactionPoolOptions; import org.hyperledger.besu.cli.options.storage.DataStorageOptions; -import org.hyperledger.besu.cli.options.storage.DiffBasedSubStorageOptions; +import org.hyperledger.besu.cli.options.storage.PathBasedExtraStorageOptions; import org.hyperledger.besu.cli.options.unstable.QBFTOptions; import org.hyperledger.besu.cli.presynctasks.PreSynchronizationTaskRunner; import org.hyperledger.besu.cli.presynctasks.PrivateDatabaseMigrationPreSyncTask; @@ -102,7 +103,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.api.ApiConfiguration; import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration; import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration; @@ -121,7 +121,6 @@ import org.hyperledger.besu.ethereum.eth.sync.SyncMode; import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration; -import org.hyperledger.besu.ethereum.mainnet.FrontierTargetingGasLimitCalculator; import org.hyperledger.besu.ethereum.p2p.config.DiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeDnsConfiguration; @@ -136,9 +135,9 @@ import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider; import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.DiffBasedSubStorageConfiguration; import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration; -import org.hyperledger.besu.ethereum.worldstate.ImmutableDiffBasedSubStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.ImmutablePathBasedExtraStorageConfiguration; +import org.hyperledger.besu.ethereum.worldstate.PathBasedExtraStorageConfiguration; import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract; import org.hyperledger.besu.evm.precompile.BigIntegerModularExponentiationPrecompiledContract; import org.hyperledger.besu.evm.precompile.KZGPointEvalPrecompiledContract; @@ -279,7 +278,6 @@ import picocli.CommandLine.ParameterException; "%nMore info and other profiles at https://besu.hyperledger.org%n" }) public class BesuCommand implements DefaultCommandValues, Runnable { - @SuppressWarnings("PrivateStaticFinalLoggers") // non-static for testing private final Logger logger; @@ -288,6 +286,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { private final Supplier rlpBlockImporter; private final Function jsonBlockImporterFactory; + private final Supplier era1BlockImporter; private final Function rlpBlockExporterFactory; // Unstable CLI options @@ -694,7 +693,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @CommandLine.Option( names = {"--cache-last-blocks"}, description = "Specifies the number of last blocks to cache (default: ${DEFAULT-VALUE})") - private final Integer numberOfblocksToCache = 0; + private final Integer numberOfBlocksToCache = 0; // Plugins Configuration Option Group @CommandLine.ArgGroup(validate = false) @@ -723,6 +722,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * * @param rlpBlockImporter RlpBlockImporter supplier * @param jsonBlockImporterFactory instance of {@code Function} + * @param era1BlockImporter Era1BlockImporter supplier * @param rlpBlockExporterFactory instance of {@code Function} * @param runnerBuilder instance of RunnerBuilder * @param controllerBuilder instance of BesuController.Builder @@ -733,6 +733,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { public BesuCommand( final Supplier rlpBlockImporter, final Function jsonBlockImporterFactory, + final Supplier era1BlockImporter, final Function rlpBlockExporterFactory, final RunnerBuilder runnerBuilder, final BesuController.Builder controllerBuilder, @@ -742,6 +743,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this( rlpBlockImporter, jsonBlockImporterFactory, + era1BlockImporter, rlpBlockExporterFactory, runnerBuilder, controllerBuilder, @@ -764,6 +766,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { * * @param rlpBlockImporter RlpBlockImporter supplier * @param jsonBlockImporterFactory instance of {@code Function} + * @param era1BlockImporter Era1BlockImporter supplier * @param rlpBlockExporterFactory instance of {@code Function} * @param runnerBuilder instance of RunnerBuilder * @param controllerBuilder instance of BesuController.Builder @@ -784,6 +787,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { protected BesuCommand( final Supplier rlpBlockImporter, final Function jsonBlockImporterFactory, + final Supplier era1BlockImporter, final Function rlpBlockExporterFactory, final RunnerBuilder runnerBuilder, final BesuController.Builder controllerBuilder, @@ -802,8 +806,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this.logger = commandLogger; this.rlpBlockImporter = rlpBlockImporter; - this.rlpBlockExporterFactory = rlpBlockExporterFactory; this.jsonBlockImporterFactory = jsonBlockImporterFactory; + this.era1BlockImporter = era1BlockImporter; + this.rlpBlockExporterFactory = rlpBlockExporterFactory; this.runnerBuilder = runnerBuilder; this.controllerBuilder = controllerBuilder; this.besuPluginContext = besuPluginContext; @@ -970,7 +975,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { // explicitly enabled, perform compatibility check VersionMetadata.versionCompatibilityChecks(versionCompatibilityProtection, dataDir()); - configureNativeLibs(); + configureNativeLibs(Optional.ofNullable(network)); besuController = buildController(); besuPluginContext.beforeExternalServices(); @@ -990,7 +995,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { runner.awaitStop(); } catch (final Exception e) { - logger.error("Failed to start Besu", e); + logger.error("Failed to start Besu: {}", e.getMessage()); + logger.debug("Startup failure cause", e); throw new ParameterException(this.commandLine, e.getMessage(), e); } } @@ -1104,6 +1110,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { new BlocksSubCommand( rlpBlockImporter, jsonBlockImporterFactory, + era1BlockImporter, rlpBlockExporterFactory, commandLine.getOut())); commandLine.addSubcommand( @@ -1383,7 +1390,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { return Optional.ofNullable(colorEnabled); } - private void configureNativeLibs() { + @VisibleForTesting + void configureNativeLibs(final Optional configuredNetwork) { if (unstableNativeLibraryOptions.getNativeAltbn128() && AbstractAltBnPrecompiledContract.maybeEnableNative()) { logger.info("Using the native implementation of alt bn128"); @@ -1430,6 +1438,37 @@ public class BesuCommand implements DefaultCommandValues, Runnable { this.commandLine, "--kzg-trusted-setup can only be specified on networks with data blobs enabled"); } + // assert required native libraries have been loaded + if (genesisFile == null && configuredNetwork.isPresent()) { + checkRequiredNativeLibraries(configuredNetwork.get()); + } + } + + @VisibleForTesting + void checkRequiredNativeLibraries(final NetworkName configuredNetwork) { + if (configuredNetwork == null) { + return; + } + + // assert native library requirements for named networks: + List failedNativeReqs = + configuredNetwork.getNativeRequirements().stream().filter(r -> !r.present()).toList(); + + if (!failedNativeReqs.isEmpty()) { + String failures = + failedNativeReqs.stream() + .map(r -> r.libname() + " " + r.errorMessage()) + .collect(Collectors.joining("\n\t")); + throw new UnsupportedOperationException( + String.format( + "Failed to load required native libraries for network %s. " + + "Verify whether your platform %s and arch %s are supported by besu. " + + "Failures loading: \n%s", + configuredNetwork.name(), + System.getProperty("os.name"), + System.getProperty("os.arch"), + failures)); + } } private void validateOptions() { @@ -1447,27 +1486,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable { validateTransactionPoolOptions(); validateDataStorageOptions(); validateGraphQlOptions(); - validateConsensusSyncCompatibilityOptions(); validatePluginOptions(); } - private void validateConsensusSyncCompatibilityOptions() { - // snap and checkpoint are experimental for BFT - if ((genesisConfigOptionsSupplier.get().isIbftLegacy() - || genesisConfigOptionsSupplier.get().isIbft2() - || genesisConfigOptionsSupplier.get().isQbft()) - && !unstableSynchronizerOptions.isSnapSyncBftEnabled()) { - final String errorSuffix = "can't be used with BFT networks"; - if (SyncMode.CHECKPOINT.equals(syncMode)) { - throw new ParameterException( - commandLine, String.format("%s %s", "Checkpoint sync", errorSuffix)); - } - if (syncMode == SyncMode.SNAP) { - throw new ParameterException(commandLine, String.format("%s %s", "Snap sync", errorSuffix)); - } - } - } - private void validatePluginOptions() { pluginsConfigurationOptions.validate(commandLine); } @@ -1509,22 +1530,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { @SuppressWarnings("ConstantConditions") private void validateNatParams() { - if (natMethod.equals(NatMethod.KUBERNETES)) { - logger.warn("Kubernetes NAT method is deprecated. Please use Docker or UPNP"); - } - if (!unstableNatOptions.getNatManagerServiceName().equals(DEFAULT_BESU_SERVICE_NAME_FILTER)) { - logger.warn( - "`--Xnat-kube-service-name` and Kubernetes NAT method are deprecated. Please use Docker or UPNP"); - } - if (!(natMethod.equals(NatMethod.AUTO) || natMethod.equals(NatMethod.KUBERNETES)) - && !unstableNatOptions - .getNatManagerServiceName() - .equals(DEFAULT_BESU_SERVICE_NAME_FILTER)) { - throw new ParameterException( - this.commandLine, - "The `--Xnat-kube-service-name` parameter is only used in kubernetes mode. Either remove --Xnat-kube-service-name" - + " or select the KUBERNETES mode (via --nat--method=KUBERNETES)"); - } if (natMethod.equals(NatMethod.AUTO) && !unstableNatOptions.getNatMethodFallbackEnabled()) { throw new ParameterException( this.commandLine, @@ -1681,7 +1686,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { "--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true", dataStorageOptions .toDomainObject() - .getDiffBasedSubStorageConfiguration() + .getPathBasedExtraStorageConfiguration() .getUnstable() .getFullFlatDbEnabled(), asList( @@ -1822,10 +1827,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .isRevertReasonEnabled(isRevertReasonEnabled) .storageProvider(storageProvider) .isEarlyRoundChangeEnabled(unstableQbftOptions.isEarlyRoundChangeEnabled()) - .gasLimitCalculator( - miningParametersSupplier.get().getTargetGasLimit().isPresent() - ? new FrontierTargetingGasLimitCalculator() - : GasLimitCalculator.constant()) .requiredBlocks(requiredBlocks) .reorgLoggingThreshold(reorgLoggingThreshold) .evmConfiguration(unstableEvmOptions.toDomainObject()) @@ -1833,13 +1834,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .maxRemotelyInitiatedPeers(maxRemoteInitiatedPeers) .randomPeerPriority(p2PDiscoveryOptions.randomPeerPriority) .chainPruningConfiguration(unstableChainPruningOptions.toDomainObject()) - .cacheLastBlocks(numberOfblocksToCache) + .cacheLastBlocks(numberOfBlocksToCache) .genesisStateHashCacheEnabled(genesisStateHashCacheEnabled) .apiConfiguration(apiConfigurationSupplier.get()) .besuComponent(besuComponent); if (DataStorageFormat.BONSAI.equals(getDataStorageConfiguration().getDataStorageFormat())) { - final DiffBasedSubStorageConfiguration subStorageConfiguration = - getDataStorageConfiguration().getDiffBasedSubStorageConfiguration(); + final PathBasedExtraStorageConfiguration subStorageConfiguration = + getDataStorageConfiguration().getPathBasedExtraStorageConfiguration(); besuControllerBuilder.isParallelTxProcessingEnabled( subStorageConfiguration.getUnstable().isParallelTxProcessingEnabled()); } @@ -2156,13 +2157,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable { getGenesisBlockPeriodSeconds(genesisConfigOptionsSupplier.get()) .ifPresent(miningParameters::setBlockPeriodSeconds); initMiningParametersMetrics(miningParameters); - // if network = holesky, set targetGasLimit to 36,000,000 unless otherwise specified - if (miningParameters.getTargetGasLimit().isEmpty() && NetworkName.HOLESKY.equals(network)) { - logger.info( - "Setting target gas limit for holesky: {}", - MiningConfiguration.DEFAULT_TARGET_GAS_LIMIT_HOLESKY); - miningParameters.setTargetGasLimit(MiningConfiguration.DEFAULT_TARGET_GAS_LIMIT_HOLESKY); - } + return miningParameters; } @@ -2183,30 +2178,30 @@ public class BesuCommand implements DefaultCommandValues, Runnable { if (SyncMode.FULL.equals(getDefaultSyncModeIfNotSet()) && DataStorageFormat.BONSAI.equals(dataStorageConfiguration.getDataStorageFormat())) { - final DiffBasedSubStorageConfiguration diffBasedSubStorageConfiguration = - dataStorageConfiguration.getDiffBasedSubStorageConfiguration(); - if (diffBasedSubStorageConfiguration.getLimitTrieLogsEnabled()) { + final PathBasedExtraStorageConfiguration pathBasedExtraStorageConfiguration = + dataStorageConfiguration.getPathBasedExtraStorageConfiguration(); + if (pathBasedExtraStorageConfiguration.getLimitTrieLogsEnabled()) { if (CommandLineUtils.isOptionSet( - commandLine, DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED)) { + commandLine, PathBasedExtraStorageOptions.LIMIT_TRIE_LOGS_ENABLED)) { throw new ParameterException( commandLine, String.format( "Cannot enable %s with --sync-mode=%s and --data-storage-format=%s. You must set %s or use a different sync-mode", - DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED, + PathBasedExtraStorageOptions.LIMIT_TRIE_LOGS_ENABLED, SyncMode.FULL, DataStorageFormat.BONSAI, - DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED + "=false")); + PathBasedExtraStorageOptions.LIMIT_TRIE_LOGS_ENABLED + "=false")); } dataStorageConfiguration = ImmutableDataStorageConfiguration.copyOf(dataStorageConfiguration) - .withDiffBasedSubStorageConfiguration( - ImmutableDiffBasedSubStorageConfiguration.copyOf( - dataStorageConfiguration.getDiffBasedSubStorageConfiguration()) + .withPathBasedExtraStorageConfiguration( + ImmutablePathBasedExtraStorageConfiguration.copyOf( + dataStorageConfiguration.getPathBasedExtraStorageConfiguration()) .withLimitTrieLogsEnabled(false)); logger.warn( "Forcing {}, since it cannot be enabled with --sync-mode={} and --data-storage-format={}.", - DiffBasedSubStorageOptions.LIMIT_TRIE_LOGS_ENABLED + "=false", + PathBasedExtraStorageOptions.LIMIT_TRIE_LOGS_ENABLED + "=false", SyncMode.FULL, DataStorageFormat.BONSAI); } @@ -2264,7 +2259,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { .besuController(controller) .p2pEnabled(p2pEnabled) .natMethod(natMethod) - .natManagerServiceName(unstableNatOptions.getNatManagerServiceName()) .natMethodFallbackEnabled(unstableNatOptions.getNatMethodFallbackEnabled()) .discoveryEnabled(peerDiscoveryEnabled) .ethNetworkConfig(ethNetworkConfig) @@ -2774,8 +2768,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } if (DataStorageFormat.BONSAI.equals(getDataStorageConfiguration().getDataStorageFormat())) { - final DiffBasedSubStorageConfiguration subStorageConfiguration = - getDataStorageConfiguration().getDiffBasedSubStorageConfiguration(); + final PathBasedExtraStorageConfiguration subStorageConfiguration = + getDataStorageConfiguration().getPathBasedExtraStorageConfiguration(); if (subStorageConfiguration.getLimitTrieLogsEnabled()) { builder.setLimitTrieLogsEnabled(); builder.setTrieLogRetentionLimit(subStorageConfiguration.getMaxLayersToLoad()); @@ -2784,7 +2778,6 @@ public class BesuCommand implements DefaultCommandValues, Runnable { } builder.setSnapServerEnabled(this.unstableSynchronizerOptions.isSnapsyncServerEnabled()); - builder.setSnapSyncBftEnabled(this.unstableSynchronizerOptions.isSnapSyncBftEnabled()); builder.setTxPoolImplementation(buildTransactionPoolConfiguration().getTxPoolImplementation()); builder.setWorldStateUpdateMode(unstableEvmOptions.toDomainObject().worldUpdaterMode()); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java b/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java index 9e69cb608..f6f31edbe 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/ConfigurationOverviewBuilder.java @@ -57,7 +57,6 @@ public class ConfigurationOverviewBuilder { private long trieLogRetentionLimit = 0; private Integer trieLogsPruningWindowSize = null; private boolean isSnapServerEnabled = false; - private boolean isSnapSyncBftEnabled = false; private TransactionPoolConfiguration.Implementation txPoolImplementation; private EvmConfiguration.WorldUpdaterMode worldStateUpdateMode; private Map environment; @@ -246,17 +245,6 @@ public class ConfigurationOverviewBuilder { return this; } - /** - * Sets snap sync BFT enabled/disabled - * - * @param snapSyncBftEnabled bool to indicate if snap sync for BFT is enabled - * @return the builder - */ - public ConfigurationOverviewBuilder setSnapSyncBftEnabled(final boolean snapSyncBftEnabled) { - isSnapSyncBftEnabled = snapSyncBftEnabled; - return this; - } - /** * Sets trie logs pruning window size * @@ -386,10 +374,6 @@ public class ConfigurationOverviewBuilder { lines.add("Experimental Snap Sync server enabled"); } - if (isSnapSyncBftEnabled) { - lines.add("Experimental Snap Sync for BFT enabled"); - } - if (isLimitTrieLogsEnabled) { final StringBuilder trieLogPruningString = new StringBuilder(); trieLogPruningString diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NativeRequirement.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NativeRequirement.java new file mode 100644 index 000000000..ba3ed2f5e --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NativeRequirement.java @@ -0,0 +1,69 @@ +/* + * Copyright contributors to Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.cli.config; + +import org.hyperledger.besu.crypto.SECP256K1; +import org.hyperledger.besu.evm.precompile.AltBN128PairingPrecompiledContract; +import org.hyperledger.besu.evm.precompile.BLS12PairingPrecompiledContract; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +/** Encapsulates the native library requirements of given networks. */ +public interface NativeRequirement { + + /** + * Record type to encapsulate the result of native library loading + * + * @param present boolean indicating library loading present or failure. + * @param libname string indicating the required library name. + * @param errorMessage Optional error message suitable to log. + */ + record NativeRequirementResult(Boolean present, String libname, Optional errorMessage) {} + + /** Ethereum mainnet-like performance requirements: */ + Supplier> MAINNET = + () -> { + List requirements = new ArrayList<>(); + var secp256k1 = new SECP256K1(); + requirements.add( + new NativeRequirementResult( + secp256k1.maybeEnableNative(), + "secp256k1", + secp256k1.maybeEnableNative() + ? Optional.empty() + : Optional.of("secp256k1: Native secp256k1 failed to load"))); + + requirements.add( + new NativeRequirementResult( + AltBN128PairingPrecompiledContract.isNative(), + "alt_bn128", + AltBN128PairingPrecompiledContract.isNative() + ? Optional.empty() + : Optional.of("alt_bn128: EC native library failed to load"))); + + requirements.add( + new NativeRequirementResult( + BLS12PairingPrecompiledContract.isAvailable(), + "bls12-381", + BLS12PairingPrecompiledContract.isAvailable() + ? Optional.empty() + : Optional.of("bls12-381: EC native library failed to load"))); + + return requirements; + }; +} diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index 35d349657..0af6c273d 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -14,29 +14,34 @@ */ package org.hyperledger.besu.cli.config; +import org.hyperledger.besu.cli.config.NativeRequirement.NativeRequirementResult; + import java.math.BigInteger; +import java.util.Collections; +import java.util.List; import java.util.Locale; import java.util.Optional; +import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; /** The enum Network name. */ public enum NetworkName { /** Mainnet network name. */ - MAINNET("/mainnet.json", BigInteger.valueOf(1)), + MAINNET("/mainnet.json", BigInteger.valueOf(1), true, NativeRequirement.MAINNET), /** Sepolia network name. */ - SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111)), + SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111), true, NativeRequirement.MAINNET), /** Holešky network name. */ - HOLESKY("/holesky.json", BigInteger.valueOf(17000)), - /** LUKSO mainnet network name. */ - LUKSO("/lukso.json", BigInteger.valueOf(42)), - + HOLESKY("/holesky.json", BigInteger.valueOf(17000), true, NativeRequirement.MAINNET), + /** Hoodi network name. */ + HOODI("/hoodi.json", BigInteger.valueOf(560048), true, NativeRequirement.MAINNET), /** * EPHEMERY network name. The actual networkId used is calculated based on this default value and * the current time. https://ephemery.dev/ */ - EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), - + EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135), true, NativeRequirement.MAINNET), + /** LUKSO mainnet network name. */ + LUKSO("/lukso.json", BigInteger.valueOf(42)), /** Dev network name. */ DEV("/dev.json", BigInteger.valueOf(2018), false), /** Future EIPs network name. */ @@ -56,17 +61,27 @@ public enum NetworkName { private final BigInteger networkId; private final boolean canSnapSync; private final String deprecationDate; + private final Supplier> nativeRequirements; NetworkName(final String genesisFile, final BigInteger networkId) { this(genesisFile, networkId, true); } NetworkName(final String genesisFile, final BigInteger networkId, final boolean canSnapSync) { + this(genesisFile, networkId, canSnapSync, Collections::emptyList); + } + + NetworkName( + final String genesisFile, + final BigInteger networkId, + final boolean canSnapSync, + final Supplier> nativeRequirements) { this.genesisFile = genesisFile; this.networkId = networkId; this.canSnapSync = canSnapSync; // no deprecations planned this.deprecationDate = null; + this.nativeRequirements = nativeRequirements; } /** @@ -122,4 +137,13 @@ public enum NetworkName { public Optional getDeprecationDate() { return Optional.ofNullable(deprecationDate); } + + /** + * Gets native requirements for this network. + * + * @return result of native library requirements defined for this network, as a list. + */ + public List getNativeRequirements() { + return this.nativeRequirements.get(); + } } diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/NatOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/NatOptions.java index 11e8051d0..7407e6554 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/NatOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/NatOptions.java @@ -14,21 +14,11 @@ */ package org.hyperledger.besu.cli.options; -import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; - import picocli.CommandLine; /** The Nat Cli options. */ public class NatOptions { - @SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings. - @CommandLine.Option( - hidden = true, - names = {"--Xnat-kube-service-name"}, - description = - "Specify the name of the service that will be used by the nat manager in Kubernetes. (default: ${DEFAULT-VALUE})") - private String natManagerServiceName = DEFAULT_BESU_SERVICE_NAME_FILTER; - @CommandLine.Option( hidden = true, names = {"--Xnat-method-fallback-enabled"}, @@ -49,15 +39,6 @@ public class NatOptions { return new NatOptions(); } - /** - * Gets nat manager service name. - * - * @return the nat manager service name - */ - public String getNatManagerServiceName() { - return natManagerServiceName; - } - /** * Whether nat method fallback is enabled. * diff --git a/besu/src/main/java/org/hyperledger/besu/cli/options/SynchronizerOptions.java b/besu/src/main/java/org/hyperledger/besu/cli/options/SynchronizerOptions.java index 99db983d9..d6a1edeb8 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/options/SynchronizerOptions.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/options/SynchronizerOptions.java @@ -306,12 +306,15 @@ public class SynchronizerOptions implements CLIOptions