In process RPC service (#7395)

Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
pull/7416/head
Fabio Di Fabio 4 months ago committed by GitHub
parent 9d92ae87df
commit a7ab1773e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      CHANGELOG.md
  2. 8
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/BesuNode.java
  3. 9
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java
  4. 8
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfiguration.java
  5. 11
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeConfigurationBuilder.java
  6. 17
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java
  7. 12
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/NodeConfigurationFactory.java
  8. 1
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java
  9. 42
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerGetMinGasPriceTransaction.java
  10. 5
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java
  11. 4
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/transaction/miner/MinerTransactions.java
  12. 81
      acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/tests/acceptance/plugins/TestInProcessRpcServicePlugin.java
  13. 51
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/InProcessRpcServicePluginTest.java
  14. 15
      besu/src/main/java/org/hyperledger/besu/Runner.java
  15. 46
      besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java
  16. 12
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  17. 73
      besu/src/main/java/org/hyperledger/besu/cli/options/unstable/InProcessRpcOptions.java
  18. 61
      besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java
  19. 7
      besu/src/test/java/org/hyperledger/besu/RunnerBuilderTest.java
  20. 2
      besu/src/test/java/org/hyperledger/besu/RunnerTest.java
  21. 1
      besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java
  22. 36
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/InProcessRpcConfiguration.java
  23. 6
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcResponse.java
  24. 2
      plugin-api/build.gradle
  25. 10
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/RpcEndpointService.java
  26. 2
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcRequest.java
  27. 27
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/PluginRpcResponse.java
  28. 26
      plugin-api/src/main/java/org/hyperledger/besu/plugin/services/rpc/RpcResponse.java

@ -14,6 +14,7 @@
### Additions and Improvements
- Expose set finalized/safe block in plugin api BlockchainService. These method can be used by plugins to set finalized/safe block for a PoA network (such as QBFT, IBFT and Clique).[#7382](https://github.com/hyperledger/besu/pull/7382)
- In process RPC service [#7395](https://github.com/hyperledger/besu/pull/7395)
### Bug fixes
@ -44,7 +45,7 @@
- Force bonsai-limit-trie-logs-enabled=false when sync-mode=FULL instead of startup error [#7357](https://github.com/hyperledger/besu/pull/7357)
- `--Xbonsai-parallel-tx-processing-enabled` option enables executing transactions in parallel during block processing for Bonsai nodes
- Reduce default trie log pruning window size from 30,000 to 5,000 [#7365](https://github.com/hyperledger/besu/pull/7365)
- Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314)
- Add option `--poa-discovery-retry-bootnodes` for PoA networks to always use bootnodes during peer refresh, not just on first start [#7314](https://github.com/hyperledger/besu/pull/7314)
### Bug fixes
- Fix `eth_call` deserialization to correctly ignore unknown fields in the transaction object. [#7323](https://github.com/hyperledger/besu/pull/7323)

@ -23,6 +23,7 @@ import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.KeyPairUtil;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
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;
@ -109,6 +110,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
private final Optional<JsonRpcConfiguration> engineRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private final InProcessRpcConfiguration inProcessRpcConfiguration;
private final MetricsConfiguration metricsConfiguration;
private final DataStorageConfiguration dataStorageConfiguration;
private Optional<PermissioningConfiguration> permissioningConfiguration;
@ -143,6 +145,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
final Optional<JsonRpcConfiguration> engineRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration,
final InProcessRpcConfiguration inProcessRpcConfiguration,
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
final ApiConfiguration apiConfiguration,
@ -193,6 +196,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
this.engineRpcConfiguration = engineRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration;
this.inProcessRpcConfiguration = inProcessRpcConfiguration;
this.metricsConfiguration = metricsConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.apiConfiguration = apiConfiguration;
@ -624,6 +628,10 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
return jsonRpcIpcConfiguration;
}
InProcessRpcConfiguration inProcessRpcConfiguration() {
return inProcessRpcConfiguration;
}
Optional<String> wsRpcListenHost() {
return Optional.of(webSocketConfiguration().getHost());
}

@ -29,6 +29,7 @@ import org.hyperledger.besu.cryptoservices.NodeKey;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
@ -236,6 +237,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
.transactionPoolValidatorService(transactionPoolValidatorServiceImpl)
.build();
final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration();
final int maxPeers = 25;
builder
@ -297,7 +300,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
.besuPluginContext(besuPluginContext)
.autoLogBloomCaching(false)
.storageProvider(storageProvider)
.rpcEndpointService(rpcEndpointServiceImpl);
.rpcEndpointService(rpcEndpointServiceImpl)
.inProcessRpcConfiguration(inProcessRpcConfiguration);
node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration);
besuPluginContext.beforeExternalServices();
@ -313,6 +317,9 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
besuController.getTransactionPool(),
besuController.getSyncState(),
besuController.getProtocolContext().getBadBlockManager()));
rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods());
besuPluginContext.startPlugins();
runner.startEthereumMainLoop();

@ -17,6 +17,7 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.configuration;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
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;
@ -45,6 +46,7 @@ public class BesuNodeConfiguration {
private final Optional<JsonRpcConfiguration> engineRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private final InProcessRpcConfiguration inProcessRpcConfiguration;
private final MetricsConfiguration metricsConfiguration;
private final Optional<PermissioningConfiguration> permissioningConfiguration;
private final ApiConfiguration apiConfiguration;
@ -81,6 +83,7 @@ public class BesuNodeConfiguration {
final Optional<JsonRpcConfiguration> engineRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration,
final InProcessRpcConfiguration inProcessRpcConfiguration,
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
final ApiConfiguration apiConfiguration,
@ -114,6 +117,7 @@ public class BesuNodeConfiguration {
this.engineRpcConfiguration = engineRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.jsonRpcIpcConfiguration = jsonRpcIpcConfiguration;
this.inProcessRpcConfiguration = inProcessRpcConfiguration;
this.metricsConfiguration = metricsConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.apiConfiguration = apiConfiguration;
@ -171,6 +175,10 @@ public class BesuNodeConfiguration {
return jsonRpcIpcConfiguration;
}
public InProcessRpcConfiguration getInProcessRpcConfiguration() {
return inProcessRpcConfiguration;
}
public MetricsConfiguration getMetricsConfiguration() {
return metricsConfiguration;
}

@ -24,6 +24,8 @@ import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
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;
@ -70,6 +72,8 @@ public class BesuNodeConfigurationBuilder {
private JsonRpcConfiguration engineRpcConfiguration = JsonRpcConfiguration.createEngineDefault();
private WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault();
private JsonRpcIpcConfiguration jsonRpcIpcConfiguration = new JsonRpcIpcConfiguration();
private InProcessRpcConfiguration inProcessRpcConfiguration =
ImmutableInProcessRpcConfiguration.builder().build();
private MetricsConfiguration metricsConfiguration = MetricsConfiguration.builder().build();
private Optional<PermissioningConfiguration> permissioningConfiguration = Optional.empty();
private ApiConfiguration apiConfiguration = ImmutableApiConfiguration.builder().build();
@ -258,6 +262,12 @@ public class BesuNodeConfigurationBuilder {
return this;
}
public BesuNodeConfigurationBuilder inProcessRpcConfiguration(
final InProcessRpcConfiguration inProcessRpcConfiguration) {
this.inProcessRpcConfiguration = inProcessRpcConfiguration;
return this;
}
public BesuNodeConfigurationBuilder metricsConfiguration(
final MetricsConfiguration metricsConfiguration) {
this.metricsConfiguration = metricsConfiguration;
@ -516,6 +526,7 @@ public class BesuNodeConfigurationBuilder {
Optional.of(engineRpcConfiguration),
webSocketConfiguration,
jsonRpcIpcConfiguration,
inProcessRpcConfiguration,
metricsConfiguration,
permissioningConfiguration,
apiConfiguration,

@ -16,6 +16,8 @@ package org.hyperledger.besu.tests.acceptance.dsl.node.configuration;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ADMIN;
import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.IBFT;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.datatypes.Wei;
@ -43,6 +45,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@ -64,6 +67,7 @@ public class BesuNodeFactory {
config.getEngineRpcConfiguration(),
config.getWebSocketConfiguration(),
config.getJsonRpcIpcConfiguration(),
config.getInProcessRpcConfiguration(),
config.getMetricsConfiguration(),
config.getPermissioningConfiguration(),
config.getApiConfiguration(),
@ -330,12 +334,20 @@ public class BesuNodeFactory {
}
public BesuNode createPluginsNode(
final String name, final List<String> plugins, final List<String> extraCLIOptions)
final String name,
final List<String> plugins,
final List<String> extraCLIOptions,
final String... extraRpcApis)
throws IOException {
final List<String> enableRpcApis = new ArrayList<>(Arrays.asList(extraRpcApis));
enableRpcApis.addAll(List.of(IBFT.name(), ADMIN.name()));
return create(
new BesuNodeConfigurationBuilder()
.name(name)
.jsonRpcConfiguration(node.createJsonRpcWithIbft2AdminEnabledConfig())
.jsonRpcConfiguration(
node.createJsonRpcWithRpcApiEnabledConfig(enableRpcApis.toArray(String[]::new)))
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.plugins(plugins)
.extraCLIOptions(extraCLIOptions)
@ -394,6 +406,7 @@ public class BesuNodeFactory {
.miningEnabled()
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig(extraRpcApis))
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.inProcessRpcConfiguration(node.createInProcessRpcConfiguration(extraRpcApis))
.devMode(false)
.jsonRpcTxPool()
.genesisConfigProvider(

@ -22,6 +22,8 @@ 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.ImmutableInProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
@ -94,4 +96,14 @@ public class NodeConfigurationFactory {
jsonRpcConfig.setRpcApis(rpcApis);
return jsonRpcConfig;
}
public InProcessRpcConfiguration createInProcessRpcConfiguration(final Set<String> extraRpcApis) {
final Set<String> rpcApis =
new HashSet<>(ImmutableInProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_APIS);
rpcApis.addAll(extraRpcApis);
return ImmutableInProcessRpcConfiguration.builder()
.inProcessRpcApis(rpcApis)
.isEnabled(true)
.build();
}
}

@ -106,6 +106,7 @@ public class PrivacyNode implements AutoCloseable {
besuConfig.getEngineRpcConfiguration(),
besuConfig.getWebSocketConfiguration(),
besuConfig.getJsonRpcIpcConfiguration(),
besuConfig.getInProcessRpcConfiguration(),
besuConfig.getMetricsConfiguration(),
besuConfig.getPermissioningConfiguration(),
besuConfig.getApiConfiguration(),

@ -0,0 +1,42 @@
/*
* 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.dsl.transaction.miner;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
import java.io.IOException;
import java.math.BigInteger;
import org.web3j.protocol.core.methods.response.EthGasPrice;
public class MinerGetMinGasPriceTransaction implements Transaction<BigInteger> {
@Override
public BigInteger execute(final NodeRequests node) {
try {
final EthGasPrice result = node.miner().minerGetMinGasPrice().send();
assertThat(result).isNotNull();
assertThat(result.hasError()).isFalse();
return result.getGasPrice();
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
}

@ -16,6 +16,7 @@ package org.hyperledger.besu.tests.acceptance.dsl.transaction.miner;
import org.web3j.protocol.Web3jService;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.response.EthGasPrice;
public class MinerRequestFactory {
@ -40,4 +41,8 @@ public class MinerRequestFactory {
web3jService,
org.web3j.protocol.core.methods.response.VoidResponse.class);
}
Request<?, EthGasPrice> minerGetMinGasPrice() {
return new Request<>("miner_getMinGasPrice", null, web3jService, EthGasPrice.class);
}
}

@ -23,4 +23,8 @@ public class MinerTransactions {
public MinerStopTransaction minerStop() {
return new MinerStopTransaction();
}
public MinerGetMinGasPriceTransaction minerGetMinGasPrice() {
return new MinerGetMinGasPriceTransaction();
}
}

@ -0,0 +1,81 @@
/*
* 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.plugins;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
import com.google.auto.service.AutoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
@AutoService(BesuPlugin.class)
public class TestInProcessRpcServicePlugin implements BesuPlugin {
private static final Logger LOG = LoggerFactory.getLogger(TestInProcessRpcServicePlugin.class);
private RpcEndpointService rpcEndpointService;
@CommandLine.Option(names = {"--plugin-test-set-min-gas-price"})
long minGasPrice = -1;
@Override
public void register(final BesuContext context) {
final PicoCLIOptions cmdlineOptions =
context
.getService(PicoCLIOptions.class)
.orElseThrow(
() ->
new IllegalStateException(
"Failed to obtain PicoCLI options from the BesuContext"));
cmdlineOptions.addPicoCLIOptions("test", this);
rpcEndpointService =
context
.getService(RpcEndpointService.class)
.orElseThrow(
() ->
new RuntimeException(
"Failed to obtain RpcEndpointService from the BesuContext."));
}
@Override
public void start() {
LOG.info("TestInProcessRpcServicePlugin minGasPrice option: {}", minGasPrice);
if (minGasPrice >= 0) {
callSetMinGasPrice(minGasPrice);
}
}
@Override
public void stop() {}
private void callSetMinGasPrice(final long minGasPrice) {
LOG.info("Setting minGasPrice via in-process RPC service");
final var minGasPriceWei = Wei.of(minGasPrice);
final var resp =
rpcEndpointService.call(
"miner_setMinGasPrice", new Object[] {minGasPriceWei.toShortHexString()});
LOG.info("miner_setMinGasPrice response: {}", resp);
if (!resp.getType().equals(RpcResponseType.SUCCESS)) {
throw new RuntimeException("Internal setMinGasPrice method failed: " + resp);
}
}
}

@ -0,0 +1,51 @@
/*
* 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.plugins;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
import java.math.BigInteger;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class InProcessRpcServicePluginTest extends AcceptanceTestBase {
private static final long MIN_GAS_PRICE = 123456;
private BesuNode node;
@BeforeEach
public void setUp() throws Exception {
node =
besu.createPluginsNode(
"node1",
List.of("testPlugins"),
List.of(
"--Xin-process-rpc-enabled=true",
"--Xin-process-rpc-apis=MINER",
"--plugin-test-set-min-gas-price=" + MIN_GAS_PRICE),
"MINER");
cluster.start(node);
}
@Test
public void smokeTest() {
final var currMinGasPrice = node.execute(minerTransactions.minerGetMinGasPrice());
assertThat(currMinGasPrice).isEqualTo(BigInteger.valueOf(MIN_GAS_PRICE));
}
}

@ -18,6 +18,7 @@ import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLHttpService;
import org.hyperledger.besu.ethereum.api.jsonrpc.EngineJsonRpcService;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
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;
@ -39,6 +40,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
@ -69,6 +71,7 @@ public class Runner implements AutoCloseable {
private final Optional<EngineJsonRpcService> engineJsonRpc;
private final Optional<MetricsService> metrics;
private final Optional<JsonRpcIpcService> ipcJsonRpc;
private final Map<String, JsonRpcMethod> inProcessRpcMethods;
private final Optional<Path> pidPath;
private final Optional<WebSocketService> webSocketRpc;
private final TransactionPoolEvictionService transactionPoolEvictionService;
@ -90,6 +93,7 @@ public class Runner implements AutoCloseable {
* @param graphQLHttp the graph ql http
* @param webSocketRpc the web socket rpc
* @param ipcJsonRpc the ipc json rpc
* @param inProcessRpcMethods the in-process rpc methods
* @param stratumServer the stratum server
* @param metrics the metrics
* @param ethStatsService the eth stats service
@ -108,6 +112,7 @@ public class Runner implements AutoCloseable {
final Optional<GraphQLHttpService> graphQLHttp,
final Optional<WebSocketService> webSocketRpc,
final Optional<JsonRpcIpcService> ipcJsonRpc,
final Map<String, JsonRpcMethod> inProcessRpcMethods,
final Optional<StratumServer> stratumServer,
final Optional<MetricsService> metrics,
final Optional<EthStatsService> ethStatsService,
@ -125,6 +130,7 @@ public class Runner implements AutoCloseable {
this.engineJsonRpc = engineJsonRpc;
this.webSocketRpc = webSocketRpc;
this.ipcJsonRpc = ipcJsonRpc;
this.inProcessRpcMethods = inProcessRpcMethods;
this.metrics = metrics;
this.ethStatsService = ethStatsService;
this.besuController = besuController;
@ -413,6 +419,15 @@ public class Runner implements AutoCloseable {
}
}
/**
* Get the RPC methods that can be called in-process
*
* @return RPC methods by name
*/
public Map<String, JsonRpcMethod> getInProcessRpcMethods() {
return inProcessRpcMethods;
}
/**
* Gets local enode.
*

@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.api.graphql.GraphQLDataFetchers;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLHttpService;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.EngineJsonRpcService;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcHttpService;
import org.hyperledger.besu.ethereum.api.jsonrpc.authentication.AuthenticationService;
@ -178,6 +179,7 @@ public class RunnerBuilder {
private Optional<JsonRpcConfiguration> engineJsonRpcConfiguration = Optional.empty();
private GraphQLConfiguration graphQLConfiguration;
private WebSocketConfiguration webSocketConfiguration;
private InProcessRpcConfiguration inProcessRpcConfiguration;
private ApiConfiguration apiConfiguration;
private Path dataDir;
private Optional<Path> pidPath = Optional.empty();
@ -414,6 +416,18 @@ public class RunnerBuilder {
return this;
}
/**
* Add In-Process RPC configuration.
*
* @param inProcessRpcConfiguration the in-process RPC configuration
* @return the runner builder
*/
public RunnerBuilder inProcessRpcConfiguration(
final InProcessRpcConfiguration inProcessRpcConfiguration) {
this.inProcessRpcConfiguration = inProcessRpcConfiguration;
return this;
}
/**
* Add Api configuration.
*
@ -1082,6 +1096,37 @@ public class RunnerBuilder {
jsonRpcIpcService = Optional.empty();
}
final Map<String, JsonRpcMethod> inProcessRpcMethods;
if (inProcessRpcConfiguration.isEnabled()) {
inProcessRpcMethods =
jsonRpcMethods(
protocolSchedule,
context,
besuController,
peerNetwork,
blockchainQueries,
synchronizer,
transactionPool,
miningParameters,
miningCoordinator,
metricsSystem,
supportedCapabilities,
inProcessRpcConfiguration.getInProcessRpcApis(),
filterManager,
accountLocalConfigPermissioningController,
nodeLocalConfigPermissioningController,
privacyParameters,
jsonRpcConfiguration,
webSocketConfiguration,
metricsConfiguration,
natService,
besuPluginContext.getNamedPlugins(),
dataDir,
rpcEndpointServiceImpl);
} else {
inProcessRpcMethods = Map.of();
}
return new Runner(
vertx,
networkRunner,
@ -1091,6 +1136,7 @@ public class RunnerBuilder {
graphQLHttpService,
webSocketService,
jsonRpcIpcService,
inProcessRpcMethods,
stratumServer,
metricsService,
ethStatsService,

@ -63,6 +63,7 @@ import org.hyperledger.besu.cli.options.unstable.ChainPruningOptions;
import org.hyperledger.besu.cli.options.unstable.DnsOptions;
import org.hyperledger.besu.cli.options.unstable.EthProtocolOptions;
import org.hyperledger.besu.cli.options.unstable.EvmOptions;
import org.hyperledger.besu.cli.options.unstable.InProcessRpcOptions;
import org.hyperledger.besu.cli.options.unstable.IpcOptions;
import org.hyperledger.besu.cli.options.unstable.MetricsCLIOptions;
import org.hyperledger.besu.cli.options.unstable.NatOptions;
@ -107,6 +108,7 @@ import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
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;
@ -660,6 +662,10 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
@CommandLine.ArgGroup(validate = false, heading = "@|bold JSON-RPC Websocket Options|@%n")
RpcWebsocketOptions rpcWebsocketOptions = new RpcWebsocketOptions();
// In-Process RPC Options
@CommandLine.ArgGroup(validate = false, heading = "@|bold In-Process RPC Options|@%n")
InProcessRpcOptions inProcessRpcOptions = InProcessRpcOptions.create();
// Privacy Options Group
@CommandLine.ArgGroup(validate = false, heading = "@|bold Privacy Options|@%n")
PrivacyOptionGroup privacyOptionGroup = new PrivacyOptionGroup();
@ -926,6 +932,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
private GraphQLConfiguration graphQLConfiguration;
private WebSocketConfiguration webSocketConfiguration;
private JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private InProcessRpcConfiguration inProcessRpcConfiguration;
private ApiConfiguration apiConfiguration;
private MetricsConfiguration metricsConfiguration;
private Optional<PermissioningConfiguration> permissioningConfiguration;
@ -1353,6 +1360,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
engineJsonRpcConfiguration,
webSocketConfiguration,
jsonRpcIpcConfiguration,
inProcessRpcConfiguration,
apiConfiguration,
metricsConfiguration,
permissioningConfiguration,
@ -1370,6 +1378,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
besuController.getProtocolContext().getWorldStateArchive(),
besuController.getProtocolSchedule(),
apiConfiguration.getGasCap()));
rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods());
besuPluginContext.addService(
BesuEvents.class,
@ -1810,6 +1819,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
unstableIpcOptions.isEnabled(),
unstableIpcOptions.getIpcPath(),
unstableIpcOptions.getRpcIpcApis());
inProcessRpcConfiguration = inProcessRpcOptions.toDomainObject();
apiConfiguration = apiConfigurationOptions.apiConfiguration();
dataStorageConfiguration = getDataStorageConfiguration();
// hostsWhitelist is a hidden option. If it is specified, add the list to hostAllowlist
@ -2321,6 +2331,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
final JsonRpcConfiguration engineJsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final JsonRpcIpcConfiguration jsonRpcIpcConfiguration,
final InProcessRpcConfiguration inProcessRpcConfiguration,
final ApiConfiguration apiConfiguration,
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
@ -2353,6 +2364,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
.engineJsonRpcConfiguration(engineJsonRpcConfiguration)
.webSocketConfiguration(webSocketConfiguration)
.jsonRpcIpcConfiguration(jsonRpcIpcConfiguration)
.inProcessRpcConfiguration(inProcessRpcConfiguration)
.apiConfiguration(apiConfiguration)
.pidPath(pidPath)
.dataDir(dataDir())

@ -0,0 +1,73 @@
/*
* 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.cli.options.unstable;
import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_APIS;
import static org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration.DEFAULT_IN_PROCESS_RPC_ENABLED;
import org.hyperledger.besu.cli.options.CLIOptions;
import org.hyperledger.besu.cli.util.CommandLineUtils;
import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
import java.util.List;
import java.util.Set;
import picocli.CommandLine;
/** The in process RPC options. */
public class InProcessRpcOptions implements CLIOptions<InProcessRpcConfiguration> {
/** Default constructor. */
InProcessRpcOptions() {}
/**
* Create ipc options.
*
* @return the ipc options
*/
public static InProcessRpcOptions create() {
return new InProcessRpcOptions();
}
@CommandLine.Option(
names = {"--Xin-process-rpc-enabled"},
hidden = true,
description = "Set to enalbe in-process RPC method call service (default: ${DEFAULT-VALUE})")
private final Boolean enabled = DEFAULT_IN_PROCESS_RPC_ENABLED;
@CommandLine.Option(
names = {"--Xin-process-rpc-api", "--Xin-process-rpc-apis"},
hidden = true,
paramLabel = "<api name>",
split = " {0,1}, {0,1}",
arity = "1..*",
description =
"Comma separated list of APIs to enable on in-process RPC method call service (default: ${DEFAULT-VALUE})")
private final Set<String> inProcessRpcApis = DEFAULT_IN_PROCESS_RPC_APIS;
@Override
public InProcessRpcConfiguration toDomainObject() {
return ImmutableInProcessRpcConfiguration.builder()
.isEnabled(enabled)
.inProcessRpcApis(inProcessRpcApis)
.build();
}
@Override
public List<String> getCLIOptions() {
return CommandLineUtils.getCLIOptions(this, new InProcessRpcOptions());
}
}

@ -17,25 +17,48 @@ 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.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.PluginJsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcResponse;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** The RPC endpoint service implementation. */
public class RpcEndpointServiceImpl implements RpcEndpointService {
private static final Logger LOG = LoggerFactory.getLogger(RpcEndpointServiceImpl.class);
private final Map<String, Function<PluginRpcRequest, ?>> rpcMethods = new HashMap<>();
private Map<String, JsonRpcMethod> inProcessRpcMethods;
/** Default Constructor. */
public RpcEndpointServiceImpl() {}
/**
* Init the service
*
* @param inProcessRpcMethods set of RPC methods that can be called
*/
public void init(final Map<String, JsonRpcMethod> inProcessRpcMethods) {
this.inProcessRpcMethods = inProcessRpcMethods;
}
@Override
public <T> void registerRPCEndpoint(
final String namespace,
@ -48,6 +71,44 @@ public class RpcEndpointServiceImpl implements RpcEndpointService {
rpcMethods.put(namespace + "_" + functionName, function);
}
@Override
public PluginRpcResponse call(final String methodName, final Object[] params) {
checkNotNull(
inProcessRpcMethods,
"Service not initialized yet, this method must be called after plugin 'beforeExternalServices' call completes");
LOG.atTrace()
.setMessage("Calling method:{} with params:{}")
.addArgument(methodName)
.addArgument(() -> Arrays.toString(params))
.log();
final var method = inProcessRpcMethods.get(methodName);
if (method == null) {
throw new NoSuchElementException("Unknown or not enabled method: " + methodName);
}
final var requestContext =
new JsonRpcRequestContext(new JsonRpcRequest("2.0", methodName, params));
final var response = method.response(requestContext);
return new PluginRpcResponse() {
@Override
public Object getResult() {
return switch (response.getType()) {
case NONE, UNAUTHORIZED -> null;
case SUCCESS -> ((JsonRpcSuccessResponse) response).getResult();
case ERROR -> ((JsonRpcErrorResponse) response).getError();
};
}
@Override
public RpcResponseType getType() {
return response.getType();
}
};
}
/**
* Gets plugin methods.
*

@ -38,6 +38,7 @@ import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
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;
@ -163,6 +164,7 @@ public final class RunnerBuilderTest {
.graphQLConfiguration(mock(GraphQLConfiguration.class))
.webSocketConfiguration(mock(WebSocketConfiguration.class))
.jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class))
.inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class))
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(vertx)
.dataDir(dataDir.getRoot())
@ -208,6 +210,7 @@ public final class RunnerBuilderTest {
.graphQLConfiguration(mock(GraphQLConfiguration.class))
.webSocketConfiguration(mock(WebSocketConfiguration.class))
.jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class))
.inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class))
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())
@ -267,6 +270,7 @@ public final class RunnerBuilderTest {
.graphQLConfiguration(mock(GraphQLConfiguration.class))
.webSocketConfiguration(mock(WebSocketConfiguration.class))
.jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class))
.inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class))
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())
@ -309,6 +313,7 @@ public final class RunnerBuilderTest {
.engineJsonRpcConfiguration(engineConf)
.webSocketConfiguration(wsRpc)
.jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class))
.inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class))
.graphQLConfiguration(mock(GraphQLConfiguration.class))
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
@ -351,6 +356,7 @@ public final class RunnerBuilderTest {
.engineJsonRpcConfiguration(engineConf)
.webSocketConfiguration(wsRpc)
.jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class))
.inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class))
.graphQLConfiguration(mock(GraphQLConfiguration.class))
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
@ -395,6 +401,7 @@ public final class RunnerBuilderTest {
.graphQLConfiguration(mock(GraphQLConfiguration.class))
.webSocketConfiguration(defaultWebSockConfig)
.jsonRpcIpcConfiguration(mock(JsonRpcIpcConfiguration.class))
.inProcessRpcConfiguration(mock(InProcessRpcConfiguration.class))
.metricsConfiguration(mock(MetricsConfiguration.class))
.vertx(Vertx.vertx())
.dataDir(dataDir.getRoot())

@ -36,6 +36,7 @@ import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.api.ImmutableApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.ImmutableInProcessRpcConfiguration;
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;
@ -211,6 +212,7 @@ public final class RunnerTest {
.graphQLConfiguration(graphQLConfiguration())
.webSocketConfiguration(wsRpcConfiguration())
.jsonRpcIpcConfiguration(new JsonRpcIpcConfiguration())
.inProcessRpcConfiguration(ImmutableInProcessRpcConfiguration.builder().build())
.metricsConfiguration(metricsConfiguration())
.dataDir(dbAhead)
.pidPath(pidPath)

@ -332,6 +332,7 @@ public abstract class CommandTestAbstract {
when(mockRunnerBuilder.graphQLConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.webSocketConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.jsonRpcIpcConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.inProcessRpcConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.apiConfiguration(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.dataDir(any())).thenReturn(mockRunnerBuilder);
when(mockRunnerBuilder.bannedNodeIds(any())).thenReturn(mockRunnerBuilder);

@ -0,0 +1,36 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc;
import java.util.HashSet;
import java.util.Set;
import org.immutables.value.Value;
@Value.Immutable
public interface InProcessRpcConfiguration {
boolean DEFAULT_IN_PROCESS_RPC_ENABLED = false;
Set<String> DEFAULT_IN_PROCESS_RPC_APIS = new HashSet<>(RpcApis.DEFAULT_RPC_APIS);
@Value.Default
default boolean isEnabled() {
return DEFAULT_IN_PROCESS_RPC_ENABLED;
}
@Value.Default
default Set<String> getInProcessRpcApis() {
return DEFAULT_IN_PROCESS_RPC_APIS;
}
}

@ -14,16 +14,14 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.response;
import org.hyperledger.besu.plugin.services.rpc.RpcResponseType;
import org.hyperledger.besu.plugin.services.rpc.RpcResponse;
import com.fasterxml.jackson.annotation.JsonGetter;
public interface JsonRpcResponse {
public interface JsonRpcResponse extends RpcResponse {
@JsonGetter("jsonrpc")
default String getVersion() {
return "2.0";
}
RpcResponseType getType();
}

@ -70,7 +70,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 = 'tXFd8EcMJtD+ZSLJxWJLYRZD0d3njRz+3Ubey2zFM2A='
knownHash = 'I851CCOs00yYpW10qIGIak1bKbYhKFQkV2wyCYELHKY='
}
check.dependsOn('checkAPIChanges')

@ -15,6 +15,7 @@
package org.hyperledger.besu.plugin.services;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import org.hyperledger.besu.plugin.services.rpc.PluginRpcResponse;
import java.util.function.Function;
@ -54,4 +55,13 @@ public interface RpcEndpointService extends BesuService {
*/
<T> void registerRPCEndpoint(
String namespace, String functionName, Function<PluginRpcRequest, T> function);
/**
* Allow to call any of the enabled in-process RPC methods
*
* @param methodName the method to invoke
* @param params the list of parameters accepted by the method
* @return the result of the method
*/
PluginRpcResponse call(String methodName, Object[] params);
}

@ -1,5 +1,5 @@
/*
* Copyright ConsenSys AG.
* 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

@ -0,0 +1,27 @@
/*
* 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.plugin.services.rpc;
/** The interface Plugin rpc response. */
public interface PluginRpcResponse extends RpcResponse {
/**
* Get the result, unfortunately there is no typing yet, so call must know how to interact with
* the response
*
* @return the result
*/
Object getResult();
}

@ -0,0 +1,26 @@
/*
* 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.plugin.services.rpc;
/** Represent a Json RPC response */
public interface RpcResponse {
/**
* Get the response type
*
* @return the response type
*/
RpcResponseType getType();
}
Loading…
Cancel
Save