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 <fabio.difabio@consensys.net>

* Remove redundant methods to set the extra data

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* miner_getExtraData unit tests

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Add CHANGELOG

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

* Apply suggestions from code review

Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>

---------

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
pull/7083/head
Fabio Di Fabio 7 months ago committed by GitHub
parent b4b6adcf99
commit 40cfc800f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 2
      besu/src/main/java/org/hyperledger/besu/chainimport/JsonBlockImporter.java
  3. 2
      consensus/clique/src/test/java/org/hyperledger/besu/consensus/clique/blockcreation/CliqueMinerExecutorTest.java
  4. 6
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinator.java
  5. 10
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftBlockCreatorFactory.java
  6. 6
      consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinator.java
  7. 6
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/MigratingMiningCoordinatorTest.java
  8. 8
      consensus/common/src/test/java/org/hyperledger/besu/consensus/common/bft/blockcreation/BftMiningCoordinatorTest.java
  9. 6
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java
  10. 7
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/TransitionCoordinator.java
  11. 2
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java
  12. 41
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraData.java
  13. 69
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraData.java
  14. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/MinerJsonRpcMethods.java
  15. 62
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerGetExtraDataTest.java
  16. 109
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/miner/MinerSetExtraDataTest.java
  17. 5
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMinerExecutor.java
  18. 7
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/AbstractMiningCoordinator.java
  19. 4
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/MiningCoordinator.java
  20. 5
      ethereum/blockcreation/src/main/java/org/hyperledger/besu/ethereum/blockcreation/NoopMiningCoordinator.java

