Skip to content

Commit

Permalink
Add json-rpc IPC support [hyperledger#535]
Browse files Browse the repository at this point in the history
Signed-off-by: Diego López León <[email protected]>
Signed-off-by: Diego López León <[email protected]>
  • Loading branch information
diega committed Apr 22, 2022
1 parent d12a2b1 commit 4e07dd3
Show file tree
Hide file tree
Showing 21 changed files with 736 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.hyperledger.besu.crypto.KeyPairUtil;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
Expand Down Expand Up @@ -102,6 +103,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
private final JsonRpcConfiguration jsonRpcConfiguration;
private final Optional<JsonRpcConfiguration> engineRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private final MetricsConfiguration metricsConfiguration;
private Optional<PermissioningConfiguration> permissioningConfiguration;
private final GenesisConfigurationProvider genesisConfigProvider;
Expand Down Expand Up @@ -132,6 +134,7 @@ public BesuNode(
final JsonRpcConfiguration jsonRpcConfiguration,
final Optional<JsonRpcConfiguration> engineRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration,
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
final Optional<String> keyfilePath,
Expand Down Expand Up @@ -178,6 +181,7 @@ public BesuNode(
this.jsonRpcConfiguration = jsonRpcConfiguration;
this.engineRpcConfiguration = engineRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration;
this.metricsConfiguration = metricsConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.genesisConfigProvider = genesisConfigProvider;
Expand Down Expand Up @@ -234,6 +238,10 @@ private boolean isWebSocketsRpcEnabled() {
return webSocketConfiguration().isEnabled();
}

public boolean isJsonRpcIpcEnabled() {
return jsonRpcIpcConfiguration().isEnabled();
}

boolean isMetricsEnabled() {
return metricsConfiguration.isEnabled();
}
Expand Down Expand Up @@ -593,6 +601,10 @@ WebSocketConfiguration webSocketConfiguration() {
return webSocketConfiguration;
}

JsonRpcIpcConfiguration jsonRpcIpcConfiguration() {
return jsonRpcIpcConfiguration;
}

Optional<String> wsRpcListenHost() {
return Optional.of(webSocketConfiguration().getHost());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;

import org.hyperledger.besu.cli.options.unstable.NetworkingOptions;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
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 @@ -230,6 +231,15 @@ public void startNode(final BesuNode node) {
params.add("0");
}

if (node.isJsonRpcIpcEnabled()) {
final JsonRpcIpcConfiguration ipcConfiguration = node.jsonRpcIpcConfiguration();
params.add("--Xrpc-ipc-enabled");
params.add("--Xrpc-ipc-path");
params.add(ipcConfiguration.getPath().toString());
params.add("--Xrpc-ipc-apis");
params.add(String.join(",", ipcConfiguration.getEnabledApis()));
}

if (node.isMetricsEnabled()) {
final MetricsConfiguration metricsConfiguration = node.getMetricsConfiguration();
params.add("--metrics-enabled");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public void startNode(final BesuNode node) {
.networkingConfiguration(node.getNetworkingConfiguration())
.jsonRpcConfiguration(node.jsonRpcConfiguration())
.webSocketConfiguration(node.webSocketConfiguration())
.jsonRpcIpcConfiguration(node.jsonRpcIpcConfiguration())
.dataDir(node.homeDirectory())
.metricsSystem(metricsSystem)
.permissioningService(new PermissioningServiceImpl())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
Expand All @@ -39,6 +40,7 @@ public class BesuNodeConfiguration {
private final JsonRpcConfiguration jsonRpcConfiguration;
private final Optional<JsonRpcConfiguration> engineRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private final Optional<WebSocketConfiguration> engineWebSocketConfiguration;
private final MetricsConfiguration metricsConfiguration;
private final Optional<PermissioningConfiguration> permissioningConfiguration;
Expand Down Expand Up @@ -72,6 +74,7 @@ public class BesuNodeConfiguration {
final JsonRpcConfiguration jsonRpcConfiguration,
final Optional<JsonRpcConfiguration> engineRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration,
final Optional<WebSocketConfiguration> engineWebSocketConfiguration,
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
Expand Down Expand Up @@ -102,6 +105,7 @@ public class BesuNodeConfiguration {
this.jsonRpcConfiguration = jsonRpcConfiguration;
this.engineRpcConfiguration = engineRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration;
this.engineWebSocketConfiguration = engineWebSocketConfiguration;
this.metricsConfiguration = metricsConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
Expand Down Expand Up @@ -150,6 +154,10 @@ public WebSocketConfiguration getWebSocketConfiguration() {
return webSocketConfiguration;
}

public JsonRpcIpcConfiguration getJsonRpcIpcConfiguration() {
return jsonRpcIpcConfiguration;
}

public Optional<WebSocketConfiguration> getEngineWebSocketConfiguration() {
return engineWebSocketConfiguration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.authentication.JwtAlgorithm;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.api.tls.FileBasedPasswordProvider;
import org.hyperledger.besu.ethereum.core.AddressHelpers;
Expand Down Expand Up @@ -59,6 +60,7 @@ public class BesuNodeConfigurationBuilder {
private JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault();
private JsonRpcConfiguration engineRpcConfiguration = JsonRpcConfiguration.createEngineDefault();
private WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault();
private JsonRpcIpcConfiguration jsonRpcIpcConfiguration = new JsonRpcIpcConfiguration();
private WebSocketConfiguration engineWebSocketConfiguration =
WebSocketConfiguration.createDefault();
private MetricsConfiguration metricsConfiguration = MetricsConfiguration.builder().build();
Expand Down Expand Up @@ -240,6 +242,12 @@ public BesuNodeConfigurationBuilder webSocketConfiguration(
return this;
}

public BesuNodeConfigurationBuilder jsonRpcIpcConfiguration(
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration) {
this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration;
return this;
}

public BesuNodeConfigurationBuilder metricsConfiguration(
final MetricsConfiguration metricsConfiguration) {
this.metricsConfiguration = metricsConfiguration;
Expand Down Expand Up @@ -487,6 +495,7 @@ public BesuNodeConfiguration build() {
jsonRpcConfiguration,
Optional.of(engineRpcConfiguration),
webSocketConfiguration,
jsonRpcIpcConfiguration,
Optional.of(engineWebSocketConfiguration),
metricsConfiguration,
permissioningConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public BesuNode create(final BesuNodeConfiguration config) throws IOException {
config.getJsonRpcConfiguration(),
config.getEngineRpcConfiguration(),
config.getWebSocketConfiguration(),
config.getJsonRpcIpcConfiguration(),
config.getMetricsConfiguration(),
config.getPermissioningConfiguration(),
config.getKeyFilePath(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public PrivacyNode(
besuConfig.getJsonRpcConfiguration(),
besuConfig.getEngineRpcConfiguration(),
besuConfig.getWebSocketConfiguration(),
besuConfig.getJsonRpcIpcConfiguration(),
besuConfig.getMetricsConfiguration(),
besuConfig.getPermissioningConfiguration(),
besuConfig.getKeyFilePath(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.hyperledger.besu.tests.acceptance.jsonrpc.ipc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;

import org.junit.Before;
import org.junit.Test;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.response.NetVersion;
import org.web3j.protocol.ipc.UnixIpcService;

public class Web3JSupportAcceptanceTest extends AcceptanceTestBase {

private Node node;
private Path socketPath;

@Before
public void setUp() throws Exception {
socketPath = Files.createTempFile("besu-test-", ".ipc");
node =
besu.createNode(
"node1",
(configurationBuilder) ->
configurationBuilder.jsonRpcIpcConfiguration(
new JsonRpcIpcConfiguration(
true, socketPath, Collections.singletonList(RpcApis.NET.name()))));
cluster.start(node);
}

@Test
public void netVersionCall() {
final Web3j web3 = Web3j.build(new UnixIpcService(socketPath.toString()));
final Request<?, NetVersion> ethBlockNumberRequest = web3.netVersion();
node.verify(
node -> {
try {
assertThat(ethBlockNumberRequest.send().getNetVersion())
.isEqualTo(String.valueOf(2018));
} catch (IOException e) {
fail("Web3J net_version call failed", e);
}
});
}
}
12 changes: 12 additions & 0 deletions besu/src/main/java/org/hyperledger/besu/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLHttpService;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcService;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketService;
import org.hyperledger.besu.ethereum.api.query.cache.AutoTransactionLogBloomCachingService;
import org.hyperledger.besu.ethereum.api.query.cache.TransactionLogBloomCacher;
Expand Down Expand Up @@ -64,6 +65,7 @@ public class Runner implements AutoCloseable {
private final Optional<JsonRpcHttpService> jsonRpc;
private final Optional<JsonRpcHttpService> engineJsonRpc;
private final Optional<MetricsService> metrics;
private final Optional<JsonRpcIpcService> ipcJsonRpc;
private final Optional<Path> pidPath;
private final Optional<WebSocketService> webSocketRpc;
private final Optional<WebSocketService> engineWebSocketRpc;
Expand All @@ -84,6 +86,7 @@ public class Runner implements AutoCloseable {
final Optional<GraphQLHttpService> graphQLHttp,
final Optional<WebSocketService> webSocketRpc,
final Optional<WebSocketService> engineWebSocketRpc,
final Optional<JsonRpcIpcService> ipcJsonRpc,
final Optional<StratumServer> stratumServer,
final Optional<MetricsService> metrics,
final Optional<EthStatsService> ethStatsService,
Expand All @@ -101,6 +104,7 @@ public class Runner implements AutoCloseable {
this.engineJsonRpc = engineJsonRpc;
this.webSocketRpc = webSocketRpc;
this.engineWebSocketRpc = engineWebSocketRpc;
this.ipcJsonRpc = ipcJsonRpc;
this.metrics = metrics;
this.ethStatsService = ethStatsService;
this.besuController = besuController;
Expand All @@ -123,6 +127,10 @@ public void startExternalServices() {
webSocketRpc.ifPresent(service -> waitForServiceToStart("websocketRpc", service.start()));
engineWebSocketRpc.ifPresent(
service -> waitForServiceToStart("engineWebsocketRpc", service.start()));
ipcJsonRpc.ifPresent(
service ->
waitForServiceToStart(
"ipcJsonRpc", service.start().toCompletionStage().toCompletableFuture()));
stratumServer.ifPresent(server -> waitForServiceToStart("stratum", server.start()));
autoTransactionLogBloomCachingService.ifPresent(AutoTransactionLogBloomCachingService::start);
ethStatsService.ifPresent(EthStatsService::start);
Expand Down Expand Up @@ -158,6 +166,10 @@ public void stop() {
webSocketRpc.ifPresent(service -> waitForServiceToStop("websocketRpc", service.stop()));
engineWebSocketRpc.ifPresent(
service -> waitForServiceToStop("engineWebsocketRpc", service.stop()));
ipcJsonRpc.ifPresent(
service ->
waitForServiceToStop(
"ipcJsonRpc", service.stop().toCompletionStage().toCompletableFuture()));
metrics.ifPresent(service -> waitForServiceToStop("metrics", service.stop()));
ethStatsService.ifPresent(EthStatsService::stop);
besuController.getMiningCoordinator().stop();
Expand Down
49 changes: 49 additions & 0 deletions besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManager;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.filter.FilterManagerBuilder;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.ipc.JsonRpcIpcService;
import org.hyperledger.besu.ethereum.api.jsonrpc.methods.JsonRpcMethodsFactory;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketRequestHandler;
Expand Down Expand Up @@ -188,6 +190,7 @@ public class RunnerBuilder {
private StorageProvider storageProvider;
private Supplier<List<Bytes>> forkIdSupplier;
private RpcEndpointServiceImpl rpcEndpointServiceImpl;
private JsonRpcIpcConfiguration jsonRpcIpcConfiguration;

public RunnerBuilder vertx(final Vertx vertx) {
this.vertx = vertx;
Expand Down Expand Up @@ -398,6 +401,12 @@ public RunnerBuilder rpcEndpointService(final RpcEndpointServiceImpl rpcEndpoint
return this;
}

public RunnerBuilder jsonRpcIpcConfiguration(
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration) {
this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration;
return this;
}

public Runner build() {

Preconditions.checkNotNull(besuController);
Expand Down Expand Up @@ -832,6 +841,45 @@ public Runner build() {
ethStatsService = Optional.empty();
}

final Optional<JsonRpcIpcService> jsonRpcIpcService;
if (jsonRpcIpcConfiguration.isEnabled()) {
Map<String, JsonRpcMethod> ipcMethods =
jsonRpcMethods(
protocolSchedule,
context,
besuController,
peerNetwork,
blockchainQueries,
synchronizer,
transactionPool,
miningCoordinator,
metricsSystem,
supportedCapabilities,
jsonRpcIpcConfiguration.getEnabledApis().stream()
.filter(apiGroup -> !apiGroup.toLowerCase().startsWith("engine"))
.collect(Collectors.toList()),
filterManager,
accountLocalConfigPermissioningController,
nodeLocalConfigPermissioningController,
privacyParameters,
jsonRpcConfiguration,
webSocketConfiguration,
metricsConfiguration,
natService,
besuPluginContext.getNamedPlugins(),
dataDir,
rpcEndpointServiceImpl);

jsonRpcIpcService =
Optional.of(
new JsonRpcIpcService(
vertx,
jsonRpcIpcConfiguration.getPath(),
new JsonRpcExecutor(new BaseJsonRpcProcessor(), ipcMethods)));
} else {
jsonRpcIpcService = Optional.empty();
}

return new Runner(
vertx,
networkRunner,
Expand All @@ -841,6 +889,7 @@ public Runner build() {
graphQLHttpService,
webSocketService,
engineWebSocketService,
jsonRpcIpcService,
stratumServer,
metricsService,
ethStatsService,
Expand Down
Loading

0 comments on commit 4e07dd3

Please sign in to comment.