Nodes whitelist acceptance test (#472)

* Refactoring PantheonNodeFactory and adding PermissioningConfiguration

* Created ClusterConfiguration

* Acceptance test for nodes whitelist

* Fixing constructor

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Lucas Saldanha 6 years ago committed by GitHub
parent 5e53036799
commit 0ba0a05c2a
  1. 1
      acceptance-tests/build.gradle
  2. 4
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/AcceptanceTestBase.java
  3. 8
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java
  4. 8
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java
  5. 1
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java
  6. 18
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/cluster/Cluster.java
  7. 26
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/cluster/ClusterConfiguration.java
  8. 26
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/cluster/ClusterConfigurationBuilder.java
  9. 75
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java
  10. 112
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java
  11. 204
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java
  12. 65
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodesWhitelistAcceptanceTest.java

@ -23,6 +23,7 @@ dependencies {
testImplementation project(':ethereum:core')
testImplementation project(':ethereum:blockcreation')
testImplementation project(':ethereum:jsonrpc')
testImplementation project(':ethereum:p2p')
testImplementation project(':metrics')
testImplementation project(':pantheon')
testImplementation project(':util')

@ -19,8 +19,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.contract.ContractVerifier;
import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth;
import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Net;
import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Web3;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.Cluster;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeFactory;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.cluster.Cluster;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.factory.PantheonNodeFactory;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions;

@ -22,6 +22,7 @@ import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.Util;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.config.PermissioningConfiguration;
import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction;
@ -68,6 +69,7 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto
private final MiningParameters miningParameters;
private final JsonRpcConfiguration jsonRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final PermissioningConfiguration permissioningConfiguration;
private final GenesisConfigProvider genesisConfigProvider;
private final boolean devMode;
@ -80,6 +82,7 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto
final MiningParameters miningParameters,
final JsonRpcConfiguration jsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final PermissioningConfiguration permissioningConfiguration,
final boolean devMode,
final GenesisConfigProvider genesisConfigProvider,
final int p2pPort)
@ -91,6 +94,7 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto
this.miningParameters = miningParameters;
this.jsonRpcConfiguration = jsonRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.genesisConfigProvider = genesisConfigProvider;
this.devMode = devMode;
LOG.info("Created PantheonNode {}", this.toString());
@ -314,6 +318,10 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto
return devMode;
}
PermissioningConfiguration getPermissioningConfiguration() {
return permissioningConfiguration;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)