@ -48,6 +48,7 @@
- Update Gradle to 7.6.4 [#7030](https://github.com/hyperledger/besu/pull/7030) - 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) - 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) - 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 ### Bug fixes
- Fix txpool dump/restore race condition [#6665](https://github.com/hyperledger/besu/pull/6665) - Fix txpool dump/restore race condition [#6665](https://github.com/hyperledger/besu/pull/6665)

@ -136,7 +136,7 @@ public class JsonBlockImporter {
// For simplicity only set these for PoW consensus algorithms. // For simplicity only set these for PoW consensus algorithms.
// Other consensus algorithms use these fields for special purposes or ignore them. // Other consensus algorithms use these fields for special purposes or ignore them.
miner.setCoinbase(blockData.getCoinbase().orElse(Address.ZERO)); 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()) { } else if (blockData.getCoinbase().isPresent() || blockData.getExtraData().isPresent()) {
// Fail if these fields are set for non-ethash chains // Fail if these fields are set for non-ethash chains
final Stream.Builder<String> fields = Stream.builder(); final Stream.Builder<String> fields = Stream.builder();

@ -200,7 +200,7 @@ public class CliqueMinerExecutorTest {
null, null,
ethScheduler); ethScheduler);
executor.setExtraData(modifiedVanityData); miningParameters.setExtraData(modifiedVanityData);
final Bytes extraDataBytes = executor.calculateExtraData(blockHeaderBuilder.buildHeader()); final Bytes extraDataBytes = executor.calculateExtraData(blockHeaderBuilder.buildHeader());
final CliqueExtraData cliqueExtraData = final CliqueExtraData cliqueExtraData =

@ -29,7 +29,6 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -108,11 +107,6 @@ public class MigratingMiningCoordinator implements MiningCoordinator, BlockAdded
return activeMiningCoordinator.getMinPriorityFeePerGas(); return activeMiningCoordinator.getMinPriorityFeePerGas();
} }
@Override
public void setExtraData(final Bytes extraData) {
activeMiningCoordinator.setExtraData(extraData);
}
@Override @Override
public Optional<Address> getCoinbase() { public Optional<Address> getCoinbase() {
return activeMiningCoordinator.getCoinbase(); return activeMiningCoordinator.getCoinbase();

@ -124,16 +124,6 @@ public class BftBlockCreatorFactory<T extends BftConfigOptions> {
ethScheduler); ethScheduler);
} }
/**
* Sets extra data.
*
* @param extraData the extra data
*/
public void setExtraData(final Bytes extraData) {
miningParameters.setExtraData(extraData.copy());
}
/** /**
* Sets min transaction gas price. * Sets min transaction gas price.
* *

@ -33,7 +33,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -154,11 +153,6 @@ public class BftMiningCoordinator implements MiningCoordinator, BlockAddedObserv
return blockCreatorFactory.getMinPriorityFeePerGas(); return blockCreatorFactory.getMinPriorityFeePerGas();
} }
@Override
public void setExtraData(final Bytes extraData) {
blockCreatorFactory.setExtraData(extraData);
}
@Override @Override
public Optional<Address> getCoinbase() { public Optional<Address> getCoinbase() {
return Optional.of(blockCreatorFactory.getLocalAddress()); return Optional.of(blockCreatorFactory.getLocalAddress());

@ -40,7 +40,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@ -162,11 +161,6 @@ public class MigratingMiningCoordinatorTest {
coordinator2, coordinator2,
coordinator1); coordinator1);
verifyDelegation(
c -> c.setExtraData(Bytes.EMPTY), GENESIS_BLOCK_NUMBER, coordinator1, coordinator2);
verifyDelegation(
c -> c.setExtraData(Bytes.EMPTY), MIGRATION_BLOCK_NUMBER, coordinator2, coordinator1);
verifyDelegation( verifyDelegation(
MiningCoordinator::getCoinbase, GENESIS_BLOCK_NUMBER, coordinator1, coordinator2); MiningCoordinator::getCoinbase, GENESIS_BLOCK_NUMBER, coordinator1, coordinator2);
verifyDelegation( verifyDelegation(

@ -35,7 +35,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.tuweni.bytes.Bytes;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@ -89,13 +88,6 @@ public class BftMiningCoordinatorTest {
assertThat(bftMiningCoordinator.getMinTransactionGasPrice()).isEqualTo(minGasPrice); assertThat(bftMiningCoordinator.getMinTransactionGasPrice()).isEqualTo(minGasPrice);
} }
@Test
public void setsTheExtraData() {
final Bytes extraData = Bytes.fromHexStringLenient("0x1234");
bftMiningCoordinator.setExtraData(extraData);
verify(bftBlockCreatorFactory).setExtraData(extraData);
}
@Test @Test
public void addsNewChainHeadEventWhenNewCanonicalHeadBlockEventReceived() throws Exception { public void addsNewChainHeadEventWhenNewCanonicalHeadBlockEventReceived() throws Exception {
BlockAddedEvent headAdvancement = BlockAddedEvent headAdvancement =

@ -61,7 +61,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -225,11 +224,6 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
return miningParameters.getMinPriorityFeePerGas(); return miningParameters.getMinPriorityFeePerGas();
} }
@Override
public void setExtraData(final Bytes extraData) {
this.miningParameters.setExtraData(extraData);
}
@Override @Override
public Optional<Address> getCoinbase() { public Optional<Address> getCoinbase() {
return miningParameters.getCoinbase(); return miningParameters.getCoinbase();

@ -33,7 +33,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
/** The Transition coordinator. */ /** The Transition coordinator. */
@ -107,12 +106,6 @@ public class TransitionCoordinator extends TransitionUtils<MiningCoordinator>
return dispatchFunctionAccordingToMergeState(MiningCoordinator::getMinPriorityFeePerGas); return dispatchFunctionAccordingToMergeState(MiningCoordinator::getMinPriorityFeePerGas);
} }
@Override
public void setExtraData(final Bytes extraData) {
miningCoordinator.setExtraData(extraData);
mergeCoordinator.setExtraData(extraData);
}
@Override @Override
public Optional<Address> getCoinbase() { public Optional<Address> getCoinbase() {
return dispatchFunctionAccordingToMergeState(MiningCoordinator::getCoinbase); return dispatchFunctionAccordingToMergeState(MiningCoordinator::getCoinbase);

@ -159,6 +159,8 @@ public enum RpcMethod {
MINER_SET_MIN_PRIORITY_FEE("miner_setMinPriorityFee"), MINER_SET_MIN_PRIORITY_FEE("miner_setMinPriorityFee"),
MINER_GET_MIN_GAS_PRICE("miner_getMinGasPrice"), MINER_GET_MIN_GAS_PRICE("miner_getMinGasPrice"),
MINER_SET_MIN_GAS_PRICE("miner_setMinGasPrice"), MINER_SET_MIN_GAS_PRICE("miner_setMinGasPrice"),
MINER_GET_EXTRA_DATA("miner_getExtraData"),
MINER_SET_EXTRA_DATA("miner_setExtraData"),
NET_ENODE("net_enode"), NET_ENODE("net_enode"),
NET_LISTENING("net_listening"), NET_LISTENING("net_listening"),
NET_PEER_COUNT("net_peerCount"), NET_PEER_COUNT("net_peerCount"),

@ -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());
}
}

