From 40cfc800f7e311b1adae9a59f7f5d220ec05a84f Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 9 May 2024 10:34:14 +0200 Subject: [PATCH] New RPC methods `miner_setExtraData` and `miner_getExtraData` (#7078) * New RPC methods to set and get block extra data Signed-off-by: Fabio Di Fabio * Remove redundant methods to set the extra data Signed-off-by: Fabio Di Fabio * miner_getExtraData unit tests Signed-off-by: Fabio Di Fabio * Add CHANGELOG Signed-off-by: Fabio Di Fabio * Apply suggestions from code review Co-authored-by: Sally MacFarlane Signed-off-by: Fabio Di Fabio --------- Signed-off-by: Fabio Di Fabio Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 1 + .../besu/chainimport/JsonBlockImporter.java | 2 +- .../CliqueMinerExecutorTest.java | 2 +- .../common/MigratingMiningCoordinator.java | 6 - .../blockcreation/BftBlockCreatorFactory.java | 10 -- .../blockcreation/BftMiningCoordinator.java | 6 - .../MigratingMiningCoordinatorTest.java | 6 - .../BftMiningCoordinatorTest.java | 8 -- .../merge/blockcreation/MergeCoordinator.java | 6 - .../blockcreation/TransitionCoordinator.java | 7 -- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 2 + .../methods/miner/MinerGetExtraData.java | 41 +++++++ .../methods/miner/MinerSetExtraData.java | 69 +++++++++++ .../jsonrpc/methods/MinerJsonRpcMethods.java | 6 +- .../methods/miner/MinerGetExtraDataTest.java | 62 ++++++++++ .../methods/miner/MinerSetExtraDataTest.java | 109 ++++++++++++++++++ .../blockcreation/AbstractMinerExecutor.java | 5 - .../AbstractMiningCoordinator.java | 7 -- .../blockcreation/MiningCoordinator.java | 4 - .../blockcreation/NoopMiningCoordinator.java | 5 - 20 files changed, 291 insertions(+), 73 deletions(-) create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraData.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraDataTest.java create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc5076594f..64dcf2b69b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ - Update Gradle to 7.6.4 [#7030](https://github.com/hyperledger/besu/pull/7030) - Remove deprecated Goerli testnet [#7049](https://github.com/hyperledger/besu/pull/7049) - Default bonsai to use full-flat db and code-storage-by-code-hash [#6984](https://github.com/hyperledger/besu/pull/6894) +- New RPC methods miner_setExtraData and miner_getExtraData [#7078](https://github.com/hyperledger/besu/pull/7078) ### Bug fixes - Fix txpool dump/restore race condition [#6665](https://github.com/hyperledger/besu/pull/6665) diff --git a/besu/src/main/java/org/hyperledger/besu/chainimport/JsonBlockImporter.java b/besu/src/main/java/org/hyperledger/besu/chainimport/JsonBlockImporter.java index 13c239d6d88..efd35d40ff4 100644 --- a/besu/src/main/java/org/hyperledger/besu/chainimport/JsonBlockImporter.java +++ b/besu/src/main/java/org/hyperledger/besu/chainimport/JsonBlockImporter.java @@ -136,7 +136,7 @@ private void setOptionalFields( // For simplicity only set these for PoW consensus algorithms. // Other consensus algorithms use these fields for special purposes or ignore them. miner.setCoinbase(blockData.getCoinbase().orElse(Address.ZERO)); - miner.setExtraData(blockData.getExtraData().orElse(Bytes.EMPTY)); + controller.getMiningParameters().setExtraData(blockData.getExtraData().orElse(Bytes.EMPTY)); } else if (blockData.getCoinbase().isPresent() || blockData.getExtraData().isPresent()) { // Fail if these fields are set for non-ethash chains final Stream.Builder fields = Stream.builder(); diff --git a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java index 9ff2b713ce8..bb69aaff483 100644 --- a/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java +++ b/consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java @@ -200,7 +200,7 @@ public void shouldUseLatestVanityData() { null, ethScheduler); - executor.setExtraData(modifiedVanityData); + miningParameters.setExtraData(modifiedVanityData); final Bytes extraDataBytes = executor.calculateExtraData(blockHeaderBuilder.buildHeader()); final CliqueExtraData cliqueExtraData = diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinator.java index 8b69ca11895..6450a108fd9 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinator.java @@ -29,7 +29,6 @@ import java.util.concurrent.CompletableFuture; import com.google.common.annotations.VisibleForTesting; -import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -108,11 +107,6 @@ public Wei getMinPriorityFeePerGas() { return activeMiningCoordinator.getMinPriorityFeePerGas(); } - @Override - public void setExtraData(final Bytes extraData) { - activeMiningCoordinator.setExtraData(extraData); - } - @Override public Optional
getCoinbase() { return activeMiningCoordinator.getCoinbase(); diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java index 3da85c616fa..64f7eef27dd 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java @@ -124,16 +124,6 @@ public BlockCreator create(final BlockHeader parentHeader, final int round) { ethScheduler); } - /** - * Sets extra data. - * - * @param extraData the extra data - */ - public void setExtraData(final Bytes extraData) { - - miningParameters.setExtraData(extraData.copy()); - } - /** * Sets min transaction gas price. * diff --git a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java index e38b1548b13..83cd61beb31 100644 --- a/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java +++ b/consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java @@ -33,7 +33,6 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; -import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -154,11 +153,6 @@ public Wei getMinPriorityFeePerGas() { return blockCreatorFactory.getMinPriorityFeePerGas(); } - @Override - public void setExtraData(final Bytes extraData) { - blockCreatorFactory.setExtraData(extraData); - } - @Override public Optional
getCoinbase() { return Optional.of(blockCreatorFactory.getLocalAddress()); diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinatorTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinatorTest.java index f4d200a9c0b..640691f0d3e 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinatorTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinatorTest.java @@ -40,7 +40,6 @@ import java.util.List; import java.util.function.Consumer; -import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -162,11 +161,6 @@ public void delegatesToActiveMiningCoordinator() { coordinator2, coordinator1); - verifyDelegation( - c -> c.setExtraData(Bytes.EMPTY), GENESIS_BLOCK_NUMBER, coordinator1, coordinator2); - verifyDelegation( - c -> c.setExtraData(Bytes.EMPTY), MIGRATION_BLOCK_NUMBER, coordinator2, coordinator1); - verifyDelegation( MiningCoordinator::getCoinbase, GENESIS_BLOCK_NUMBER, coordinator1, coordinator2); verifyDelegation( diff --git a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java index dda38b45af1..f2618c1abd1 100644 --- a/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java +++ b/consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java @@ -35,7 +35,6 @@ import java.util.Collections; import java.util.concurrent.TimeUnit; -import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -89,13 +88,6 @@ public void getsMinTransactionGasPrice() { assertThat(bftMiningCoordinator.getMinTransactionGasPrice()).isEqualTo(minGasPrice); } - @Test - public void setsTheExtraData() { - final Bytes extraData = Bytes.fromHexStringLenient("0x1234"); - bftMiningCoordinator.setExtraData(extraData); - verify(bftBlockCreatorFactory).setExtraData(extraData); - } - @Test public void addsNewChainHeadEventWhenNewCanonicalHeadBlockEventReceived() throws Exception { BlockAddedEvent headAdvancement = diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java index b58c3605774..68c5a16599a 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java @@ -61,7 +61,6 @@ import java.util.function.Supplier; import com.google.common.annotations.VisibleForTesting; -import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -225,11 +224,6 @@ public Wei getMinPriorityFeePerGas() { return miningParameters.getMinPriorityFeePerGas(); } - @Override - public void setExtraData(final Bytes extraData) { - this.miningParameters.setExtraData(extraData); - } - @Override public Optional
getCoinbase() { return miningParameters.getCoinbase(); diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/TransitionCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/TransitionCoordinator.java index 4f3ac3f0c70..681c6f334bc 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/TransitionCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/TransitionCoordinator.java @@ -33,7 +33,6 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; -import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; /** The Transition coordinator. */ @@ -107,12 +106,6 @@ public Wei getMinPriorityFeePerGas() { return dispatchFunctionAccordingToMergeState(MiningCoordinator::getMinPriorityFeePerGas); } - @Override - public void setExtraData(final Bytes extraData) { - miningCoordinator.setExtraData(extraData); - mergeCoordinator.setExtraData(extraData); - } - @Override public Optional
getCoinbase() { return dispatchFunctionAccordingToMergeState(MiningCoordinator::getCoinbase); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index 7b528ebd452..36e4ff8b8a5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -159,6 +159,8 @@ public enum RpcMethod { MINER_SET_MIN_PRIORITY_FEE("miner_setMinPriorityFee"), MINER_GET_MIN_GAS_PRICE("miner_getMinGasPrice"), MINER_SET_MIN_GAS_PRICE("miner_setMinGasPrice"), + MINER_GET_EXTRA_DATA("miner_getExtraData"), + MINER_SET_EXTRA_DATA("miner_setExtraData"), NET_ENODE("net_enode"), NET_LISTENING("net_listening"), NET_PEER_COUNT("net_peerCount"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraData.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraData.java new file mode 100644 index 00000000000..b433ed0b6af --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraData.java @@ -0,0 +1,41 @@ +/* + * 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.ethereum.api.jsonrpc.internal.methods.miner; + +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.core.MiningParameters; + +public class MinerGetExtraData implements JsonRpcMethod { + private final MiningParameters miningParameters; + + public MinerGetExtraData(final MiningParameters miningParameters) { + this.miningParameters = miningParameters; + } + + @Override + public String getName() { + return RpcMethod.MINER_GET_EXTRA_DATA.getMethodName(); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + return new JsonRpcSuccessResponse( + requestContext.getRequest().getId(), miningParameters.getExtraData().toShortHexString()); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java new file mode 100644 index 00000000000..f82d30684af --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java @@ -0,0 +1,69 @@ +/* + * 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.ethereum.api.jsonrpc.internal.methods.miner; + +import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.ethereum.core.MiningParameters; + +import java.nio.charset.StandardCharsets; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MinerSetExtraData implements JsonRpcMethod { + private static final Logger LOG = LoggerFactory.getLogger(MinerSetExtraData.class); + + private final MiningParameters miningParameters; + + public MinerSetExtraData(final MiningParameters miningParameters) { + this.miningParameters = miningParameters; + } + + @Override + public String getName() { + return RpcMethod.MINER_SET_EXTRA_DATA.getMethodName(); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + try { + final String rawParam = requestContext.getRequiredParameter(0, String.class); + Bytes32.fromHexStringLenient( + rawParam); // done for validation, we want a hex string and max 32 bytes + final var extraData = Bytes.fromHexStringLenient(rawParam); + miningParameters.setExtraData(extraData); + LOG.atDebug() + .setMessage("set extra data, raw=[{}] parsed=[{}], UTF-8=[{}]") + .addArgument(rawParam) + .addArgument(extraData::toHexString) + .addArgument(() -> new String(extraData.toArray(), StandardCharsets.UTF_8)) + .log(); + return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), true); + } catch (final IllegalArgumentException invalidJsonRpcParameters) { + return new JsonRpcErrorResponse( + requestContext.getRequest().getId(), + new JsonRpcError(RpcErrorType.INVALID_PARAMS, invalidJsonRpcParameters.getMessage())); + } + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/MinerJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/MinerJsonRpcMethods.java index 8afaf6a5873..c799c23305b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/MinerJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/MinerJsonRpcMethods.java @@ -17,10 +17,12 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerChangeTargetGasLimit; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerGetExtraData; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerGetMinGasPrice; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerGetMinPriorityFee; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetCoinbase; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetEtherbase; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetExtraData; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetMinGasPrice; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetMinPriorityFee; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerStart; @@ -58,6 +60,8 @@ protected Map create() { new MinerGetMinPriorityFee(miningParameters), new MinerSetMinPriorityFee(miningParameters), new MinerGetMinGasPrice(miningParameters), - new MinerSetMinGasPrice(miningParameters)); + new MinerSetMinGasPrice(miningParameters), + new MinerGetExtraData(miningParameters), + new MinerSetExtraData(miningParameters)); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraDataTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraDataTest.java new file mode 100644 index 00000000000..ebaf817a477 --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraDataTest.java @@ -0,0 +1,62 @@ +/* + * 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.ethereum.api.jsonrpc.internal.methods.miner; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters; +import org.hyperledger.besu.ethereum.core.MiningParameters; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; + +public class MinerGetExtraDataTest { + + @Test + public void shouldReturnDefaultExtraData() { + final MiningParameters miningParameters = ImmutableMiningParameters.newDefault(); + final MinerGetExtraData method = new MinerGetExtraData(miningParameters); + final JsonRpcRequestContext request = + new JsonRpcRequestContext(new JsonRpcRequest("2.0", method.getName(), new Object[] {})); + + final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId(), "0x"); + + final JsonRpcResponse actual = method.response(request); + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + } + + @Test + public void shouldReturnSetAtRuntimeExtraData() { + final MiningParameters miningParameters = ImmutableMiningParameters.newDefault(); + final MinerGetExtraData method = new MinerGetExtraData(miningParameters); + final var extraData = "0x123456"; + final Bytes extraDataAtRuntime = Bytes.fromHexString(extraData); + + miningParameters.setExtraData(extraDataAtRuntime); + + final JsonRpcRequestContext request = + new JsonRpcRequestContext(new JsonRpcRequest("2.0", method.getName(), new Object[] {})); + + final JsonRpcResponse expected = + new JsonRpcSuccessResponse(request.getRequest().getId(), extraData); + + final JsonRpcResponse actual = method.response(request); + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + } +} diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java new file mode 100644 index 00000000000..ad44c690433 --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java @@ -0,0 +1,109 @@ +/* + * 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.ethereum.api.jsonrpc.internal.methods.miner; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType; +import org.hyperledger.besu.ethereum.core.MiningParameters; + +import java.nio.charset.StandardCharsets; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class MinerSetExtraDataTest { + MiningParameters miningParameters = MiningParameters.newDefault(); + private MinerSetExtraData method; + + @BeforeEach + public void setUp() { + method = new MinerSetExtraData(miningParameters); + } + + @Test + public void shouldChangeExtraData() { + final String newExtraData = " pippo 🐐 | "; + final var request = + request(Bytes.wrap(newExtraData.getBytes(StandardCharsets.UTF_8)).toHexString()); + final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId(), true); + + final JsonRpcResponse actual = method.response(request); + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + final var currExtraData = miningParameters.getExtraData(); + assertThat(new String(currExtraData.toArray(), StandardCharsets.UTF_8)).isEqualTo(newExtraData); + } + + private JsonRpcRequestContext request(final String newExtraData) { + return new JsonRpcRequestContext( + new JsonRpcRequest("2.0", method.getName(), new Object[] {newExtraData})); + } + + @Test + public void shouldNotTrimLeadingZeros() { + final var zeroPrefixedExtraData = "0010203"; + final var request = request(zeroPrefixedExtraData); + + final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId(), true); + + final JsonRpcResponse actual = method.response(request); + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + final var currExtraData = miningParameters.getExtraData(); + assertThat(new String(currExtraData.toArray(), StandardCharsets.UTF_8)) + .isEqualTo( + new String( + Bytes.fromHexStringLenient(zeroPrefixedExtraData).toArray(), + StandardCharsets.UTF_8)); + } + + @Test + public void shouldReturnErrorWhenExtraDataNotHex() { + final var request = request("not hex string"); + + final JsonRpcResponse expected = + new JsonRpcErrorResponse( + request.getRequest().getId(), + new JsonRpcError( + RpcErrorType.INVALID_PARAMS, + "Illegal character 'n' found at index 0 in hex binary representation")); + + final JsonRpcResponse actual = method.response(request); + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + } + + @Test + public void shouldReturnErrorWhenExtraDataTooLong() { + final var tooLongExtraData = "shouldReturnFalseWhenExtraDataTooLong"; + final var request = + request(Bytes.wrap(tooLongExtraData.getBytes(StandardCharsets.UTF_8)).toHexString()); + + final JsonRpcResponse expected = + new JsonRpcErrorResponse( + request.getRequest().getId(), + new JsonRpcError( + RpcErrorType.INVALID_PARAMS, + "Hex value is too large: expected at most 32 bytes but got 37")); + + final JsonRpcResponse actual = method.response(request); + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + } +} diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMinerExecutor.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMinerExecutor.java index ec66f2725ad..af71938d1d5 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMinerExecutor.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMinerExecutor.java @@ -34,7 +34,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -98,10 +97,6 @@ public abstract M createMiner( final Subscribers ethHashObservers, final BlockHeader parentHeader); - public void setExtraData(final Bytes extraData) { - miningParameters.setExtraData(extraData.copy()); - } - public void setMinTransactionGasPrice(final Wei minTransactionGasPrice) { miningParameters.setMinTransactionGasPrice(minTransactionGasPrice); } diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMiningCoordinator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMiningCoordinator.java index 6d87f1da7da..9c939b91bc8 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMiningCoordinator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMiningCoordinator.java @@ -32,8 +32,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import org.apache.tuweni.bytes.Bytes; - public abstract class AbstractMiningCoordinator< M extends BlockMiner> implements BlockAddedObserver, MiningCoordinator { @@ -212,11 +210,6 @@ public Wei getMinPriorityFeePerGas() { return executor.getMinPriorityFeePerGas(); } - @Override - public void setExtraData(final Bytes extraData) { - executor.setExtraData(extraData); - } - @Override public Optional
getCoinbase() { return executor.getCoinbase(); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/MiningCoordinator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/MiningCoordinator.java index 4ab98f3ca9a..d1a91083b63 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/MiningCoordinator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/MiningCoordinator.java @@ -26,8 +26,6 @@ import java.util.List; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes; - public interface MiningCoordinator { void start(); @@ -60,8 +58,6 @@ default void onPauseMining() {} Wei getMinPriorityFeePerGas(); - void setExtraData(Bytes extraData); - default void setCoinbase(final Address coinbase) { throw new UnsupportedOperationException( "Current consensus mechanism prevents setting coinbase."); diff --git a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/NoopMiningCoordinator.java b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/NoopMiningCoordinator.java index b0b49ed0e8f..6eb4927226c 100644 --- a/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/NoopMiningCoordinator.java +++ b/ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/NoopMiningCoordinator.java @@ -24,8 +24,6 @@ import java.util.List; import java.util.Optional; -import org.apache.tuweni.bytes.Bytes; - public class NoopMiningCoordinator implements MiningCoordinator { private final MiningParameters miningParameters; @@ -68,9 +66,6 @@ public Wei getMinPriorityFeePerGas() { return miningParameters.getMinPriorityFeePerGas(); } - @Override - public void setExtraData(final Bytes extraData) {} - @Override public Optional
getCoinbase() { return miningParameters.getCoinbase();