Allow Besu to host RPC endpoints via a plugin. (#2754)

This is a re-implementation of the initial POC done in https://github.com/PegaSysEng/pantheon/pull/1909/ by Danno Ferrin <danno.ferrin@gmail.com>

* Only enable plugin rpc api when enabled on --rpc-http-api or --rpc-ws-apis
* Only allow new rpc endpoints to be defined

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>
This commit is contained in:
Antony Denyer
2021-10-11 09:45:52 +01:00
committed by GitHub
parent fc687ab1a4
commit a30c314290
64 changed files with 635 additions and 422 deletions

View File

@@ -8,7 +8,7 @@
### Bug Fixes
### Early Access Features
- Enable plugins to expose custom JSON-RPC / WebSocket methods [#1317](https://github.com/hyperledger/besu/issues/1317)
## 21.10.0-RC1
### Additions and Improvements

View File

@@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration;
import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
@@ -447,8 +445,8 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner {
StaticNodesUtils.createStaticNodesFile(node.homeDirectory(), node.getStaticNodes());
}
private String apiList(final Collection<RpcApi> rpcApis) {
return rpcApis.stream().map(RpcApis::getValue).collect(Collectors.joining(","));
private String apiList(final Collection<String> rpcApis) {
return String.join(",", rpcApis);
}
@Override

View File

@@ -49,6 +49,7 @@ import org.hyperledger.besu.services.BesuEventsImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.PicoCLIOptionsImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import org.hyperledger.besu.services.SecurityModuleServiceImpl;
import org.hyperledger.besu.services.StorageServiceImpl;
@@ -211,6 +212,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
.autoLogBloomCaching(false)
.storageProvider(storageProvider)
.forkIdSupplier(() -> besuController.getProtocolManager().getForkIdAsBytesList())
.rpcEndpointService(new RpcEndpointServiceImpl())
.build();
runner.start();

View File

@@ -107,13 +107,13 @@ public class BesuNodeConfigurationBuilder {
public BesuNodeConfigurationBuilder miningEnabled(final boolean enabled) {
this.miningParameters =
new MiningParameters.Builder().enabled(enabled).coinbase(AddressHelpers.ofValue(1)).build();
this.jsonRpcConfiguration.addRpcApi(RpcApis.MINER);
this.jsonRpcConfiguration.addRpcApi(RpcApis.MINER.name());
return this;
}
public BesuNodeConfigurationBuilder miningConfiguration(final MiningParameters miningParameters) {
this.miningParameters = miningParameters;
this.jsonRpcConfiguration.addRpcApi(RpcApis.MINER);
this.jsonRpcConfiguration.addRpcApi(RpcApis.MINER.name());
return this;
}
@@ -143,18 +143,18 @@ public class BesuNodeConfigurationBuilder {
}
public BesuNodeConfigurationBuilder enablePrivateTransactions() {
this.jsonRpcConfiguration.addRpcApi(RpcApis.EEA);
this.jsonRpcConfiguration.addRpcApi(RpcApis.PRIV);
this.jsonRpcConfiguration.addRpcApi(RpcApis.EEA.name());
this.jsonRpcConfiguration.addRpcApi(RpcApis.PRIV.name());
return this;
}
public BesuNodeConfigurationBuilder jsonRpcTxPool() {
this.jsonRpcConfiguration.addRpcApi(RpcApis.TX_POOL);
this.jsonRpcConfiguration.addRpcApi(RpcApis.TXPOOL.name());
return this;
}
public BesuNodeConfigurationBuilder jsonRpcAdmin() {
this.jsonRpcConfiguration.addRpcApi(RpcApis.ADMIN);
this.jsonRpcConfiguration.addRpcApi(RpcApis.ADMIN.name());
return this;
}

View File

@@ -24,7 +24,6 @@ import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.core.AddressHelpers;
import org.hyperledger.besu.ethereum.core.InMemoryPrivacyStorageProvider;
@@ -255,12 +254,14 @@ public class BesuNodeFactory {
return create(
new BesuNodeConfigurationBuilder()
.name(name)
.jsonRpcConfiguration(node.createJsonRpcWithIbft2AdminEnabledConfig())
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.plugins(plugins)
.extraCLIOptions(extraCLIOptions)
.build());
}
public BesuNode createArchiveNodeWithRpcApis(final String name, final RpcApi... enabledRpcApis)
public BesuNode createArchiveNodeWithRpcApis(final String name, final String... enabledRpcApis)
throws IOException {
final JsonRpcConfiguration jsonRpcConfig = node.createJsonRpcEnabledConfig();
jsonRpcConfig.setRpcApis(asList(enabledRpcApis));

View File

@@ -16,14 +16,13 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.configuration;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static org.hyperledger.besu.consensus.clique.jsonrpc.CliqueRpcApis.CLIQUE;
import static org.hyperledger.besu.consensus.ibft.jsonrpc.IbftRpcApis.IBFT;
import static org.hyperledger.besu.consensus.qbft.jsonrpc.QbftRpcApis.QBFT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ADMIN;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.CLIQUE;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.IBFT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.MINER;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.QBFT;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider;
@@ -46,23 +45,23 @@ public class NodeConfigurationFactory {
}
public JsonRpcConfiguration createJsonRpcWithCliqueEnabledConfig() {
return createJsonRpcWithRpcApiEnabledConfig(CLIQUE);
return createJsonRpcWithRpcApiEnabledConfig(CLIQUE.name());
}
public JsonRpcConfiguration createJsonRpcWithIbft2EnabledConfig(final boolean minerEnabled) {
return minerEnabled
? createJsonRpcWithRpcApiEnabledConfig(IBFT, MINER)
: createJsonRpcWithRpcApiEnabledConfig(IBFT);
? createJsonRpcWithRpcApiEnabledConfig(IBFT.name(), MINER.name())
: createJsonRpcWithRpcApiEnabledConfig(IBFT.name());
}
public JsonRpcConfiguration createJsonRpcWithIbft2AdminEnabledConfig() {
return createJsonRpcWithRpcApiEnabledConfig(IBFT, ADMIN);
return createJsonRpcWithRpcApiEnabledConfig(IBFT.name(), ADMIN.name());
}
public JsonRpcConfiguration createJsonRpcWithQbftEnabledConfig(final boolean minerEnabled) {
return minerEnabled
? createJsonRpcWithRpcApiEnabledConfig(QBFT, MINER)
: createJsonRpcWithRpcApiEnabledConfig(QBFT);
? createJsonRpcWithRpcApiEnabledConfig(QBFT.name(), MINER.name())
: createJsonRpcWithRpcApiEnabledConfig(QBFT.name());
}
public JsonRpcConfiguration createJsonRpcEnabledConfig() {
@@ -81,12 +80,12 @@ public class NodeConfigurationFactory {
}
public JsonRpcConfiguration jsonRpcConfigWithAdmin() {
return createJsonRpcWithRpcApiEnabledConfig(ADMIN);
return createJsonRpcWithRpcApiEnabledConfig(ADMIN.name());
}
public JsonRpcConfiguration createJsonRpcWithRpcApiEnabledConfig(final RpcApi... rpcApi) {
public JsonRpcConfiguration createJsonRpcWithRpcApiEnabledConfig(final String... rpcApi) {
final JsonRpcConfiguration jsonRpcConfig = createJsonRpcEnabledConfig();
final List<RpcApi> rpcApis = new ArrayList<>(jsonRpcConfig.getRpcApis());
final List<String> rpcApis = new ArrayList<>(jsonRpcConfig.getRpcApis());
rpcApis.addAll(Arrays.asList(rpcApi));
jsonRpcConfig.setRpcApis(rpcApis);
return jsonRpcConfig;

View File

@@ -19,7 +19,6 @@ import static java.util.stream.Collectors.toList;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
import org.hyperledger.besu.ethereum.permissioning.AllowlistPersistor;
@@ -297,9 +296,9 @@ public class PermissionedNodeBuilder {
jsonRpcConfig.setPort(0);
jsonRpcConfig.setHostsAllowlist(singletonList("*"));
jsonRpcConfig.setCorsAllowedDomains(singletonList("*"));
final List<RpcApi> rpcApis = new ArrayList<>(jsonRpcConfig.getRpcApis());
rpcApis.add(RpcApis.PERM);
rpcApis.add(RpcApis.ADMIN);
final List<String> rpcApis = new ArrayList<>(jsonRpcConfig.getRpcApis());
rpcApis.add(RpcApis.PERM.name());
rpcApis.add(RpcApis.ADMIN.name());
jsonRpcConfig.setRpcApis(rpcApis);
return jsonRpcConfig;
}

View File

@@ -59,8 +59,7 @@ public class TestPicoCLIPlugin implements BesuPlugin {
context
.getService(PicoCLIOptions.class)
.ifPresent(
picoCLIOptions -> picoCLIOptions.addPicoCLIOptions("test", TestPicoCLIPlugin.this));
.ifPresent(picoCLIOptions -> picoCLIOptions.addPicoCLIOptions("test", this));
callbackDir = new File(System.getProperty("besu.plugins.dir", "plugins"));
writeSignal("registered");

View File

@@ -0,0 +1,72 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.plugins;
import static com.google.common.base.Preconditions.checkArgument;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import java.util.concurrent.atomic.AtomicReference;
import com.google.auto.service.AutoService;
@AutoService(BesuPlugin.class)
public class TestRpcEndpointServicePlugin implements BesuPlugin {
private final AtomicReference<String> stringStorage = new AtomicReference<>("InitialValue");
private final AtomicReference<Object[]> arrayStorage = new AtomicReference<>();
private String setValue(final PluginRpcRequest request) {
checkArgument(request.getParams().length == 1, "Only one parameter accepted");
return stringStorage.updateAndGet(x -> request.getParams()[0].toString());
}
private String getValue(final PluginRpcRequest request) {
return stringStorage.get();
}
private Object[] replaceValueList(final PluginRpcRequest request) {
return arrayStorage.updateAndGet(x -> request.getParams());
}
private String throwException(final PluginRpcRequest request) {
throw new RuntimeException("Kaboom");
}
@Override
public void register(final BesuContext context) {
context
.getService(RpcEndpointService.class)
.ifPresent(
rpcEndpointService -> {
rpcEndpointService.registerRPCEndpoint("tests", "getValue", this::getValue);
rpcEndpointService.registerRPCEndpoint("tests", "setValue", this::setValue);
rpcEndpointService.registerRPCEndpoint(
"tests", "replaceValueList", this::replaceValueList);
rpcEndpointService.registerRPCEndpoint(
"tests", "throwException", this::throwException);
rpcEndpointService.registerRPCEndpoint("notEnabled", "getValue", this::getValue);
});
}
@Override
public void start() {}
@Override
public void stop() {}
}

View File

@@ -35,7 +35,7 @@ public class RpcApisTogglesAcceptanceTest extends AcceptanceTestBase {
public void before() throws Exception {
rpcEnabledNode = besu.createArchiveNode("rpc-enabled");
rpcDisabledNode = besu.createArchiveNodeWithRpcDisabled("rpc-disabled");
ethApiDisabledNode = besu.createArchiveNodeWithRpcApis("eth-api-disabled", RpcApis.NET);
ethApiDisabledNode = besu.createArchiveNodeWithRpcApis("eth-api-disabled", RpcApis.NET.name());
cluster.start(rpcEnabledNode, rpcDisabledNode, ethApiDisabledNode);
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.plugins;
import static org.assertj.core.api.Assertions.assertThat;
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.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.junit.Before;
import org.junit.Test;
public class RpcEndpointServicePluginTest extends AcceptanceTestBase {
private BesuNode node;
private OkHttpClient client;
protected static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
@Before
public void setUp() throws Exception {
node = besu.createPluginsNode("node1", List.of("testPlugins"), List.of("--rpc-http-api=TESTS"));
cluster.start(node);
client = new OkHttpClient();
}
@Test
public void canUseRpcToSetValue() throws IOException {
String setValue = "secondCall";
ObjectNode resultJson = callTestMethod("tests_getValue", List.of());
assertThat(resultJson.get("result").asText()).isEqualTo("InitialValue");
resultJson = callTestMethod("tests_setValue", List.of(setValue));
assertThat(resultJson.get("result").asText()).isEqualTo(setValue);
resultJson = callTestMethod("tests_getValue", List.of("ignored"));
assertThat(resultJson.get("result").asText()).isEqualTo(setValue);
}
@Test
public void canCheckArgumentInsideSetValue() throws IOException {
ObjectNode resultJson = callTestMethod("tests_setValue", List.of("one", "two"));
assertThat(resultJson.get("error").get("message").asText()).isEqualTo("Internal error");
}
@Test
public void exceptionsInPluginMethodReturnError() throws IOException {
ObjectNode resultJson = callTestMethod("tests_throwException", List.of());
assertThat(resultJson.get("error").get("message").asText()).isEqualTo("Internal error");
}
@Test
public void onlyEnabledMethodsReturn() throws IOException {
ObjectNode resultJson = callTestMethod("notEnabled_getValue", List.of());
assertThat(resultJson.get("error").get("message").asText()).isEqualTo("Method not found");
}
@Test
public void mixedTypeArraysAreStringified() throws IOException {
ObjectNode resultJson = callTestMethod("tests_replaceValueList", List.of());
assertThat(resultJson.get("result")).isEmpty();
resultJson = callTestMethod("tests_replaceValueList", List.of("One", 2, true));
JsonNode result = resultJson.get("result");
assertThat(result.get(0).asText()).isEqualTo("One");
assertThat(result.get(1).asText()).isEqualTo("2");
assertThat(result.get(2).asText()).isEqualTo("true");
}
private ObjectNode callTestMethod(final String method, final List<Object> params)
throws IOException {
String format =
String.format(
"{\"jsonrpc\":\"2.0\",\"method\":\"%s\",\"params\":[%s],\"id\":42}",
method,
params.stream().map(value -> "\"" + value + "\"").collect(Collectors.joining(",")));
RequestBody body = RequestBody.create(format, JSON);
final String resultString =
client
.newCall(
new Request.Builder()
.post(body)
.url(
"http://"
+ node.getHostName()
+ ":"
+ node.getJsonRpcSocketPort().get()
+ "/")
.build())
.execute()
.body()
.string();
return JsonUtil.objectNodeFromString(resultString);
}
}

View File

@@ -33,7 +33,6 @@ import org.hyperledger.besu.ethereum.api.graphql.GraphQLHttpService;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.health.HealthService;
import org.hyperledger.besu.ethereum.api.jsonrpc.health.LivenessCheck;
import org.hyperledger.besu.ethereum.api.jsonrpc.health.ReadinessCheck;
@@ -109,6 +108,7 @@ import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import org.hyperledger.besu.util.NetworkUtility;
import java.io.IOException;
@@ -175,6 +175,7 @@ public class RunnerBuilder {
private boolean randomPeerPriority;
private StorageProvider storageProvider;
private Supplier<List<Bytes>> forkIdSupplier;
private RpcEndpointServiceImpl rpcEndpointServiceImpl;
public RunnerBuilder vertx(final Vertx vertx) {
this.vertx = vertx;
@@ -368,6 +369,11 @@ public class RunnerBuilder {
return this;
}
public RunnerBuilder rpcEndpointService(final RpcEndpointServiceImpl rpcEndpointService) {
this.rpcEndpointServiceImpl = rpcEndpointService;
return this;
}
public Runner build() {
Preconditions.checkNotNull(besuController);
@@ -567,7 +573,8 @@ public class RunnerBuilder {
metricsConfiguration,
natService,
besuPluginContext.getNamedPlugins(),
dataDir);
dataDir,
rpcEndpointServiceImpl);
jsonRpcHttpService =
Optional.of(
new JsonRpcHttpService(
@@ -634,7 +641,8 @@ public class RunnerBuilder {
metricsConfiguration,
natService,
besuPluginContext.getNamedPlugins(),
dataDir);
dataDir,
rpcEndpointServiceImpl);
final SubscriptionManager subscriptionManager =
createSubscriptionManager(vertx, transactionPool, blockchainQueries);
@@ -816,7 +824,7 @@ public class RunnerBuilder {
final MiningCoordinator miningCoordinator,
final ObservableMetricsSystem metricsSystem,
final Set<Capability> supportedCapabilities,
final Collection<RpcApi> jsonRpcApis,
final Collection<String> jsonRpcApis,
final FilterManager filterManager,
final Optional<AccountLocalConfigPermissioningController> accountAllowlistController,
final Optional<NodeLocalConfigPermissioningController> nodeAllowlistController,
@@ -826,7 +834,8 @@ public class RunnerBuilder {
final MetricsConfiguration metricsConfiguration,
final NatService natService,
final Map<String, BesuPlugin> namedPlugins,
final Path dataDir) {
final Path dataDir,
final RpcEndpointServiceImpl rpcEndpointServiceImpl) {
final Map<String, JsonRpcMethod> methods =
new JsonRpcMethodsFactory()
.methods(
@@ -854,6 +863,16 @@ public class RunnerBuilder {
dataDir,
besuController.getProtocolManager().ethContext().getEthPeers());
methods.putAll(besuController.getAdditionalJsonRpcMethods(jsonRpcApis));
var pluginMethods = rpcEndpointServiceImpl.getPluginMethods(jsonRpcConfiguration.getRpcApis());
var overriddenMethods =
methods.keySet().stream().filter(pluginMethods::containsKey).collect(Collectors.toList());
if (overriddenMethods.size() > 0) {
throw new RuntimeException("You can not override built in methods " + overriddenMethods);
}
methods.putAll(pluginMethods);
return methods;
}
@@ -955,6 +974,11 @@ public class RunnerBuilder {
privateWebSocketMethodsFactory.methods().forEach(websocketMethodsFactory::addMethods);
}
rpcEndpointServiceImpl
.getPluginMethods(configuration.getRpcApis())
.values()
.forEach(websocketMethodsFactory::addMethods);
final WebSocketRequestHandler websocketRequestHandler =
new WebSocketRequestHandler(
vertx,

View File

@@ -24,7 +24,7 @@ import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPENDENCY_WARNING_
import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;
import static org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration.DEFAULT_GRAPHQL_HTTP_PORT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_JSON_RPC_PORT;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_JSON_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration.DEFAULT_WEBSOCKET_PORT;
import static org.hyperledger.besu.ethereum.permissioning.GoQuorumPermissioningConfiguration.QIP714_DEFAULT_BLOCK;
import static org.hyperledger.besu.metrics.BesuMetricCategory.DEFAULT_METRIC_CATEGORIES;
@@ -43,7 +43,6 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.cli.converter.MetricCategoryConverter;
import org.hyperledger.besu.cli.converter.PercentageConverter;
import org.hyperledger.besu.cli.converter.RpcApisConverter;
import org.hyperledger.besu.cli.custom.CorsAllowedOriginsProperty;
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty;
import org.hyperledger.besu.cli.custom.RpcAuthFileValidator;
@@ -101,7 +100,6 @@ import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.api.tls.FileBasedPasswordProvider;
@@ -152,6 +150,7 @@ import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.PermissioningService;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.PrivacyPluginService;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.SecurityModuleService;
import org.hyperledger.besu.plugin.services.StorageService;
import org.hyperledger.besu.plugin.services.exception.StorageException;
@@ -165,6 +164,7 @@ import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.PicoCLIOptionsImpl;
import org.hyperledger.besu.services.PrivacyPluginServiceImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import org.hyperledger.besu.services.SecurityModuleServiceImpl;
import org.hyperledger.besu.services.StorageServiceImpl;
import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin;
@@ -185,6 +185,7 @@ import java.net.UnknownHostException;
import java.nio.file.Path;
import java.time.Clock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.HashMap;
@@ -197,6 +198,7 @@ import java.util.OptionalLong;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -282,6 +284,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private final SecurityModuleServiceImpl securityModuleService;
private final PermissioningServiceImpl permissioningService;
private final PrivacyPluginServiceImpl privacyPluginPluginService;
private final RpcEndpointServiceImpl rpcEndpointServiceImpl;
private final Map<String, String> environment;
private final MetricCategoryRegistryImpl metricCategoryRegistry =
@@ -549,12 +552,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
@Option(
names = {"--rpc-http-api", "--rpc-http-apis"},
paramLabel = "<api name>",
split = ",",
split = " {0,1}, {0,1}",
arity = "1..*",
converter = RpcApisConverter.class,
description =
"Comma separated list of APIs to enable on JSON-RPC HTTP service (default: ${DEFAULT-VALUE})")
private final Collection<RpcApi> rpcHttpApis = DEFAULT_JSON_RPC_APIS;
private final List<String> rpcHttpApis = DEFAULT_RPC_APIS;
@Option(
names = {"--rpc-http-authentication-enabled"},
@@ -646,12 +648,11 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
@Option(
names = {"--rpc-ws-api", "--rpc-ws-apis"},
paramLabel = "<api name>",
split = ",",
split = " {0,1}, {0,1}",
arity = "1..*",
converter = RpcApisConverter.class,
description =
"Comma separated list of APIs to enable on JSON-RPC WebSocket service (default: ${DEFAULT-VALUE})")
private final List<RpcApi> rpcWsApis = DEFAULT_JSON_RPC_APIS;
private final List<String> rpcWsApis = DEFAULT_RPC_APIS;
@Option(
names = {"--rpc-ws-authentication-enabled"},
@@ -1141,7 +1142,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
new SecurityModuleServiceImpl(),
new PermissioningServiceImpl(),
new PrivacyPluginServiceImpl(),
new PkiBlockCreationConfigurationProvider());
new PkiBlockCreationConfigurationProvider(),
new RpcEndpointServiceImpl());
}
@VisibleForTesting
@@ -1158,7 +1160,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final SecurityModuleServiceImpl securityModuleService,
final PermissioningServiceImpl permissioningService,
final PrivacyPluginServiceImpl privacyPluginPluginService,
final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider) {
final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider,
final RpcEndpointServiceImpl rpcEndpointServiceImpl) {
this.logger = logger;
this.rlpBlockImporter = rlpBlockImporter;
this.rlpBlockExporterFactory = rlpBlockExporterFactory;
@@ -1174,6 +1177,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
pluginCommonConfiguration = new BesuCommandConfigurationService();
besuPluginContext.addService(BesuConfiguration.class, pluginCommonConfiguration);
this.pkiBlockCreationConfigProvider = pkiBlockCreationConfigProvider;
this.rpcEndpointServiceImpl = rpcEndpointServiceImpl;
}
public void parse(
@@ -1313,6 +1317,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
besuPluginContext.addService(MetricCategoryRegistry.class, metricCategoryRegistry);
besuPluginContext.addService(PermissioningService.class, permissioningService);
besuPluginContext.addService(PrivacyPluginService.class, privacyPluginPluginService);
besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl);
// register built-in plugins
new RocksDBPlugin().register(besuPluginContext);
@@ -1453,6 +1458,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
validateNatParams();
validateNetStatsParams();
validateDnsOptionsParams();
validateRpcOptionsParams();
p2pTLSConfigOptions.checkP2PTLSOptionsDependencies(logger, commandLine);
pkiBlockCreationOptions.checkPkiBlockCreationOptionsDependencies(logger, commandLine);
}
@@ -1522,6 +1528,22 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
}
public void validateRpcOptionsParams() {
Predicate<String> configuredApis =
apiName ->
Arrays.stream(RpcApis.values())
.anyMatch(builtInApi -> apiName.equals(builtInApi.name()))
|| rpcEndpointServiceImpl.hasNamespace(apiName);
if (!rpcHttpApis.stream().allMatch(configuredApis)) {
throw new ParameterException(this.commandLine, "Invalid value for option '--rpc-http-apis'");
}
if (!rpcWsApis.stream().allMatch(configuredApis)) {
throw new ParameterException(this.commandLine, "Invalid value for option '--rpc-ws-apis'");
}
}
private GenesisConfigOptions readGenesisConfigOptions() {
final GenesisConfigOptions genesisConfigOptions;
try {
@@ -1993,7 +2015,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private Optional<PermissioningConfiguration> permissioningConfiguration() throws Exception {
if (!(localPermissionsEnabled() || contractPermissionsEnabled())) {
if (rpcHttpApis.contains(RpcApis.PERM) || rpcWsApis.contains(RpcApis.PERM)) {
if (rpcHttpApis.contains(RpcApis.PERM.name()) || rpcWsApis.contains(RpcApis.PERM.name())) {
logger.warn(
"Permissions are disabled. Cannot enable PERM APIs when not using Permissions.");
}
@@ -2225,7 +2247,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
if (!isGoQuorumCompatibilityMode
&& (rpcHttpApis.contains(RpcApis.GOQUORUM) || rpcWsApis.contains(RpcApis.GOQUORUM))) {
&& (rpcHttpApis.contains(RpcApis.GOQUORUM.name())
|| rpcWsApis.contains(RpcApis.GOQUORUM.name()))) {
logger.warn("Cannot use GOQUORUM API methods when not in GoQuorum mode.");
}
privacyParametersBuilder.setPrivacyService(privacyPluginPluginService);
@@ -2248,10 +2271,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
}
private boolean anyPrivacyApiEnabled() {
return rpcHttpApis.contains(RpcApis.EEA)
|| rpcWsApis.contains(RpcApis.EEA)
|| rpcHttpApis.contains(RpcApis.PRIV)
|| rpcWsApis.contains(RpcApis.PRIV);
return rpcHttpApis.contains(RpcApis.EEA.name())
|| rpcWsApis.contains(RpcApis.EEA.name())
|| rpcHttpApis.contains(RpcApis.PRIV.name())
|| rpcWsApis.contains(RpcApis.PRIV.name());
}
private PrivacyKeyValueStorageProvider privacyKeyStorageProvider(final String name) {
@@ -2381,6 +2404,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.ethstatsContact(ethstatsOptions.getEthstatsContact())
.storageProvider(keyValueStorageProvider(keyValueStorageName))
.forkIdSupplier(() -> besuController.getProtocolManager().getForkIdAsBytesList())
.rpcEndpointService(rpcEndpointServiceImpl)
.build();
addShutdownHook(runner);

View File

@@ -1,42 +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.cli.converter;
import org.hyperledger.besu.cli.converter.exception.RpcApisConversionException;
import org.hyperledger.besu.consensus.clique.jsonrpc.CliqueRpcApis;
import org.hyperledger.besu.consensus.ibft.jsonrpc.IbftRpcApis;
import org.hyperledger.besu.consensus.qbft.jsonrpc.QbftRpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import picocli.CommandLine;
public class RpcApisConverter implements CommandLine.ITypeConverter<RpcApi> {
@Override
public RpcApi convert(final String name) throws RpcApisConversionException {
return Stream.<Function<String, Optional<RpcApi>>>of(
RpcApis::valueOf, CliqueRpcApis::valueOf, IbftRpcApis::valueOf, QbftRpcApis::valueOf)
.map(f -> f.apply(name.trim().toUpperCase()))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst()
.orElseThrow(() -> new RpcApisConversionException(name));
}
}

View File

@@ -20,7 +20,6 @@ import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.config.PowAlgorithm;
import org.hyperledger.besu.crypto.NodeKey;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.methods.JsonRpcMethods;
import org.hyperledger.besu.ethereum.blockcreation.MiningCoordinator;
@@ -156,7 +155,7 @@ public class BesuController implements java.io.Closeable {
}
public Map<String, JsonRpcMethod> getAdditionalJsonRpcMethods(
final Collection<RpcApi> enabledRpcApis) {
final Collection<String> enabledRpcApis) {
return additionalJsonRpcMethodsFactory.create(enabledRpcApis);
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.services;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.PluginJsonRpcMethod;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class RpcEndpointServiceImpl implements RpcEndpointService {
private final Map<String, Function<PluginRpcRequest, ?>> rpcMethods = new HashMap<>();
@Override
public <T> void registerRPCEndpoint(
final String namespace,
final String functionName,
final Function<PluginRpcRequest, T> function) {
checkArgument(namespace.matches("\\p{Alnum}+"), "Namespace must be only alpha numeric");
checkArgument(functionName.matches("\\p{Alnum}+"), "Function Name must be only alpha numeric");
checkNotNull(function);
rpcMethods.put(namespace + "_" + functionName, function);
}
public Map<String, ? extends JsonRpcMethod> getPluginMethods(
final Collection<String> namespaces) {
return rpcMethods.entrySet().stream()
.filter(
entry ->
namespaces.stream()
.anyMatch(
namespace ->
entry.getKey().toUpperCase().startsWith(namespace.toUpperCase())))
.map(entry -> new PluginJsonRpcMethod(entry.getKey(), entry.getValue()))
.collect(Collectors.toMap(PluginJsonRpcMethod::getName, e -> e));
}
public boolean hasNamespace(final String namespace) {
return rpcMethods.keySet().stream()
.anyMatch(key -> key.toUpperCase().startsWith(namespace.toUpperCase()));
}
}

View File

@@ -57,6 +57,7 @@ import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.nat.NatMethod;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
@@ -142,6 +143,7 @@ public final class RunnerBuilderTest {
.dataDir(dataDir.getRoot().toPath())
.storageProvider(mock(KeyValueStorageProvider.class))
.forkIdSupplier(() -> Collections.singletonList(Bytes.EMPTY))
.rpcEndpointService(new RpcEndpointServiceImpl())
.build();
runner.start();
@@ -185,6 +187,7 @@ public final class RunnerBuilderTest {
.dataDir(dataDir.getRoot().toPath())
.storageProvider(storageProvider)
.forkIdSupplier(() -> Collections.singletonList(Bytes.EMPTY))
.rpcEndpointService(new RpcEndpointServiceImpl())
.build();
runner.start();
when(besuController.getProtocolSchedule().streamMilestoneBlocks())

View File

@@ -60,6 +60,7 @@ import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksD
import org.hyperledger.besu.services.BesuConfigurationImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import org.hyperledger.besu.testutil.TestClock;
import java.math.BigInteger;
@@ -211,7 +212,8 @@ public final class RunnerTest {
.permissioningService(new PermissioningServiceImpl())
.staticNodes(emptySet())
.storageProvider(new InMemoryKeyValueStorageProvider())
.forkIdSupplier(() -> Collections.singletonList(Bytes.EMPTY));
.forkIdSupplier(() -> Collections.singletonList(Bytes.EMPTY))
.rpcEndpointService(new RpcEndpointServiceImpl());
Runner runnerBehind = null;
final Runner runnerAhead =
@@ -226,6 +228,7 @@ public final class RunnerTest {
.pidPath(pidPath)
.besuPluginContext(new BesuPluginContextImpl())
.forkIdSupplier(() -> controllerAhead.getProtocolManager().getForkIdAsBytesList())
.rpcEndpointService(new RpcEndpointServiceImpl())
.build();
try {

View File

@@ -57,7 +57,6 @@ import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.api.tls.TlsConfiguration;
import org.hyperledger.besu.ethereum.core.MiningParameters;
@@ -76,6 +75,7 @@ import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.nat.NatMethod;
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import org.hyperledger.besu.util.number.Fraction;
import org.hyperledger.besu.util.number.Percentage;
@@ -93,6 +93,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -315,7 +316,7 @@ public class BesuCommandTest extends CommandTestAbstract {
final Path toml = createTempFile("toml", updatedConfig.getBytes(UTF_8));
final List<RpcApi> expectedApis = asList(ETH, WEB3);
final List<String> expectedApis = asList(ETH.name(), WEB3.name());
final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault();
jsonRpcConfiguration.setEnabled(false);
@@ -1823,7 +1824,7 @@ public class BesuCommandTest extends CommandTestAbstract {
.warn("Permissions are disabled. Cannot enable PERM APIs when not using Permissions.");
assertThat(jsonRpcConfigArgumentCaptor.getValue().getRpcApis())
.containsExactlyInAnyOrder(ETH, NET, PERM);
.containsExactlyInAnyOrder(ETH.name(), NET.name(), PERM.name());
assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).isEmpty();
@@ -1837,7 +1838,7 @@ public class BesuCommandTest extends CommandTestAbstract {
verify(mockRunnerBuilder).build();
assertThat(jsonRpcConfigArgumentCaptor.getValue().getRpcApis())
.containsExactlyInAnyOrder(ETH, NET);
.containsExactlyInAnyOrder(ETH.name(), NET.name());
assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).isEmpty();
@@ -1927,6 +1928,24 @@ public class BesuCommandTest extends CommandTestAbstract {
.contains("Invalid value for option '--rpc-http-apis'");
}
@Test
public void rpcApisPropertyWithPluginNamespaceAreValid() {
rpcEndpointServiceImpl.registerRPCEndpoint(
"bob", "method", (Function<PluginRpcRequest, Object>) request -> "nothing");
parseCommand("--rpc-http-api", "BOB");
verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
verify(mockRunnerBuilder).build();
assertThat(jsonRpcConfigArgumentCaptor.getValue().getRpcApis())
.containsExactlyInAnyOrder("BOB");
assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).isEmpty();
}
@Test
public void rpcHttpHostAndPortOptionsMustBeUsed() {
@@ -2682,7 +2701,7 @@ public class BesuCommandTest extends CommandTestAbstract {
verify(mockRunnerBuilder).build();
assertThat(wsRpcConfigArgumentCaptor.getValue().getRpcApis())
.containsExactlyInAnyOrder(ETH, NET);
.containsExactlyInAnyOrder(ETH.name(), NET.name());
assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).isEmpty();

View File

@@ -75,6 +75,7 @@ import org.hyperledger.besu.plugin.services.storage.PrivacyKeyValueStorageFactor
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.PrivacyPluginServiceImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import org.hyperledger.besu.services.SecurityModuleServiceImpl;
import org.hyperledger.besu.services.StorageServiceImpl;
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
@@ -133,6 +134,9 @@ public abstract class CommandTestAbstract {
private final List<TestBesuCommand> besuCommands = new ArrayList<>();
private KeyPair keyPair;
protected static final RpcEndpointServiceImpl rpcEndpointServiceImpl =
new RpcEndpointServiceImpl();
@Mock protected RunnerBuilder mockRunnerBuilder;
@Mock protected Runner mockRunner;
@@ -275,6 +279,7 @@ public abstract class CommandTestAbstract {
when(mockRunnerBuilder.ethstatsContact(anyString())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.storageProvider(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.forkIdSupplier(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.rpcEndpointService(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.build()).thenReturn(mockRunner);
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance();
@@ -409,7 +414,8 @@ public abstract class CommandTestAbstract {
securityModuleService,
new PermissioningServiceImpl(),
new PrivacyPluginServiceImpl(),
pkiBlockCreationConfigProvider);
pkiBlockCreationConfigProvider,
rpcEndpointServiceImpl);
}
@Override

View File

@@ -26,7 +26,7 @@ import org.hyperledger.besu.consensus.common.EpochManager;
import org.hyperledger.besu.consensus.common.validator.ValidatorProvider;
import org.hyperledger.besu.consensus.common.validator.blockbased.BlockValidatorProvider;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.methods.ApiGroupJsonRpcMethods;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
@@ -43,8 +43,8 @@ public class CliqueJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return CliqueRpcApis.CLIQUE;
protected String getApiGroup() {
return RpcApis.CLIQUE.name();
}
@Override

View File

@@ -1,31 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.clique.jsonrpc;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import java.util.Optional;
public class CliqueRpcApis {
public static final RpcApi CLIQUE = new RpcApi("CLIQUE");
public static final Optional<RpcApi> valueOf(final String name) {
if (name.equals(CLIQUE.getCliValue())) {
return Optional.of(CLIQUE);
} else {
return Optional.empty();
}
}
}

View File

@@ -27,7 +27,7 @@ import org.hyperledger.besu.consensus.ibft.jsonrpc.methods.IbftGetValidatorsByBl
import org.hyperledger.besu.consensus.ibft.jsonrpc.methods.IbftGetValidatorsByBlockNumber;
import org.hyperledger.besu.consensus.ibft.jsonrpc.methods.IbftProposeValidatorVote;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.methods.ApiGroupJsonRpcMethods;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
@@ -44,8 +44,8 @@ public class IbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return IbftRpcApis.IBFT;
protected String getApiGroup() {
return RpcApis.IBFT.name();
}
@Override

View File

@@ -27,7 +27,7 @@ import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBl
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftGetValidatorsByBlockNumber;
import org.hyperledger.besu.consensus.qbft.jsonrpc.methods.QbftProposeValidatorVote;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.methods.ApiGroupJsonRpcMethods;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
@@ -44,8 +44,8 @@ public class QbftJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return QbftRpcApis.QBFT;
protected String getApiGroup() {
return RpcApis.QBFT.name();
}
@Override

View File

@@ -1,31 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.qbft.jsonrpc;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import java.util.Optional;
public class QbftRpcApis {
public static final RpcApi QBFT = new RpcApi("QBFT");
public static final Optional<RpcApi> valueOf(final String name) {
if (name.equals(QBFT.getCliValue())) {
return Optional.of(QBFT);
} else {
return Optional.empty();
}
}
}

View File

@@ -146,12 +146,12 @@ public class JsonRpcTestMethodsFactory {
final MetricsConfiguration metricsConfiguration = mock(MetricsConfiguration.class);
final NatService natService = new NatService(Optional.empty());
final List<RpcApi> apis = new ArrayList<>();
apis.add(RpcApis.ETH);
apis.add(RpcApis.NET);
apis.add(RpcApis.WEB3);
apis.add(RpcApis.PRIV);
apis.add(RpcApis.DEBUG);
final List<String> apis = new ArrayList<>();
apis.add(RpcApis.ETH.name());
apis.add(RpcApis.NET.name());
apis.add(RpcApis.WEB3.name());
apis.add(RpcApis.PRIV.name());
apis.add(RpcApis.DEBUG.name());
final Path dataDir = mock(Path.class);

View File

@@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions;
import org.hyperledger.besu.ethereum.api.tls.TlsConfiguration;
@@ -37,7 +39,7 @@ public class JsonRpcConfiguration {
private int port;
private String host;
private List<String> corsAllowedDomains = Collections.emptyList();
private List<RpcApi> rpcApis;
private List<String> rpcApis;
private List<String> hostsAllowlist = Arrays.asList("localhost", "127.0.0.1");
private boolean authenticationEnabled = false;
private String authenticationCredentialsFile;
@@ -51,7 +53,7 @@ public class JsonRpcConfiguration {
config.setEnabled(false);
config.setPort(DEFAULT_JSON_RPC_PORT);
config.setHost(DEFAULT_JSON_RPC_HOST);
config.rpcApis = RpcApis.DEFAULT_JSON_RPC_APIS;
config.setRpcApis(DEFAULT_RPC_APIS);
config.httpTimeoutSec = TimeoutOptions.defaultOptions().getTimeoutSeconds();
config.setMaxActiveConnections(DEFAULT_MAX_ACTIVE_CONNECTIONS);
return config;
@@ -93,15 +95,15 @@ public class JsonRpcConfiguration {
}
}
public Collection<RpcApi> getRpcApis() {
public Collection<String> getRpcApis() {
return rpcApis;
}
public void setRpcApis(final List<RpcApi> rpcApis) {
public void setRpcApis(final List<String> rpcApis) {
this.rpcApis = rpcApis;
}
public void addRpcApi(final RpcApi rpcApi) {
public void addRpcApi(final String rpcApi) {
this.rpcApis = new ArrayList<>(rpcApis);
rpcApis.add(rpcApi);
}

View File

@@ -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.ethereum.api.jsonrpc;
import java.util.Objects;
public class RpcApi {
private final String cliValue;
public RpcApi(final String cliValue) {
this.cliValue = cliValue;
}
public String getCliValue() {
return cliValue;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final RpcApi rpcApi = (RpcApi) o;
return Objects.equals(cliValue, rpcApi.cliValue);
}
@Override
public int hashCode() {
return Objects.hashCode(cliValue);
}
@Override
public String toString() {
return cliValue;
}
}

View File

@@ -16,63 +16,24 @@ package org.hyperledger.besu.ethereum.api.jsonrpc;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class RpcApis {
public enum RpcApis {
ETH,
DEBUG,
MINER,
NET,
PERM,
WEB3,
ADMIN,
EEA,
PRIV,
TXPOOL,
TRACE,
PLUGINS,
GOQUORUM,
CLIQUE,
IBFT,
QBFT;
public static final RpcApi ETH = new RpcApi("ETH");
public static final RpcApi DEBUG = new RpcApi("DEBUG");
public static final RpcApi MINER = new RpcApi("MINER");
public static final RpcApi NET = new RpcApi("NET");
public static final RpcApi PERM = new RpcApi("PERM");
public static final RpcApi WEB3 = new RpcApi("WEB3");
public static final RpcApi ADMIN = new RpcApi("ADMIN");
public static final RpcApi EEA = new RpcApi("EEA");
public static final RpcApi PRIV = new RpcApi("PRIV");
public static final RpcApi TX_POOL = new RpcApi("TXPOOL");
public static final RpcApi TRACE = new RpcApi("TRACE");
public static final RpcApi PLUGINS = new RpcApi("PLUGINS");
public static final RpcApi GOQUORUM = new RpcApi("GOQUORUM");
public static final List<RpcApi> DEFAULT_JSON_RPC_APIS = Arrays.asList(ETH, NET, WEB3);
@SuppressWarnings("unused")
public static final List<RpcApi> ALL_JSON_RPC_APIS =
Arrays.asList(ETH, DEBUG, MINER, NET, PERM, WEB3, ADMIN, EEA, PRIV, TX_POOL, TRACE, PLUGINS);
public static Optional<RpcApi> valueOf(final String name) {
if (name.equals(ETH.getCliValue())) {
return Optional.of(ETH);
} else if (name.equals(DEBUG.getCliValue())) {
return Optional.of(DEBUG);
} else if (name.equals(MINER.getCliValue())) {
return Optional.of(MINER);
} else if (name.equals(NET.getCliValue())) {
return Optional.of(NET);
} else if (name.equals(PERM.getCliValue())) {
return Optional.of(PERM);
} else if (name.equals(WEB3.getCliValue())) {
return Optional.of(WEB3);
} else if (name.equals(ADMIN.getCliValue())) {
return Optional.of(ADMIN);
} else if (name.equals(EEA.getCliValue())) {
return Optional.of(EEA);
} else if (name.equals(PRIV.getCliValue())) {
return Optional.of(PRIV);
} else if (name.equals(TX_POOL.getCliValue())) {
return Optional.of(TX_POOL);
} else if (name.equals(TRACE.getCliValue())) {
return Optional.of(TRACE);
} else if (name.equals(PLUGINS.getCliValue())) {
return Optional.of(PLUGINS);
} else if (name.equals(GOQUORUM.getCliValue())) {
return Optional.of(GOQUORUM);
} else {
return Optional.empty();
}
}
public static String getValue(final RpcApi rpcapi) {
return rpcapi.getCliValue();
}
public static final List<String> DEFAULT_RPC_APIS = Arrays.asList("ETH", "NET", "WEB3");
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INTERNAL_ERROR;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
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.plugin.services.rpc.PluginRpcRequest;
import java.util.function.Function;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class PluginJsonRpcMethod implements JsonRpcMethod {
private static final Logger LOG = LogManager.getLogger();
private final String name;
private final Function<PluginRpcRequest, ?> function;
public PluginJsonRpcMethod(final String name, final Function<PluginRpcRequest, ?> function) {
this.name = name;
this.function = function;
}
@Override
public String getName() {
return name;
}
@Override
public JsonRpcResponse response(final JsonRpcRequestContext request) {
try {
Object result = function.apply(() -> request.getRequest().getParams());
return new JsonRpcSuccessResponse(request.getRequest().getId(), result);
} catch (Exception ex) {
LOG.error("Error calling plugin JSON-RPC endpoint", ex);
return new JsonRpcErrorResponse(request.getRequest().getId(), INTERNAL_ERROR);
}
}
}

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.response.JsonRpcResponse;
@@ -29,10 +28,9 @@ public class RpcModules implements JsonRpcMethod {
private final Map<String, String> moduleVersions;
public RpcModules(final Collection<RpcApi> modulesList) {
public RpcModules(final Collection<String> modulesList) {
this.moduleVersions =
modulesList.stream()
.map(RpcApi::getCliValue)
.map(String::toLowerCase)
.collect(Collectors.toMap(Function.identity(), s -> "1.0"));
}

View File

@@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AdminAddPeer;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AdminChangeLogLevel;
@@ -67,8 +66,8 @@ public class AdminJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.ADMIN;
protected String getApiGroup() {
return RpcApis.ADMIN.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import java.util.Arrays;
@@ -26,11 +25,11 @@ import java.util.stream.Collectors;
public abstract class ApiGroupJsonRpcMethods implements JsonRpcMethods {
@Override
public Map<String, JsonRpcMethod> create(final Collection<RpcApi> apis) {
public Map<String, JsonRpcMethod> create(final Collection<String> apis) {
return apis.contains(getApiGroup()) ? create() : Collections.emptyMap();
}
protected abstract RpcApi getApiGroup();
protected abstract String getApiGroup();
protected abstract Map<String, JsonRpcMethod> create();

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.DebugAccountAt;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.DebugAccountRange;
@@ -66,8 +65,8 @@ public class DebugJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.DEBUG;
protected String getApiGroup() {
return RpcApis.DEBUG.name();
}
@Override

View File

@@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.LatestNonceProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.privacy.methods.PrivacyIdProvider;
@@ -89,7 +88,7 @@ public class EeaJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.EEA;
protected String getApiGroup() {
return RpcApis.EEA.name();
}
}

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.EthAccounts;
@@ -108,8 +107,8 @@ public class EthJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.ETH;
protected String getApiGroup() {
return RpcApis.ETH.name();
}
@Override

View File

@@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.enclave.GoQuorumEnclave;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.privacy.methods.PrivacyIdProvider;
@@ -66,7 +65,7 @@ public class GoQuorumJsonRpcPrivacyMethods extends PrivacyApiGroupJsonRpcMethods
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.GOQUORUM;
protected String getApiGroup() {
return RpcApis.GOQUORUM.name();
}
}

View File

@@ -14,12 +14,11 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import java.util.Collection;
import java.util.Map;
public interface JsonRpcMethods {
Map<String, JsonRpcMethod> create(Collection<RpcApi> enabledRpcApis);
Map<String, JsonRpcMethod> create(Collection<String> enabledRpcApis);
}

View File

@@ -16,7 +16,6 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.config.GenesisConfigOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.RpcModules;
@@ -63,7 +62,7 @@ public class JsonRpcMethodsFactory {
final Set<Capability> supportedCapabilities,
final Optional<AccountLocalConfigPermissioningController> accountsAllowlistController,
final Optional<NodeLocalConfigPermissioningController> nodeAllowlistController,
final Collection<RpcApi> rpcApis,
final Collection<String> rpcApis,
final PrivacyParameters privacyParameters,
final JsonRpcConfiguration jsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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;
@@ -35,8 +34,8 @@ public class MinerJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.MINER;
protected String getApiGroup() {
return RpcApis.MINER.name();
}
@Override

View File

@@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.NetEnode;
@@ -53,8 +52,8 @@ public class NetJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.NET;
protected String getApiGroup() {
return RpcApis.NET.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.permissioning.PermAddAccountsToAllowlist;
@@ -49,8 +48,8 @@ public class PermJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.PERM;
protected String getApiGroup() {
return RpcApis.PERM.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.PluginsReloadConfiguration;
@@ -31,8 +30,8 @@ public class PluginsJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.PLUGINS;
protected String getApiGroup() {
return RpcApis.PLUGINS.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
@@ -59,8 +58,8 @@ public class PrivJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.PRIV;
protected String getApiGroup() {
return RpcApis.PRIV.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.privacy.methods.PrivacyIdProvider;
@@ -39,8 +38,8 @@ public class PrivxJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.PRIV;
protected String getApiGroup() {
return RpcApis.PRIV.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.TraceBlock;
@@ -39,9 +38,9 @@ public class TraceJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
protected String getApiGroup() {
// Disable TRACE functionality while under development
return RpcApis.TRACE;
return RpcApis.TRACE.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.TxPoolBesuPendingTransactions;
@@ -33,8 +32,8 @@ public class TxPoolJsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.TX_POOL;
protected String getApiGroup() {
return RpcApis.TXPOOL.name();
}
@Override

View File

@@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
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.Web3ClientVersion;
@@ -31,8 +30,8 @@ public class Web3JsonRpcMethods extends ApiGroupJsonRpcMethods {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.WEB3;
protected String getApiGroup() {
return RpcApis.WEB3.name();
}
@Override

View File

@@ -14,9 +14,9 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.websocket;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import org.hyperledger.besu.ethereum.api.handlers.TimeoutOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import java.io.File;
import java.util.Arrays;
@@ -30,14 +30,12 @@ import com.google.common.base.MoreObjects;
public class WebSocketConfiguration {
public static final String DEFAULT_WEBSOCKET_HOST = "127.0.0.1";
public static final int DEFAULT_WEBSOCKET_PORT = 8546;
public static final List<RpcApi> DEFAULT_WEBSOCKET_APIS =
Arrays.asList(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3);
public static final int DEFAULT_MAX_ACTIVE_CONNECTIONS = 80;
private boolean enabled;
private int port;
private String host;
private List<RpcApi> rpcApis;
private List<String> rpcApis;
private boolean authenticationEnabled = false;
private String authenticationCredentialsFile;
private List<String> hostsAllowlist = Arrays.asList("localhost", "127.0.0.1");
@@ -50,7 +48,7 @@ public class WebSocketConfiguration {
config.setEnabled(false);
config.setHost(DEFAULT_WEBSOCKET_HOST);
config.setPort(DEFAULT_WEBSOCKET_PORT);
config.setRpcApis(DEFAULT_WEBSOCKET_APIS);
config.setRpcApis(DEFAULT_RPC_APIS);
config.setTimeoutSec(TimeoutOptions.defaultOptions().getTimeoutSeconds());
config.setMaxActiveConnections(DEFAULT_MAX_ACTIVE_CONNECTIONS);
return config;
@@ -82,11 +80,11 @@ public class WebSocketConfiguration {
return port;
}
public Collection<RpcApi> getRpcApis() {
public Collection<String> getRpcApis() {
return rpcApis;
}
public void setRpcApis(final List<RpcApi> rpcApis) {
public void setRpcApis(final List<String> rpcApis) {
this.rpcApis = rpcApis;
}

View File

@@ -74,8 +74,13 @@ public abstract class AbstractJsonRpcHttpServiceTest {
protected static String CLIENT_VERSION = "TestClientVersion/0.1.0";
protected static final BigInteger NETWORK_ID = BigInteger.valueOf(123);
protected static final Collection<RpcApi> JSON_RPC_APIS =
Arrays.asList(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3, RpcApis.DEBUG, RpcApis.TRACE);
protected static final Collection<String> JSON_RPC_APIS =
Arrays.asList(
RpcApis.ETH.name(),
RpcApis.NET.name(),
RpcApis.WEB3.name(),
RpcApis.DEBUG.name(),
RpcApis.TRACE.name());
protected final Vertx vertx = Vertx.vertx();
protected JsonRpcHttpService service;

View File

@@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import java.util.Optional;
@@ -31,8 +32,7 @@ public class JsonRpcConfigurationTest {
assertThat(configuration.getHost()).isEqualTo("127.0.0.1");
assertThat(configuration.getPort()).isEqualTo(8545);
assertThat(configuration.getCorsAllowedDomains()).isEmpty();
assertThat(configuration.getRpcApis())
.containsExactlyInAnyOrder(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3);
assertThat(configuration.getRpcApis()).containsExactlyInAnyOrderElementsOf(DEFAULT_RPC_APIS);
assertThat(configuration.getMaxActiveConnections())
.isEqualTo(JsonRpcConfiguration.DEFAULT_MAX_ACTIVE_CONNECTIONS);
}
@@ -46,7 +46,7 @@ public class JsonRpcConfigurationTest {
@Test
public void rpcApiDefaultShouldBePredefinedList() {
final JsonRpcConfiguration configuration = JsonRpcConfiguration.createDefault();
assertThat(configuration.getRpcApis()).containsExactly(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3);
assertThat(configuration.getRpcApis()).containsExactlyElementsOf(DEFAULT_RPC_APIS);
}
@Test
@@ -64,11 +64,12 @@ public class JsonRpcConfigurationTest {
public void settingRpcApisShouldOverridePreviousValues() {
final JsonRpcConfiguration configuration = JsonRpcConfiguration.createDefault();
configuration.setRpcApis(Lists.newArrayList(RpcApis.ETH, RpcApis.MINER));
assertThat(configuration.getRpcApis()).containsExactly(RpcApis.ETH, RpcApis.MINER);
configuration.setRpcApis(Lists.newArrayList(RpcApis.ETH.name(), RpcApis.MINER.name()));
assertThat(configuration.getRpcApis())
.containsExactly(RpcApis.ETH.name(), RpcApis.MINER.name());
configuration.setRpcApis(Lists.newArrayList(RpcApis.DEBUG));
assertThat(configuration.getRpcApis()).containsExactly(RpcApis.DEBUG);
configuration.setRpcApis(Lists.newArrayList(RpcApis.DEBUG.name()));
assertThat(configuration.getRpcApis()).containsExactly(RpcApis.DEBUG.name());
}
@Test

View File

@@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -43,7 +44,6 @@ import org.hyperledger.besu.nat.NatService;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -77,8 +77,7 @@ public class JsonRpcHttpServiceHostAllowlistTest {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
private static final Collection<RpcApi> JSON_RPC_APIS =
Arrays.asList(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3);
private final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig();
private final NatService natService = new NatService(Optional.empty());
@@ -113,7 +112,7 @@ public class JsonRpcHttpServiceHostAllowlistTest {
supportedCapabilities,
Optional.of(mock(AccountLocalConfigPermissioningController.class)),
Optional.of(mock(NodeLocalConfigPermissioningController.class)),
JSON_RPC_APIS,
DEFAULT_RPC_APIS,
mock(PrivacyParameters.class),
mock(JsonRpcConfiguration.class),
mock(WebSocketConfiguration.class),

View File

@@ -101,8 +101,9 @@ public class JsonRpcHttpServiceLoginTest {
protected static P2PNetwork peerDiscoveryMock;
protected static BlockchainQueries blockchainQueries;
protected static Synchronizer synchronizer;
protected static final Collection<RpcApi> JSON_RPC_APIS =
Arrays.asList(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3, RpcApis.ADMIN);
protected static final Collection<String> JSON_RPC_APIS =
Arrays.asList(
RpcApis.ETH.name(), RpcApis.NET.name(), RpcApis.WEB3.name(), RpcApis.ADMIN.name());
protected static JWTAuth jwtAuth;
protected static String authPermissionsConfigFilePath = "JsonRpcHttpService/auth.toml";
protected final JsonRpcTestHelper testHelper = new JsonRpcTestHelper();

View File

@@ -125,7 +125,7 @@ public class JsonRpcHttpServiceRpcApisTest {
@Test
public void requestWithNetMethodShouldSucceedWhenNetApiIsEnabled() throws Exception {
service = createJsonRpcHttpServiceWithRpcApis(RpcApis.NET);
service = createJsonRpcHttpServiceWithRpcApis(RpcApis.NET.name());
final String id = "123";
final RequestBody body =
RequestBody.create(
@@ -140,7 +140,7 @@ public class JsonRpcHttpServiceRpcApisTest {
@Test
public void requestWithNetMethodShouldSuccessWithCode200WhenNetApiIsNotEnabled()
throws Exception {
service = createJsonRpcHttpServiceWithRpcApis(RpcApis.WEB3);
service = createJsonRpcHttpServiceWithRpcApis(RpcApis.WEB3.name());
final String id = "123";
final RequestBody body =
RequestBody.create(
@@ -159,7 +159,7 @@ public class JsonRpcHttpServiceRpcApisTest {
@Test
public void requestWithNetMethodShouldSucceedWhenNetApiAndOtherIsEnabled() throws Exception {
service = createJsonRpcHttpServiceWithRpcApis(RpcApis.NET, RpcApis.WEB3);
service = createJsonRpcHttpServiceWithRpcApis(RpcApis.NET.name(), RpcApis.WEB3.name());
final String id = "123";
final RequestBody body =
RequestBody.create(
@@ -171,7 +171,7 @@ public class JsonRpcHttpServiceRpcApisTest {
}
}
private JsonRpcConfiguration createJsonRpcConfigurationWithRpcApis(final RpcApi... rpcApis) {
private JsonRpcConfiguration createJsonRpcConfigurationWithRpcApis(final String... rpcApis) {
final JsonRpcConfiguration config = JsonRpcConfiguration.createDefault();
config.setCorsAllowedDomains(singletonList("*"));
config.setPort(0);
@@ -181,7 +181,7 @@ public class JsonRpcHttpServiceRpcApisTest {
return config;
}
private JsonRpcHttpService createJsonRpcHttpServiceWithRpcApis(final RpcApi... rpcApis)
private JsonRpcHttpService createJsonRpcHttpServiceWithRpcApis(final String... rpcApis)
throws Exception {
return createJsonRpcHttpServiceWithRpcApis(createJsonRpcConfigurationWithRpcApis(rpcApis));
}

View File

@@ -82,8 +82,9 @@ public class JsonRpcHttpServiceTestBase {
protected static BlockchainQueries blockchainQueries;
protected static ChainHead chainHead;
protected static Synchronizer synchronizer;
protected static final Collection<RpcApi> JSON_RPC_APIS =
Arrays.asList(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3, RpcApis.ADMIN);
protected static final Collection<String> JSON_RPC_APIS =
Arrays.asList(
RpcApis.ETH.name(), RpcApis.NET.name(), RpcApis.WEB3.name(), RpcApis.ADMIN.name());
protected static final NatService natService = new NatService(Optional.empty());
protected static int maxConnections = 80;

View File

@@ -16,9 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIOException;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ETH;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.NET;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.WEB3;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.tls.KnownClientFileUtil.writeToKnownClientsFile;
import static org.hyperledger.besu.ethereum.api.tls.TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration;
import static org.hyperledger.besu.ethereum.api.tls.TlsConfiguration.Builder.aTlsConfiguration;
@@ -55,10 +53,8 @@ import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -88,7 +84,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
private static final String JSON_HEADER = "application/json; charset=utf-8";
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
private static final Collection<RpcApi> JSON_RPC_APIS = List.of(ETH, NET, WEB3);
private static final NatService natService = new NatService(Optional.empty());
private static final SelfSignedP12Certificate CLIENT_AS_CA_CERT =
SelfSignedP12Certificate.create();
@@ -131,7 +127,7 @@ public class JsonRpcHttpServiceTlsClientAuthTest {
supportedCapabilities,
Optional.of(mock(AccountLocalConfigPermissioningController.class)),
Optional.of(mock(NodeLocalConfigPermissioningController.class)),
JSON_RPC_APIS,
DEFAULT_RPC_APIS,
mock(PrivacyParameters.class),
mock(JsonRpcConfiguration.class),
mock(WebSocketConfiguration.class),

View File

@@ -15,9 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ETH;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.NET;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.WEB3;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.tls.KnownClientFileUtil.writeToKnownClientsFile;
import static org.hyperledger.besu.ethereum.api.tls.TlsClientAuthConfiguration.Builder.aTlsClientAuthConfiguration;
import static org.hyperledger.besu.ethereum.api.tls.TlsConfiguration.Builder.aTlsConfiguration;
@@ -54,7 +52,6 @@ import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -78,7 +75,6 @@ public class JsonRpcHttpServiceTlsMisconfigurationTest {
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
private static final Collection<RpcApi> JSON_RPC_APIS = List.of(ETH, NET, WEB3);
private static final NatService natService = new NatService(Optional.empty());
private final SelfSignedP12Certificate besuCertificate = SelfSignedP12Certificate.create();
private Path knownClientsFile;
@@ -119,7 +115,7 @@ public class JsonRpcHttpServiceTlsMisconfigurationTest {
supportedCapabilities,
Optional.of(mock(AccountLocalConfigPermissioningController.class)),
Optional.of(mock(NodeLocalConfigPermissioningController.class)),
JSON_RPC_APIS,
DEFAULT_RPC_APIS,
mock(PrivacyParameters.class),
mock(JsonRpcConfiguration.class),
mock(WebSocketConfiguration.class),

View File

@@ -17,9 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc;
import static okhttp3.Protocol.HTTP_1_1;
import static okhttp3.Protocol.HTTP_2;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ETH;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.NET;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.WEB3;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.tls.TlsConfiguration.Builder.aTlsConfiguration;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -54,10 +52,8 @@ import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -85,7 +81,6 @@ public class JsonRpcHttpServiceTlsTest {
private static final String JSON_HEADER = "application/json; charset=utf-8";
private static final String CLIENT_VERSION = "TestClientVersion/0.1.0";
private static final BigInteger CHAIN_ID = BigInteger.valueOf(123);
private static final Collection<RpcApi> JSON_RPC_APIS = List.of(ETH, NET, WEB3);
private static final NatService natService = new NatService(Optional.empty());
private JsonRpcHttpService service;
private String baseUrl;
@@ -122,7 +117,7 @@ public class JsonRpcHttpServiceTlsTest {
supportedCapabilities,
Optional.of(mock(AccountLocalConfigPermissioningController.class)),
Optional.of(mock(NodeLocalConfigPermissioningController.class)),
JSON_RPC_APIS,
DEFAULT_RPC_APIS,
mock(PrivacyParameters.class),
mock(JsonRpcConfiguration.class),
mock(WebSocketConfiguration.class),

View File

@@ -36,7 +36,7 @@ public class RpcModulesTest {
@Before
public void setUp() {
method = new RpcModules(ImmutableList.of(RpcApis.DEBUG));
method = new RpcModules(ImmutableList.of(RpcApis.DEBUG.name()));
}
@Test

View File

@@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.PRIVACY_NOT_ENABLED;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
@@ -189,8 +188,8 @@ public class PrivacyApiGroupJsonRpcMethodsTest {
}
@Override
protected RpcApi getApiGroup() {
return RpcApis.PRIV;
protected String getApiGroup() {
return RpcApis.PRIV.name();
}
}
}

View File

@@ -15,8 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.websocket;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.DEFAULT_RPC_APIS;
import org.junit.Test;
@@ -29,8 +28,7 @@ public class WebSocketConfigurationTest {
assertThat(configuration.isEnabled()).isFalse();
assertThat(configuration.getHost()).isEqualTo("127.0.0.1");
assertThat(configuration.getPort()).isEqualTo(8546);
assertThat(configuration.getRpcApis())
.containsExactlyInAnyOrder(RpcApis.ETH, RpcApis.NET, RpcApis.WEB3);
assertThat(configuration.getRpcApis()).containsExactlyInAnyOrderElementsOf(DEFAULT_RPC_APIS);
assertThat(configuration.getMaxActiveConnections())
.isEqualTo(WebSocketConfiguration.DEFAULT_MAX_ACTIVE_CONNECTIONS);
}

View File

@@ -64,7 +64,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'zpv92JZmlU6gPifGcPG5ATE6Lv/ruWdJtjLk3EVXO4g='
knownHash = 'nYb32ASSettoae0o+E+aOhGv7BvkRTXWr8/PlWlWmEA='
}
check.dependsOn('checkAPIChanges')

View File

@@ -0,0 +1,57 @@
/*
* Copyright Hyperledger Besu Contributors.
*
* 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.plugin.services;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import java.util.function.Function;
/**
* This service allows you to add functions exposed via RPC endpoints.
*
* <p>This service will be available during the registration callback and must be used during the
* registration callback. RPC endpoints are configured prior to the start callback and all endpoints
* connected. No endpoint will actually be called prior to the start callback so initialization
* unrelated to the callback registration can also be done at that time.
*/
public interface RpcEndpointService extends BesuService {
/**
* Register a function as an RPC endpoint exposed via JSON-RPC.
*
* <p>The mechanism is a Java function that takes a list of Strings and returns any Java object,
* registered in a specific namespace with a function name.
*
* <p>The resulting endpoint is the {@code namespace} and the {@code functionName} concatenated
* with an underscore to create the JSON-RPC method name.
*
* <p>The function takes a {@link PluginRpcRequest} which contains a list of the inputs expressed
* entirely as strings. Javascript numbers are converted to strings via their toString method, and
* complex input objects are not supported.
*
* <p>The output is a Java object, primitive, or array that will be inspected via <a
* href="https://github.com/FasterXML/jackson-databind">Jackson databind</a>. In general if
* JavaBeans naming patterns are followed those names will be reflected in the returned JSON
* object. If the method throws an exception the return is an error with an INTERNAL_ERROR
* treatment.
*
* @param namespace The namespace of the method, must be alphanumeric.
* @param functionName The name of the function, must be alphanumeric.
* @param function The function itself.
* @param <T> specified type of return object
*/
<T> void registerRPCEndpoint(
String namespace, String functionName, Function<PluginRpcRequest, T> function);
}

View File

@@ -12,20 +12,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.consensus.ibft.jsonrpc;
package org.hyperledger.besu.plugin.services.rpc;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import java.util.Optional;
public class IbftRpcApis {
public static final RpcApi IBFT = new RpcApi("IBFT");
public static final Optional<RpcApi> valueOf(final String name) {
if (name.equals(IBFT.getCliValue())) {
return Optional.of(IBFT);
} else {
return Optional.empty();
}
}
public interface PluginRpcRequest {
Object[] getParams();
}