Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 18 commits into from
Oct 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f25dadc
Initial PoC for RPC end points via the plugin mechanism.
antonydenyer Sep 13, 2021
35d619a
Make acceptance more explicit around what is being tested
antonydenyer Sep 14, 2021
cb20cfa
Remove RpcApis and switch to String
antonydenyer Sep 14, 2021
58bcf4d
Only enable plugin rpc api when enabled on --rpc-http-api or --rpc-ws…
antonydenyer Sep 15, 2021
d1ebe35
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Sep 22, 2021
01e1d5a
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Sep 23, 2021
7e1c7ac
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Sep 27, 2021
80396f3
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Sep 28, 2021
7553651
Update changelog
antonydenyer Sep 28, 2021
05479e4
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Sep 30, 2021
fc65ddf
Prevent rpc endpoints from being overridden
antonydenyer Sep 30, 2021
13fa025
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Oct 1, 2021
ef28dfc
fix issues based on feedback
antonydenyer Oct 1, 2021
e40f8cc
fix method name in test
antonydenyer Oct 1, 2021
aadc0a4
Fix copyright on new files
antonydenyer Oct 1, 2021
eac5a0f
tidy up javadocs
antonydenyer Oct 1, 2021
9a2be51
Fix method/function rename
antonydenyer Oct 1, 2021
39d3de4
Merge branch 'main' of github.com:hyperledger/besu into json-rpc-plugin
antonydenyer Oct 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
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;
Expand Down Expand Up @@ -447,8 +445,8 @@ private void createStaticNodes(final BesuNode node) {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
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;

Expand Down Expand Up @@ -211,6 +212,7 @@ public void startNode(final BesuNode node) {
.autoLogBloomCaching(false)
.storageProvider(storageProvider)
.forkIdSupplier(() -> besuController.getProtocolManager().getForkIdAsBytesList())
.rpcEndpointService(new RpcEndpointServiceImpl())
.build();

runner.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ public BesuNodeConfigurationBuilder miningEnabled() {
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;
}

Expand Down Expand Up @@ -143,18 +143,18 @@ public BesuNodeConfigurationBuilder metricsEnabled() {
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
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;
Expand Down Expand Up @@ -255,12 +254,14 @@ public BesuNode createPluginsNode(
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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@

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;
Expand All @@ -46,23 +45,23 @@ public Optional<String> createGenesisConfigForValidators(
}

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() {
Expand All @@ -81,12 +80,12 @@ public WebSocketConfiguration createWebSocketEnabledConfig() {
}

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

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;
Expand Down Expand Up @@ -297,9 +296,9 @@ private JsonRpcConfiguration jsonRpcConfigWithPermApiEnabled() {
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ public void register(final BesuContext context) {

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");
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Loading