Skip to content

Commit 58bcf4d

Browse files
committed
Only enable plugin rpc api when enabled on --rpc-http-api or --rpc-ws-apis
Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>
1 parent cb20cfa commit 58bcf4d

File tree

7 files changed

+72
-22
lines changed

7 files changed

+72
-22
lines changed

acceptance-tests/test-plugins/src/main/java/org/hyperledger/besu/plugins/TestRpcEndpointServicePlugin.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,13 @@ public void register(final BesuContext context) {
5454
.getService(RpcEndpointService.class)
5555
.ifPresent(
5656
rpcEndpointService -> {
57-
rpcEndpointService.registerRPCEndpoint("unitTests", "getValue", this::getValue);
58-
rpcEndpointService.registerRPCEndpoint("unitTests", "setValue", this::setValue);
57+
rpcEndpointService.registerRPCEndpoint("tests", "getValue", this::getValue);
58+
rpcEndpointService.registerRPCEndpoint("tests", "setValue", this::setValue);
5959
rpcEndpointService.registerRPCEndpoint(
60-
"unitTests", "replaceValueList", this::replaceValueList);
60+
"tests", "replaceValueList", this::replaceValueList);
6161
rpcEndpointService.registerRPCEndpoint(
62-
"unitTests", "throwException", this::throwException);
62+
"tests", "throwException", this::throwException);
63+
rpcEndpointService.registerRPCEndpoint("notEnabled", "getValue", this::getValue);
6364
});
6465
}
6566

acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/plugins/RpcEndpointServicePluginTest.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
2222

2323
import java.io.IOException;
24-
import java.util.Collections;
2524
import java.util.List;
2625
import java.util.stream.Collectors;
2726

