Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
added --nodes-whitelist param to CLI and NodeWhitelistController (#346)
Browse files Browse the repository at this point in the history
* added --nodes-whitelist param to CLI and NodeWhitelistController
  • Loading branch information
macfarla authored Dec 3, 2018
1 parent 665ae97 commit e3a58b6
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2018 ConsenSys AG.
*
* 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.
*/
package tech.pegasys.pantheon.ethereum.permissioning;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class PermissioningConfiguration {
private List<String> nodeWhitelist;
private boolean nodeWhitelistSet;

public List<String> getNodeWhitelist() {
return nodeWhitelist;
}

public static PermissioningConfiguration createDefault() {
final PermissioningConfiguration config = new PermissioningConfiguration();
config.nodeWhitelist = new ArrayList<>();
return config;
}

public void setNodeWhitelist(final Collection<String> nodeWhitelist) {
if (nodeWhitelist != null) {
this.nodeWhitelist.addAll(nodeWhitelist);
this.nodeWhitelistSet = true;
}
}

public boolean isNodeWhitelistSet() {
return nodeWhitelistSet;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2018 ConsenSys AG.
*
* 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.
*/
package tech.pegasys.pantheon.ethereum.permissioning;

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

import java.util.Arrays;

import org.junit.Test;

public class PermissioningConfigurationTest {

@Test
public void defaultConfiguration() {
final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault();
assertThat(configuration.getNodeWhitelist()).isEmpty();
assertThat(configuration.isNodeWhitelistSet()).isFalse();
}

@Test
public void setNodeWhitelist() {
final String[] nodes = {"enode://001@123:4567", "enode://002@123:4567", "enode://003@123:4567"};
final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault();
configuration.setNodeWhitelist(Arrays.asList(nodes));
assertThat(configuration.getNodeWhitelist()).containsExactlyInAnyOrder(nodes);
assertThat(configuration.isNodeWhitelistSet()).isTrue();
}

@Test
public void setNodeWhiteListPassingNull() {
final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault();
configuration.setNodeWhitelist(null);
assertThat(configuration.getNodeWhitelist()).isEmpty();
assertThat(configuration.isNodeWhitelistSet()).isFalse();
}
}
7 changes: 6 additions & 1 deletion pantheon/src/main/java/tech/pegasys/pantheon/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package tech.pegasys.pantheon;

import tech.pegasys.pantheon.controller.NodeWhitelistController;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcHttpService;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketService;
Expand Down Expand Up @@ -46,19 +47,23 @@ public class Runner implements AutoCloseable {
private final PantheonController<?> pantheonController;
private final Path dataDir;

private final NodeWhitelistController nodeWhitelistController;

Runner(
final Vertx vertx,
final NetworkRunner networkRunner,
final Optional<JsonRpcHttpService> jsonRpc,
final Optional<WebSocketService> websocketRpc,
final PantheonController<?> pantheonController,
final Path dataDir) {
final Path dataDir,
final NodeWhitelistController nodeWhitelistController) {
this.vertx = vertx;
this.networkRunner = networkRunner;
this.jsonRpc = jsonRpc;
this.websocketRpc = websocketRpc;
this.pantheonController = pantheonController;
this.dataDir = dataDir;
this.nodeWhitelistController = nodeWhitelistController;
}

public void execute() {
Expand Down
20 changes: 19 additions & 1 deletion pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package tech.pegasys.pantheon;

import tech.pegasys.pantheon.controller.NodeWhitelistController;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.ProtocolContext;
Expand Down Expand Up @@ -50,6 +51,7 @@
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.prometheus.PrometheusMetricsSystem;
import tech.pegasys.pantheon.util.bytes.BytesValue;
Expand Down Expand Up @@ -78,6 +80,7 @@ public class RunnerBuilder {
private WebSocketConfiguration webSocketConfiguration;
private Path dataDir;
private Collection<String> bannedNodeIds;
private PermissioningConfiguration permissioningConfiguration;

public RunnerBuilder vertx(final Vertx vertx) {
this.vertx = vertx;
Expand Down Expand Up @@ -124,6 +127,12 @@ public RunnerBuilder webSocketConfiguration(final WebSocketConfiguration webSock
return this;
}

public RunnerBuilder permissioningConfiguration(
final PermissioningConfiguration permissioningConfiguration) {
this.permissioningConfiguration = permissioningConfiguration;
return this;
}

public RunnerBuilder dataDir(final Path dataDir) {
this.dataDir = dataDir;
return this;
Expand Down Expand Up @@ -259,8 +268,17 @@ public Runner build() {
vertx, webSocketConfiguration, subscriptionManager, webSocketsJsonRpcMethods));
}

NodeWhitelistController nodeWhitelistController =
new NodeWhitelistController(permissioningConfiguration);

return new Runner(
vertx, networkRunner, jsonRpcHttpService, webSocketService, pantheonController, dataDir);
vertx,
networkRunner,
jsonRpcHttpService,
webSocketService,
pantheonController,
dataDir,
nodeWhitelistController);
}

private FilterManager createFilterManager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApis;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.util.InvalidConfigurationException;
import tech.pegasys.pantheon.util.BlockImporter;
import tech.pegasys.pantheon.util.bytes.BytesValue;
Expand Down Expand Up @@ -377,6 +378,17 @@ public static class RpcApisConversionException extends Exception {
)
private final BytesValue extraData = DEFAULT_EXTRA_DATA;

// Permissioning: A list of whitelist nodes can be passed.
@Option(
names = {"--nodes-whitelist"},
paramLabel = "<enode://id@host:port>",
description =
"Comma separated enode URLs for permissioned networks. You may specify an empty list.",
split = ",",
arity = "0..*"
)
private final Collection<String> nodesWhitelist = null;

public PantheonCommand(
final BlockImporter blockImporter,
final RunnerBuilder runnerBuilder,
Expand Down Expand Up @@ -442,7 +454,8 @@ public void run() {
maxPeers,
p2pHostAndPort,
jsonRpcConfiguration(),
webSocketConfiguration());
webSocketConfiguration(),
permissioningConfiguration());
}

PantheonController<?> buildController() {
Expand Down Expand Up @@ -487,6 +500,13 @@ private WebSocketConfiguration webSocketConfiguration() {
return webSocketConfiguration;
}

private PermissioningConfiguration permissioningConfiguration() {
final PermissioningConfiguration permissioningConfiguration =
PermissioningConfiguration.createDefault();
permissioningConfiguration.setNodeWhitelist(nodesWhitelist);
return permissioningConfiguration;
}

private SynchronizerConfiguration buildSyncConfig(final SyncMode syncMode) {
checkNotNull(syncMode);
synchronizerConfigurationBuilder.syncMode(syncMode);
Expand All @@ -502,11 +522,12 @@ private void synchronize(
final int maxPeers,
final HostAndPort discoveryHostAndPort,
final JsonRpcConfiguration jsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration) {
final WebSocketConfiguration webSocketConfiguration,
final PermissioningConfiguration permissioningConfiguration) {

checkNotNull(runnerBuilder);

final Runner runner =
Runner runner =
runnerBuilder
.vertx(Vertx.vertx())
.pantheonController(controller)
Expand All @@ -520,6 +541,7 @@ private void synchronize(
.webSocketConfiguration(webSocketConfiguration)
.dataDir(dataDir)
.bannedNodeIds(bannedNodeIds)
.permissioningConfiguration(permissioningConfiguration)
.build();

addShutdownHook(runner);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2018 ConsenSys AG.
*
* 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.
*/
package tech.pegasys.pantheon.controller;

import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;

import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class NodeWhitelistController {

private static final Logger LOG = LogManager.getLogger();

private static List<String> nodeWhitelist;
private static boolean nodeWhitelistSet = false;

public NodeWhitelistController(final PermissioningConfiguration configuration) {
nodeWhitelist = new ArrayList<>();
if (configuration != null && configuration.getNodeWhitelist() != null) {
nodeWhitelist.addAll(configuration.getNodeWhitelist());
nodeWhitelistSet = true;
}
}

public boolean addNode(final String nodeId) {
return nodeWhitelist.add(nodeId);
}

public boolean removeNode(final String nodeId) {
return nodeWhitelist.remove(nodeId);
}

public static boolean isNodeWhitelistSet() {
return nodeWhitelistSet;
}
}
8 changes: 8 additions & 0 deletions pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule;
import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.storage.StorageProvider;
import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider;
import tech.pegasys.pantheon.util.uint.UInt256;
Expand Down Expand Up @@ -118,6 +119,7 @@ private void syncFromGenesis(final SyncMode mode) throws Exception {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final JsonRpcConfiguration aheadJsonRpcConfiguration = jsonRpcConfiguration();
final WebSocketConfiguration aheadWebSocketConfiguration = wsRpcConfiguration();
final PermissioningConfiguration aheadPermissioningConfiguration = permissioningConfiguration();
final RunnerBuilder runnerBuilder =
new RunnerBuilder()
.vertx(Vertx.vertx())
Expand All @@ -134,6 +136,7 @@ private void syncFromGenesis(final SyncMode mode) throws Exception {
.jsonRpcConfiguration(aheadJsonRpcConfiguration)
.webSocketConfiguration(aheadWebSocketConfiguration)
.dataDir(dbAhead)
.permissioningConfiguration(aheadPermissioningConfiguration)
.build();
try {

Expand Down Expand Up @@ -251,6 +254,11 @@ private WebSocketConfiguration wsRpcConfiguration() {
return configuration;
}

private PermissioningConfiguration permissioningConfiguration() {
final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault();
return configuration;
}

private static void setupState(
final int count,
final ProtocolSchedule<Void> protocolSchedule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.util.BlockImporter;

import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -71,6 +72,7 @@ public abstract class CommandTestAbstract {
@Captor ArgumentCaptor<Integer> intArgumentCaptor;
@Captor ArgumentCaptor<JsonRpcConfiguration> jsonRpcConfigArgumentCaptor;
@Captor ArgumentCaptor<WebSocketConfiguration> wsRpcConfigArgumentCaptor;
@Captor ArgumentCaptor<PermissioningConfiguration> permissioningConfigurationArgumentCaptor;

@Before
public void initMocks() throws Exception {
Expand Down
Loading

0 comments on commit e3a58b6

Please sign in to comment.