@ -17,6 +17,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import tech.pegasys.pantheon.cli.EthNetworkConfig;
import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi;
import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApis;
import tech.pegasys.pantheon.ethereum.p2p.config.PermissioningConfiguration;
import java.io.File;
import java.io.IOException;
@ -69,6 +70,13 @@ public class ProcessPantheonNodeRunner implements PantheonNodeRunner {
params.add("--bootnodes");
params.add(String.join(",", node.bootnodes().toString()));
final PermissioningConfiguration permissioningConfiguration =
node.getPermissioningConfiguration();
if (permissioningConfiguration.isNodeWhitelistSet()) {
params.add("--nodes-whitelist");
params.add(String.join(",", permissioningConfiguration.getNodeWhitelist().toString()));
}
if (node.jsonRpcEnabled()) {
params.add("--rpc-enabled");
params.add("--rpc-listen");

@ -86,6 +86,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
.dataDir(node.homeDirectory())
.bannedNodeIds(Collections.emptySet())
.metricsSystem(noOpMetricsSystem)
.permissioningConfiguration(node.getPermissioningConfiguration())
.build();
nodeExecutor.submit(runner::execute);

@ -10,13 +10,17 @@
* 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.tests.acceptance.dsl.node;
package tech.pegasys.pantheon.tests.acceptance.dsl.node.cluster;
import static org.assertj.core.api.Assertions.assertThat;
import tech.pegasys.pantheon.cli.EthNetworkConfig;
import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition;
import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Net;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeRunner;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.RunnableNode;
import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition;
import java.util.ArrayList;
@ -33,8 +37,14 @@ public class Cluster implements AutoCloseable {
private final Map<String, RunnableNode> nodes = new HashMap<>();
private final PantheonNodeRunner pantheonNodeRunner = PantheonNodeRunner.instance();
private final Net net;
private final ClusterConfiguration clusterConfiguration;
public Cluster(final Net net) {
this(new ClusterConfigurationBuilder().build(), net);
}
public Cluster(final ClusterConfiguration clusterConfiguration, final Net net) {
this.clusterConfiguration = clusterConfiguration;
this.net = net;
}
@ -70,8 +80,10 @@ public class Cluster implements AutoCloseable {
node.start(pantheonNodeRunner);
}
for (final RunnableNode node : nodes) {
node.awaitPeerDiscovery(net.awaitPeerCount(nodes.size() - 1));
if (clusterConfiguration.isAwaitPeerDiscovery()) {
for (final RunnableNode node : nodes) {
node.awaitPeerDiscovery(net.awaitPeerCount(nodes.size() - 1));
}
}
}

@ -0,0 +1,26 @@
/*
* 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.tests.acceptance.dsl.node.cluster;
public class ClusterConfiguration {
private final boolean awaitPeerDiscovery;
ClusterConfiguration(final boolean awaitPeerDiscovery) {
this.awaitPeerDiscovery = awaitPeerDiscovery;
}
public boolean isAwaitPeerDiscovery() {
return awaitPeerDiscovery;
}
}

@ -0,0 +1,26 @@
/*
* 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.tests.acceptance.dsl.node.cluster;
public class ClusterConfigurationBuilder {
private boolean awaitPeerDiscovery = true;
public ClusterConfigurationBuilder setAwaitPeerDiscovery(final boolean awaitPeerDiscovery) {
this.awaitPeerDiscovery = awaitPeerDiscovery;
return this;
}
public ClusterConfiguration build() {
return new ClusterConfiguration(awaitPeerDiscovery);
}
}

@ -0,0 +1,75 @@
/*
* 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.tests.acceptance.dsl.node.factory;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.config.PermissioningConfiguration;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.GenesisConfigProvider;
class PantheonFactoryConfiguration {
private final String name;
private final MiningParameters miningParameters;
private final JsonRpcConfiguration jsonRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final PermissioningConfiguration permissioningConfiguration;
private final boolean devMode;
private final GenesisConfigProvider genesisConfigProvider;
PantheonFactoryConfiguration(
final String name,
final MiningParameters miningParameters,
final JsonRpcConfiguration jsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final PermissioningConfiguration permissioningConfiguration,
final boolean devMode,
final GenesisConfigProvider genesisConfigProvider) {
this.name = name;
this.miningParameters = miningParameters;
this.jsonRpcConfiguration = jsonRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.devMode = devMode;
this.genesisConfigProvider = genesisConfigProvider;
}
public String getName() {
return name;
}
public MiningParameters getMiningParameters() {
return miningParameters;
}
public JsonRpcConfiguration getJsonRpcConfiguration() {
return jsonRpcConfiguration;
}
public WebSocketConfiguration getWebSocketConfiguration() {
return webSocketConfiguration;
}
public PermissioningConfiguration getPermissioningConfiguration() {
return permissioningConfiguration;
}
public boolean isDevMode() {
return devMode;
}
public GenesisConfigProvider getGenesisConfigProvider() {
return genesisConfigProvider;
}
}

@ -0,0 +1,112 @@
/*
* 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.tests.acceptance.dsl.node.factory;
import static java.util.Collections.singletonList;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.config.PermissioningConfiguration;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.GenesisConfigProvider;
import java.util.Optional;
public class PantheonFactoryConfigurationBuilder {
private String name;
private MiningParameters miningParameters =
new MiningParametersTestBuilder().enabled(false).build();
private JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault();
private WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault();
private PermissioningConfiguration permissioningConfiguration =
PermissioningConfiguration.createDefault();
private boolean devMode = true;
private GenesisConfigProvider genesisConfigProvider = ignore -> Optional.empty();
public PantheonFactoryConfigurationBuilder setName(final String name) {
this.name = name;
return this;
}
public PantheonFactoryConfigurationBuilder setMiningParameters(
final MiningParameters miningParameters) {
this.miningParameters = miningParameters;
return this;
}
public PantheonFactoryConfigurationBuilder miningEnabled() {
this.miningParameters = new MiningParametersTestBuilder().enabled(true).build();
return this;
}
public PantheonFactoryConfigurationBuilder setJsonRpcConfiguration(
final JsonRpcConfiguration jsonRpcConfiguration) {
this.jsonRpcConfiguration = jsonRpcConfiguration;
return this;
}
public PantheonFactoryConfigurationBuilder jsonRpcEnabled() {
final JsonRpcConfiguration config = JsonRpcConfiguration.createDefault();
config.setEnabled(true);
config.setPort(0);
config.setHostsWhitelist(singletonList("*"));
this.jsonRpcConfiguration = config;
return this;
}
public PantheonFactoryConfigurationBuilder setWebSocketConfiguration(
final WebSocketConfiguration webSocketConfiguration) {
this.webSocketConfiguration = webSocketConfiguration;
return this;
}
public PantheonFactoryConfigurationBuilder webSocketEnabled() {
final WebSocketConfiguration config = WebSocketConfiguration.createDefault();
config.setEnabled(true);
config.setPort(0);
this.webSocketConfiguration = config;
return this;
}
public PantheonFactoryConfigurationBuilder setPermissioningConfiguration(
final PermissioningConfiguration permissioningConfiguration) {
this.permissioningConfiguration = permissioningConfiguration;
return this;
}
public PantheonFactoryConfigurationBuilder setDevMode(final boolean devMode) {
this.devMode = devMode;
return this;
}
public PantheonFactoryConfigurationBuilder setGenesisConfigProvider(
final GenesisConfigProvider genesisConfigProvider) {
this.genesisConfigProvider = genesisConfigProvider;
return this;
}
public PantheonFactoryConfiguration build() {
return new PantheonFactoryConfiguration(
name,
miningParameters,
jsonRpcConfiguration,
webSocketConfiguration,
permissioningConfiguration,
devMode,
genesisConfigProvider);
}
}

@ -10,7 +10,7 @@
* 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.tests.acceptance.dsl.node;
package tech.pegasys.pantheon.tests.acceptance.dsl.node.factory;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
@ -19,11 +19,12 @@ import static tech.pegasys.pantheon.consensus.clique.jsonrpc.CliqueRpcApis.CLIQU
import tech.pegasys.pantheon.consensus.clique.CliqueExtraData;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.MiningParameters;
import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder;
import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration;
import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi;
import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.config.PermissioningConfiguration;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.RunnableNode;
import java.io.IOException;
import java.net.ServerSocket;
@ -47,6 +48,7 @@ public class PantheonNodeFactory {
config.getMiningParameters(),
config.getJsonRpcConfiguration(),
config.getWebSocketConfiguration(),
config.getPermissioningConfiguration(),
config.isDevMode(),
config.getGenesisConfigProvider(),
serverSocket.getLocalPort());
@ -57,76 +59,94 @@ public class PantheonNodeFactory {
public PantheonNode createMinerNode(final String name) throws IOException {
return create(
new PantheonFactoryConfiguration(
name, createMiningParameters(true), createJsonRpcConfig(), createWebSocketConfig()));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.miningEnabled()
.jsonRpcEnabled()
.webSocketEnabled()
.build());
}
public PantheonNode createMinerNodeWithCustomRefreshDelay(
final String name, final Long refreshDelay) throws IOException {
WebSocketConfiguration wsConfig = createWebSocketConfig();
WebSocketConfiguration wsConfig = createWebSocketEnabledConfig();
wsConfig.setRefreshDelay(refreshDelay);
return create(
new PantheonFactoryConfiguration(
name, createMiningParameters(true), createJsonRpcConfig(), wsConfig));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.miningEnabled()
.setJsonRpcConfiguration(createJsonRpcEnabledConfig())
.setWebSocketConfiguration(wsConfig)
.build());
}
public PantheonNode createArchiveNode(final String name) throws IOException {
return create(
new PantheonFactoryConfiguration(
name, createMiningParameters(false), createJsonRpcConfig(), createWebSocketConfig()));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.jsonRpcEnabled()
.webSocketEnabled()
.build());
}
public PantheonNode createArchiveNodeWithCustomRefreshDelay(
final String name, final Long refreshDelay) throws IOException {
WebSocketConfiguration wsConfig = createWebSocketConfig();
WebSocketConfiguration wsConfig = createWebSocketEnabledConfig();
wsConfig.setRefreshDelay(refreshDelay);
return create(
new PantheonFactoryConfiguration(
name, createMiningParameters(false), createJsonRpcConfig(), wsConfig));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.setJsonRpcConfiguration(createJsonRpcEnabledConfig())
.setWebSocketConfiguration(wsConfig)
.build());
}
public PantheonNode createArchiveNodeWithRpcDisabled(final String name) throws IOException {
return create(
new PantheonFactoryConfiguration(
name,
createMiningParameters(false),
JsonRpcConfiguration.createDefault(),
WebSocketConfiguration.createDefault()));
return create(new PantheonFactoryConfigurationBuilder().setName(name).build());
}
public PantheonNode createArchiveNodeWithRpcApis(
final String name, final RpcApi... enabledRpcApis) throws IOException {
final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig();
final JsonRpcConfiguration jsonRpcConfig = createJsonRpcEnabledConfig();
jsonRpcConfig.setRpcApis(asList(enabledRpcApis));
final WebSocketConfiguration webSocketConfig = createWebSocketConfig();
final WebSocketConfiguration webSocketConfig = createWebSocketEnabledConfig();
webSocketConfig.setRpcApis(asList(enabledRpcApis));
return create(
new PantheonFactoryConfiguration(
name, createMiningParameters(false), jsonRpcConfig, webSocketConfig));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.setJsonRpcConfiguration(jsonRpcConfig)
.setWebSocketConfiguration(webSocketConfig)
.build());
}
public PantheonNode createCliqueNode(final String name) throws IOException {
public PantheonNode createNodeWithNodesWhitelist(
final String name, final List<URI> nodesWhitelist) throws IOException {
PermissioningConfiguration permissioningConfiguration =
PermissioningConfiguration.createDefault();
permissioningConfiguration.setNodeWhitelist(nodesWhitelist);
return create(
new PantheonFactoryConfiguration(
name,
createMiningParameters(true),
jsonRpcConfigWithClique(),
createWebSocketConfig(),
false,
this::createCliqueGenesisConfig));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.jsonRpcEnabled()
.setPermissioningConfiguration(permissioningConfiguration)
.build());
}
public PantheonNode createCliqueNodeWithValidators(final String name, final String... validators)
throws IOException {
public PantheonNode createCliqueNode(final String name) throws IOException {
return create(
new PantheonFactoryConfiguration(
name,
createMiningParameters(true),
jsonRpcConfigWithClique(),
createWebSocketConfig(),
false,
nodes -> createCliqueGenesisConfigForValidators(asList(validators), nodes)));
new PantheonFactoryConfigurationBuilder()
.setName(name)
.miningEnabled()
.setJsonRpcConfiguration(jsonRpcConfigWithClique())
.setWebSocketConfiguration(createWebSocketEnabledConfig())
.setDevMode(false)
.setGenesisConfigProvider(this::createCliqueGenesisConfig)
.build());
}
private Optional<String> createCliqueGenesisConfig(final Collection<RunnableNode> validators) {
@ -136,11 +156,9 @@ public class PantheonNodeFactory {
return Optional.of(genesis);
}
private Optional<String> createCliqueGenesisConfigForValidators(
final Collection<String> validators, final Collection<RunnableNode> pantheonNodes) {
List<RunnableNode> collect =
pantheonNodes.stream().filter(n -> validators.contains(n.getName())).collect(toList());
return createCliqueGenesisConfig(collect);
private String encodeCliqueExtraData(final Collection<RunnableNode> nodes) {
final List<Address> addresses = nodes.stream().map(RunnableNode::getAddress).collect(toList());
return CliqueExtraData.createGenesisExtraDataString(addresses);
}
private String cliqueGenesisTemplateConfig() {
@ -152,24 +170,37 @@ public class PantheonNodeFactory {
}
}
private String encodeCliqueExtraData(final Collection<RunnableNode> nodes) {
final List<Address> addresses = nodes.stream().map(RunnableNode::getAddress).collect(toList());
return CliqueExtraData.createGenesisExtraDataString(addresses);
public PantheonNode createCliqueNodeWithValidators(final String name, final String... validators)
throws IOException {
return create(
new PantheonFactoryConfigurationBuilder()
.setName(name)
.miningEnabled()
.setJsonRpcConfiguration(jsonRpcConfigWithClique())
.setWebSocketConfiguration(createWebSocketEnabledConfig())
.setDevMode(false)
.setGenesisConfigProvider(
nodes -> createCliqueGenesisConfigForValidators(asList(validators), nodes))
.build());
}
private Optional<String> createCliqueGenesisConfigForValidators(
final Collection<String> validators, final Collection<RunnableNode> pantheonNodes) {
List<RunnableNode> collect =
pantheonNodes.stream().filter(n -> validators.contains(n.getName())).collect(toList());
return createCliqueGenesisConfig(collect);
}
private JsonRpcConfiguration jsonRpcConfigWithClique() {
final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig();
final JsonRpcConfiguration jsonRpcConfig = createJsonRpcEnabledConfig();
final List<RpcApi> rpcApis = new ArrayList<>(jsonRpcConfig.getRpcApis());
rpcApis.add(CLIQUE);
jsonRpcConfig.setRpcApis(rpcApis);
return jsonRpcConfig;
}
private MiningParameters createMiningParameters(final boolean miner) {
return new MiningParametersTestBuilder().enabled(miner).build();
}
private JsonRpcConfiguration createJsonRpcConfig() {
private JsonRpcConfiguration createJsonRpcEnabledConfig() {
final JsonRpcConfiguration config = JsonRpcConfiguration.createDefault();
config.setEnabled(true);
config.setPort(0);
@ -177,73 +208,10 @@ public class PantheonNodeFactory {
return config;
}
private WebSocketConfiguration createWebSocketConfig() {
private WebSocketConfiguration createWebSocketEnabledConfig() {
final WebSocketConfiguration config = WebSocketConfiguration.createDefault();
config.setEnabled(true);
config.setPort(0);
return config;
}
static class PantheonFactoryConfiguration {
private final String name;
private final MiningParameters miningParameters;
private final JsonRpcConfiguration jsonRpcConfiguration;
private final WebSocketConfiguration webSocketConfiguration;
private final boolean devMode;
private final GenesisConfigProvider genesisConfigProvider;
public PantheonFactoryConfiguration(
final String name,
final MiningParameters miningParameters,
final JsonRpcConfiguration jsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration) {
this(
name,
miningParameters,
jsonRpcConfiguration,
webSocketConfiguration,
true,
ignore -> Optional.empty());
}
public PantheonFactoryConfiguration(
final String name,
final MiningParameters miningParameters,
final JsonRpcConfiguration jsonRpcConfiguration,
final WebSocketConfiguration webSocketConfiguration,
final boolean devMode,
final GenesisConfigProvider genesisConfigProvider) {
this.name = name;
this.miningParameters = miningParameters;
this.jsonRpcConfiguration = jsonRpcConfiguration;
this.webSocketConfiguration = webSocketConfiguration;
this.devMode = devMode;
this.genesisConfigProvider = genesisConfigProvider;
}
public String getName() {
return name;
}
public MiningParameters getMiningParameters() {
return miningParameters;
}
public JsonRpcConfiguration getJsonRpcConfiguration() {
return jsonRpcConfiguration;
}
public WebSocketConfiguration getWebSocketConfiguration() {
return webSocketConfiguration;
}
public boolean isDevMode() {
return devMode;
}
public GenesisConfigProvider getGenesisConfigProvider() {
return genesisConfigProvider;
}
}
}

@ -0,0 +1,65 @@
/*
* 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.tests.acceptance.permissioning;
import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.cluster.Cluster;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.cluster.ClusterConfiguration;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder;
import java.net.URI;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
public class NodesWhitelistAcceptanceTest extends AcceptanceTestBase {
private Cluster permissionedCluster;
private Node forbiddenNode;
private Node allowedNode;
private Node permissionedNode;
@Before
public void setUp() throws Exception {
final ClusterConfiguration clusterConfiguration =
new ClusterConfigurationBuilder().setAwaitPeerDiscovery(false).build();
permissionedCluster = new Cluster(clusterConfiguration, net);
forbiddenNode = pantheon.createArchiveNode("forbidden-node");
allowedNode = pantheon.createArchiveNode("allowed-node");
permissionedNode =
pantheon.createNodeWithNodesWhitelist(
"permissioned-node", Collections.singletonList(getEnodeURI(allowedNode)));
permissionedCluster.start(allowedNode, forbiddenNode, permissionedNode);
}
@Test
public void permissionedNodeShouldDiscoverOnlyAllowedNode() {
allowedNode.verify(net.awaitPeerCount(2));
forbiddenNode.verify(net.awaitPeerCount(1));
permissionedNode.verify(net.awaitPeerCount(1));
}
private URI getEnodeURI(final Node node) {
return URI.create(((PantheonNode) node).getConfiguration().enodeUrl());
}
@Override
public void tearDownAcceptanceTestBase() {
permissionedCluster.stop();
super.tearDownAcceptanceTestBase();
}
}
Loading…
Cancel
Save