@@ -43,9 +42,7 @@ public class RpcEndpointServicePluginTest extends AcceptanceTestBase {
4342

4443
@Before
4544
public void setUp() throws Exception {
46-
node =
47-
besu.createPluginsNode(
48-
"node1", Collections.singletonList("testPlugins"), Collections.emptyList());
45+
node = besu.createPluginsNode("node1", List.of("testPlugins"), List.of("--rpc-http-api=TESTS"));
4946
cluster.start(node);
5047
client = new OkHttpClient();
5148
}
@@ -54,34 +51,40 @@ public void setUp() throws Exception {
5451
public void canUseRpcToSetValue() throws IOException {
5552
String setValue = "secondCall";
5653

57-
ObjectNode resultJson = callTestMethod("unitTests_getValue", List.of());
54+
ObjectNode resultJson = callTestMethod("tests_getValue", List.of());
5855
assertThat(resultJson.get("result").asText()).isEqualTo("InitialValue");
5956

60-
resultJson = callTestMethod("unitTests_setValue", List.of(setValue));
57+
resultJson = callTestMethod("tests_setValue", List.of(setValue));
6158
assertThat(resultJson.get("result").asText()).isEqualTo(setValue);
6259

63-
resultJson = callTestMethod("unitTests_getValue", List.of("ignored"));
60+
resultJson = callTestMethod("tests_getValue", List.of("ignored"));
6461
assertThat(resultJson.get("result").asText()).isEqualTo(setValue);
6562
}
6663

6764
@Test
6865
public void canCheckArgumentInsideSetValue() throws IOException {
69-
ObjectNode resultJson = callTestMethod("unitTests_setValue", List.of("one", "two"));
66+
ObjectNode resultJson = callTestMethod("tests_setValue", List.of("one", "two"));
7067
assertThat(resultJson.get("error").get("message").asText()).isEqualTo("Internal error");
7168
}
7269

7370
@Test
7471
public void canThrowExceptions() throws IOException {
75-
ObjectNode resultJson = callTestMethod("unitTests_throwException", List.of());
72+
ObjectNode resultJson = callTestMethod("tests_throwException", List.of());
7673
assertThat(resultJson.get("error").get("message").asText()).isEqualTo("Internal error");
7774
}
7875

76+
@Test
77+
public void onlyEnabledMethodsReturn() throws IOException {
78+
ObjectNode resultJson = callTestMethod("notEnabled_getValue", List.of());
79+
assertThat(resultJson.get("error").get("message").asText()).isEqualTo("Method not found");
80+
}
81+
7982
@Test
8083
public void mixedTypeArraysAreStringified() throws IOException {
81-
ObjectNode resultJson = callTestMethod("unitTests_replaceValueList", List.of());
84+
ObjectNode resultJson = callTestMethod("tests_replaceValueList", List.of());
8285
assertThat(resultJson.get("result")).isEmpty();
8386

84-
resultJson = callTestMethod("unitTests_replaceValueList", List.of("One", 2, true));
87+
resultJson = callTestMethod("tests_replaceValueList", List.of("One", 2, true));
8588
JsonNode result = resultJson.get("result");
8689

8790
assertThat(result.get(0).asText()).isEqualTo("One");

besu/src/main/java/org/hyperledger/besu/RunnerBuilder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ private Map<String, JsonRpcMethod> jsonRpcMethods(
863863
dataDir,
864864
besuController.getProtocolManager().ethContext().getEthPeers());
865865
methods.putAll(besuController.getAdditionalJsonRpcMethods(jsonRpcApis));
866-
methods.putAll(rpcEndpointServiceImpl.getPluginMethods());
866+
methods.putAll(rpcEndpointServiceImpl.getPluginMethods(jsonRpcConfiguration.getRpcApis()));
867867
return methods;
868868
}
869869

@@ -965,6 +965,11 @@ private WebSocketService createWebsocketService(
965965
privateWebSocketMethodsFactory.methods().forEach(websocketMethodsFactory::addMethods);
966966
}
967967

968+
rpcEndpointServiceImpl
969+
.getPluginMethods(configuration.getRpcApis())
970+
.values()
971+
.forEach(websocketMethodsFactory::addMethods);
972+
968973
final WebSocketRequestHandler websocketRequestHandler =
969974
new WebSocketRequestHandler(
970975
vertx,

besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@
196196
import java.util.Set;
197197
import java.util.TreeMap;
198198
import java.util.function.Function;
199+
import java.util.function.Predicate;
199200
import java.util.function.Supplier;
200201
import java.util.stream.Collectors;
201202

@@ -1524,13 +1525,17 @@ private void validateDnsOptionsParams() {
15241525
}
15251526

15261527
public void validateRpcOptionsParams() {
1527-
if (!rpcHttpApis.stream()
1528-
.allMatch(x -> Arrays.stream(RpcApis.values()).anyMatch(y -> x.equals(y.name())))) {
1528+
Predicate<String> configuredApi =
1529+
apiName ->
1530+
Arrays.stream(RpcApis.values())
1531+
.anyMatch(builtInApi -> apiName.equals(builtInApi.name()))
1532+
|| rpcEndpointServiceImpl.hasNamespace(apiName);
1533+
1534+
if (!rpcHttpApis.stream().allMatch(configuredApi)) {
15291535
throw new ParameterException(this.commandLine, "Invalid value for option '--rpc-http-apis'");
15301536
}
15311537

1532-
if (!rpcWsApis.stream()
1533-
.allMatch(x -> Arrays.stream(RpcApis.values()).anyMatch(y -> x.equals(y.name())))) {
1538+
if (!rpcWsApis.stream().allMatch(configuredApi)) {
15341539
throw new ParameterException(this.commandLine, "Invalid value for option '--rpc-ws-apis'");
15351540
}
15361541
}

besu/src/main/java/org/hyperledger/besu/services/RpcEndpointServiceImpl.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.hyperledger.besu.plugin.services.RpcEndpointService;
2323
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
2424

25+
import java.util.Collection;
2526
import java.util.HashMap;
2627
import java.util.Map;
2728
import java.util.function.Function;
@@ -42,9 +43,21 @@ public <T> void registerRPCEndpoint(
4243
rpcMethods.put(namespace + "_" + functionName, function);
4344
}
4445

45-
public Map<String, ? extends JsonRpcMethod> getPluginMethods() {
46+
public Map<String, ? extends JsonRpcMethod> getPluginMethods(
47+
final Collection<String> namespaces) {
4648
return rpcMethods.entrySet().stream()
49+
.filter(
50+
entry ->
51+
namespaces.stream()
52+
.anyMatch(
53+
namespace ->
54+
entry.getKey().toUpperCase().startsWith(namespace.toUpperCase())))
4755
.map(entry -> new PluginJsonRpcMethod(entry.getKey(), entry.getValue()))
4856
.collect(Collectors.toMap(PluginJsonRpcMethod::getName, e -> e));
4957
}
58+
59+
public boolean hasNamespace(final String namespace) {
60+
return rpcMethods.keySet().stream()
61+
.anyMatch(key -> key.toUpperCase().startsWith(namespace.toUpperCase()));
62+
}
5063
}

besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import org.hyperledger.besu.nat.NatMethod;
7676
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration;
7777
import org.hyperledger.besu.plugin.data.EnodeURL;
78+
import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
7879
import org.hyperledger.besu.util.number.Fraction;
7980
import org.hyperledger.besu.util.number.Percentage;
8081

@@ -92,6 +93,7 @@
9293
import java.util.List;
9394
import java.util.Map;
9495
import java.util.Optional;
96+
import java.util.function.Function;
9597
import java.util.stream.Collectors;
9698
import java.util.stream.Stream;
9799

@@ -1926,6 +1928,24 @@ public void rpcApisPropertyWithInvalidEntryMustDisplayError() {
19261928
.contains("Invalid value for option '--rpc-http-apis'");
19271929
}
19281930

1931+
@Test
1932+
public void rpcApisPropertyWithPluginNamespaceAreValid() {
1933+
1934+
rpcEndpointServiceImpl.registerRPCEndpoint(
1935+
"bob", "method", (Function<PluginRpcRequest, Object>) request -> "nothing");
1936+
1937+
parseCommand("--rpc-http-api", "BOB");
1938+
1939+
verify(mockRunnerBuilder).jsonRpcConfiguration(jsonRpcConfigArgumentCaptor.capture());
1940+
verify(mockRunnerBuilder).build();
1941+
1942+
assertThat(jsonRpcConfigArgumentCaptor.getValue().getRpcApis())
1943+
.containsExactlyInAnyOrder("BOB");
1944+
1945+
assertThat(commandOutput.toString()).isEmpty();
1946+
assertThat(commandErrorOutput.toString()).isEmpty();
1947+
}
1948+
19291949
@Test
19301950
public void rpcHttpHostAndPortOptionsMustBeUsed() {
19311951

besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ public abstract class CommandTestAbstract {
130130
private final List<TestBesuCommand> besuCommands = new ArrayList<>();
131131
private KeyPair keyPair;
132132

133+
protected static final RpcEndpointServiceImpl rpcEndpointServiceImpl =
134+
new RpcEndpointServiceImpl();
135+
133136
@Mock protected RunnerBuilder mockRunnerBuilder;
134137
@Mock protected Runner mockRunner;
135138

@@ -402,7 +405,7 @@ public static class TestBesuCommand extends BesuCommand {
402405
new PermissioningServiceImpl(),
403406
new PrivacyPluginServiceImpl(),
404407
pkiBlockCreationConfigProvider,
405-
new RpcEndpointServiceImpl());
408+
rpcEndpointServiceImpl);
406409
this.mockNodeKey = mockNodeKey;
407410
this.keyPair = keyPair;
408411
}

0 commit comments

Comments
 (0)