Skip to content

Commit

Permalink
Add json-rpc IPC support [#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 26, 2022
1 parent e2645ba commit 70a0196
Show file tree
Hide file tree
Showing 22 changed files with 756 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- Onchain node permissioning - log the enodeURL that was previously only throwing an IllegalStateException during the isPermitted check [#3697](https://github.com/hyperledger/besu/pull/3697)
- \[EXPERIMENTAL\] Add snapsync `--sync-mode="X_SNAP"` (only as client) [#3710](https://github.com/hyperledger/besu/pull/3710)
- Adapt Fast sync, and Snap sync, to use finalized block, from consensus layer, as pivot after the Merge [#3506](https://github.com/hyperledger/besu/issues/3506)
- Add IPC JSON-RPC interface (BSD/MacOS and Linux only) [#3695](https://github.com/hyperledger/besu/pull/3695)

### Bug Fixes

Expand Down
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,74 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.tests.acceptance.jsonrpc.ipc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.Assume.assumeTrue;

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 java.util.Locale;

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 String osName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
assumeTrue(osName.contains("mac") || osName.contains("linux"));

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
Loading

0 comments on commit 70a0196

Please sign in to comment.