@ -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()));
}
}
}

@ -17,10 +17,12 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; 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.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerChangeTargetGasLimit; 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.MinerGetMinGasPrice;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerGetMinPriorityFee; 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.MinerSetCoinbase;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetEtherbase; 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.MinerSetMinGasPrice;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetMinPriorityFee; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerSetMinPriorityFee;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerStart; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.miner.MinerStart;
@ -58,6 +60,8 @@ public class MinerJsonRpcMethods extends ApiGroupJsonRpcMethods {
new MinerGetMinPriorityFee(miningParameters), new MinerGetMinPriorityFee(miningParameters),
new MinerSetMinPriorityFee(miningParameters), new MinerSetMinPriorityFee(miningParameters),
new MinerGetMinGasPrice(miningParameters), new MinerGetMinGasPrice(miningParameters),
new MinerSetMinGasPrice(miningParameters)); new MinerSetMinGasPrice(miningParameters),
new MinerGetExtraData(miningParameters),
new MinerSetExtraData(miningParameters));
} }
} }

@ -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);
}
}

@ -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);
}
}

@ -34,7 +34,6 @@ import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.tuweni.bytes.Bytes;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -98,10 +97,6 @@ public abstract class AbstractMinerExecutor<M extends BlockMiner<? extends Abstr
final Subscribers<PoWObserver> ethHashObservers, final Subscribers<PoWObserver> ethHashObservers,
final BlockHeader parentHeader); final BlockHeader parentHeader);
public void setExtraData(final Bytes extraData) {
miningParameters.setExtraData(extraData.copy());
}
public void setMinTransactionGasPrice(final Wei minTransactionGasPrice) { public void setMinTransactionGasPrice(final Wei minTransactionGasPrice) {
miningParameters.setMinTransactionGasPrice(minTransactionGasPrice); miningParameters.setMinTransactionGasPrice(minTransactionGasPrice);
} }

@ -32,8 +32,6 @@ import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.apache.tuweni.bytes.Bytes;
public abstract class AbstractMiningCoordinator< public abstract class AbstractMiningCoordinator<
M extends BlockMiner<? extends AbstractBlockCreator>> M extends BlockMiner<? extends AbstractBlockCreator>>
implements BlockAddedObserver, MiningCoordinator { implements BlockAddedObserver, MiningCoordinator {
@ -212,11 +210,6 @@ public abstract class AbstractMiningCoordinator<
return executor.getMinPriorityFeePerGas(); return executor.getMinPriorityFeePerGas();
} }
@Override
public void setExtraData(final Bytes extraData) {
executor.setExtraData(extraData);
}
@Override @Override
public Optional<Address> getCoinbase() { public Optional<Address> getCoinbase() {
return executor.getCoinbase(); return executor.getCoinbase();

@ -26,8 +26,6 @@ import org.hyperledger.besu.ethereum.mainnet.PoWSolverInputs;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public interface MiningCoordinator { public interface MiningCoordinator {
void start(); void start();
@ -60,8 +58,6 @@ public interface MiningCoordinator {
Wei getMinPriorityFeePerGas(); Wei getMinPriorityFeePerGas();
void setExtraData(Bytes extraData);
default void setCoinbase(final Address coinbase) { default void setCoinbase(final Address coinbase) {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"Current consensus mechanism prevents setting coinbase."); "Current consensus mechanism prevents setting coinbase.");

@ -24,8 +24,6 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public class NoopMiningCoordinator implements MiningCoordinator { public class NoopMiningCoordinator implements MiningCoordinator {
private final MiningParameters miningParameters; private final MiningParameters miningParameters;
@ -68,9 +66,6 @@ public class NoopMiningCoordinator implements MiningCoordinator {
return miningParameters.getMinPriorityFeePerGas(); return miningParameters.getMinPriorityFeePerGas();
} }
@Override
public void setExtraData(final Bytes extraData) {}
@Override @Override
public Optional<Address> getCoinbase() { public Optional<Address> getCoinbase() {
return miningParameters.getCoinbase(); return miningParameters.getCoinbase();

Loading…
Cancel
Save