From ab52ba3fe1bdd8198e50f357d0d2a22a74ef570a Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Fri, 26 Jul 2019 16:00:44 +1200 Subject: [PATCH] PAN-2723: Testing permissioning with static nodes behaviour (#1764) * PAN-2723: Created Miner API transactions and conditions * PAN-2723: Added static nodes options to permissioned node builder * PAN-2723: Implemented permissioned node with static-nodes AT * PAN-2723: Renaming test * Refactoring test to use the waitForBlockHeight method Signed-off-by: Adrian Sutton --- .../acceptance/dsl/AcceptanceTestBase.java | 3 + .../dsl/condition/eth/EthConditions.java | 5 ++ .../miner/MiningStatusCondition.java | 36 +++++++++ .../acceptance/dsl/node/PantheonNode.java | 2 + .../PantheonFactoryConfigurationBuilder.java | 1 + .../configuration/PantheonNodeFactory.java | 20 ++++- .../PermissionedNodeBuilder.java | 24 +++++- .../dsl/transaction/NodeRequests.java | 8 ++ .../transaction/eth/EthMiningTransaction.java | 38 +++++++++ .../dsl/transaction/eth/EthTransactions.java | 4 + .../miner/MinerRequestFactory.java | 41 ++++++++++ .../miner/MinerStartTransaction.java | 29 +++++++ .../miner/MinerStopTransaction.java | 29 +++++++ .../transaction/miner/MinerTransactions.java | 24 ++++++ ...ntractPermissioningAcceptanceTestBase.java | 24 +++++- ...tPermissioningOutOfSyncAcceptanceTest.java | 21 +---- ...ermissioningStaticNodesAcceptanceTest.java | 81 +++++++++++++++++++ 17 files changed, 364 insertions(+), 26 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/miner/MiningStatusCondition.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthMiningTransaction.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStartTransaction.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStopTransaction.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerTransactions.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/AcceptanceTestBase.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/AcceptanceTestBase.java index 5ae972ff8c..30b6c814e3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/AcceptanceTestBase.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/AcceptanceTestBase.java @@ -32,6 +32,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTrans import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.contract.ContractTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2Transactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.miner.MinerTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.NetTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.perm.PermissioningTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.web3.Web3Transactions; @@ -60,6 +61,7 @@ public class AcceptanceTestBase { protected final PermissioningConditions perm; protected final PermissionedNodeBuilder permissionedNodeBuilder; protected final PermissioningTransactions permissioningTransactions; + protected final MinerTransactions minerTransactions; protected final Web3Conditions web3; protected AcceptanceTestBase() { @@ -71,6 +73,7 @@ public class AcceptanceTestBase { accountTransactions = new AccountTransactions(accounts); permissioningTransactions = new PermissioningTransactions(); contractTransactions = new ContractTransactions(); + minerTransactions = new MinerTransactions(); blockchain = new Blockchain(ethTransactions); clique = new CliqueConditions(ethTransactions, cliqueTransactions); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java index 982ca4145b..742c0d1537 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/eth/EthConditions.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.condition.eth; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.miner.MiningStatusCondition; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; public class EthConditions { @@ -61,4 +62,8 @@ public class EthConditions { return new ExpectSuccessfulEthGetTransactionReceiptWithoutReason( transactions.getTransactionReceiptWithRevertReason(transactionHash)); } + + public Condition miningStatus(final boolean isMining) { + return new MiningStatusCondition(transactions.mining(), isMining); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/miner/MiningStatusCondition.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/miner/MiningStatusCondition.java new file mode 100644 index 0000000000..797fa1a17b --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/miner/MiningStatusCondition.java @@ -0,0 +1,36 @@ +/* + * 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.condition.miner; + +import static org.assertj.core.api.Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthMiningTransaction; + +public class MiningStatusCondition implements Condition { + + private final EthMiningTransaction transaction; + private final boolean expectedMiningStatus; + + public MiningStatusCondition(final EthMiningTransaction transaction, final boolean miningStatus) { + this.transaction = transaction; + this.expectedMiningStatus = miningStatus; + } + + @Override + public void verify(final Node node) { + waitFor(10, () -> assertThat(node.execute(transaction)).isEqualTo(expectedMiningStatus)); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index b638f3cb10..13bac921b1 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -37,6 +37,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueReque import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2RequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.login.LoginRequestFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.miner.MinerRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.perm.PermissioningJsonRpcRequestFactory; @@ -293,6 +294,7 @@ public class PantheonNode implements NodeConfiguration, RunnableNode, AutoClosea new AdminRequestFactory(web3jService), new EeaRequestFactory(web3jService), new CustomRequestFactory(web3jService), + new MinerRequestFactory(web3jService), websocketService, loginRequestFactory()); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java index 3f44f2c905..bbca1dc278 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonFactoryConfigurationBuilder.java @@ -67,6 +67,7 @@ public class PantheonFactoryConfigurationBuilder { public PantheonFactoryConfigurationBuilder miningEnabled() { this.miningParameters = new MiningParametersTestBuilder().enabled(true).build(); + this.jsonRpcConfiguration.addRpcApi(RpcApis.MINER); return this; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java index 408f092f57..6bb440356a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/PantheonNodeFactory.java @@ -222,16 +222,30 @@ public class PantheonNodeFactory { public PantheonNode createCustomGenesisNode( final String name, final String genesisPath, final boolean canBeBootnode) throws IOException { + return createCustomGenesisNode(name, genesisPath, canBeBootnode, false); + } + + public PantheonNode createCustomGenesisNode( + final String name, + final String genesisPath, + final boolean canBeBootnode, + final boolean mining) + throws IOException { final String genesisFile = genesis.readGenesisFile(genesisPath); - return create( + final PantheonFactoryConfigurationBuilder builder = new PantheonFactoryConfigurationBuilder() .name(name) .jsonRpcEnabled() .webSocketEnabled() .genesisConfigProvider((a) -> Optional.of(genesisFile)) .devMode(false) - .bootnodeEligible(canBeBootnode) - .build()); + .bootnodeEligible(canBeBootnode); + + if (mining) { + builder.miningEnabled(); + } + + return create(builder.build()); } public PantheonNode createCliqueNodeWithValidators(final String name, final String... validators) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/permissioning/PermissionedNodeBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/permissioning/PermissionedNodeBuilder.java index dbda8577df..fee56956f0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/permissioning/PermissionedNodeBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/configuration/permissioning/PermissionedNodeBuilder.java @@ -68,6 +68,9 @@ public class PermissionedNodeBuilder { private boolean accountSmartContractPermissioningEnabled = false; private String accountPermissioningSmartContractAddress = null; + private List staticNodes = new ArrayList<>(); + private boolean mining = true; + public PermissionedNodeBuilder name(final String name) { this.name = name; return this; @@ -129,6 +132,16 @@ public class PermissionedNodeBuilder { return this; } + public PermissionedNodeBuilder staticNodes(final List staticNodes) { + this.staticNodes = staticNodes; + return this; + } + + public PermissionedNodeBuilder disableMining() { + this.mining = false; + return this; + } + @SuppressWarnings("UnstableApiUsage") public PermissionedNodeBuilder genesisFile(final String path) { try { @@ -163,8 +176,15 @@ public class PermissionedNodeBuilder { .name(name) .jsonRpcConfiguration(jsonRpcConfigWithPermApiEnabled()) .permissioningConfiguration(permissioningConfiguration) - .bootnodeEligible(false) - .miningEnabled(); + .bootnodeEligible(false); + + if (mining) { + builder.miningEnabled(); + } + + if (!staticNodes.isEmpty()) { + builder.staticNodes(staticNodes); + } if (genesisFile != null) { builder.genesisConfigProvider((a) -> Optional.of(genesisFile)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java index 247859588a..2a93e2aaec 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/NodeRequests.java @@ -17,6 +17,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueReque import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ibft2.Ibft2RequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.login.LoginRequestFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.miner.MinerRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.CustomRequestFactory; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.perm.PermissioningJsonRpcRequestFactory; @@ -36,6 +37,7 @@ public class NodeRequests { private final CustomRequestFactory custom; private final Optional websocketService; private final LoginRequestFactory login; + private final MinerRequestFactory miner; public NodeRequests( final Web3j netEth, @@ -45,6 +47,7 @@ public class NodeRequests { final AdminRequestFactory admin, final EeaRequestFactory eea, final CustomRequestFactory custom, + final MinerRequestFactory miner, final Optional websocketService, final LoginRequestFactory login) { this.netEth = netEth; @@ -54,6 +57,7 @@ public class NodeRequests { this.admin = admin; this.eea = eea; this.custom = custom; + this.miner = miner; this.websocketService = websocketService; this.login = login; } @@ -94,6 +98,10 @@ public class NodeRequests { return login; } + public MinerRequestFactory miner() { + return miner; + } + public void shutdown() { netEth.shutdown(); websocketService.ifPresent(WebSocketService::close); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthMiningTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthMiningTransaction.java new file mode 100644 index 0000000000..bc9dc5e833 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthMiningTransaction.java @@ -0,0 +1,38 @@ +/* + * 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.transaction.eth; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.NodeRequests; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; + +import org.web3j.protocol.core.methods.response.EthMining; + +public class EthMiningTransaction implements Transaction { + + EthMiningTransaction() {} + + @Override + public Boolean execute(final NodeRequests node) { + try { + EthMining response = node.eth().ethMining().send(); + assertThat(response).isNotNull(); + return response.isMining(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java index 807b2f132f..1e9d696c4b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthTransactions.java @@ -59,4 +59,8 @@ public class EthTransactions { final String transactionHash) { return new EthGetTransactionReceiptWithRevertReason(transactionHash); } + + public EthMiningTransaction mining() { + return new EthMiningTransaction(); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java new file mode 100644 index 0000000000..13c596994e --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerRequestFactory.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019 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.transaction.miner; + +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.Request; + +public class MinerRequestFactory { + + private final Web3jService web3jService; + + public MinerRequestFactory(final Web3jService web3jService) { + this.web3jService = web3jService; + } + + Request minerStart() { + return new Request<>( + "miner_start", + null, + web3jService, + org.web3j.protocol.core.methods.response.VoidResponse.class); + } + + Request minerStop() { + return new Request<>( + "miner_stop", + null, + web3jService, + org.web3j.protocol.core.methods.response.VoidResponse.class); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStartTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStartTransaction.java new file mode 100644 index 0000000000..2a7420d9e7 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStartTransaction.java @@ -0,0 +1,29 @@ +/* + * Copyright 2019 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.transaction.miner; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.NodeRequests; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +public class MinerStartTransaction implements Transaction { + + @Override + public Void execute(final NodeRequests node) { + try { + node.miner().minerStart().send(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStopTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStopTransaction.java new file mode 100644 index 0000000000..d505f398af --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerStopTransaction.java @@ -0,0 +1,29 @@ +/* + * Copyright 2019 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.transaction.miner; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.NodeRequests; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +public class MinerStopTransaction implements Transaction { + + @Override + public Void execute(final NodeRequests node) { + try { + node.miner().minerStop().send(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerTransactions.java new file mode 100644 index 0000000000..54deb95c18 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/miner/MinerTransactions.java @@ -0,0 +1,24 @@ +/* + * Copyright 2019 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.transaction.miner; + +public class MinerTransactions { + + public MinerStartTransaction minerStart() { + return new MinerStartTransaction(); + } + + public MinerStopTransaction minerStop() { + return new MinerStopTransaction(); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.java index 5f8a613f2b..c0cb9c32d0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningAcceptanceTestBase.java @@ -12,8 +12,11 @@ */ package tech.pegasys.pantheon.tests.acceptance.permissioning; +import static org.assertj.core.api.Assertions.assertThat; + import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.perm.NodeSmartContractPermissioningConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; @@ -25,14 +28,15 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningTransactions; import java.io.IOException; +import java.math.BigInteger; class NodeSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBase { private final NodeSmartContractPermissioningTransactions smartContractNodePermissioning; private final NodeSmartContractPermissioningConditions nodeSmartContractPermissioningConditions; - private static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009999"; - private static final String GENESIS_FILE = "/permissioning/simple_permissioning_genesis.json"; + protected static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009999"; + protected static final String GENESIS_FILE = "/permissioning/simple_permissioning_genesis.json"; protected final Cluster permissionedCluster; @@ -78,6 +82,14 @@ class NodeSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBas } } + protected Node miner(final String name) { + try { + return pantheon.createCustomGenesisNode(name, GENESIS_FILE, false, true); + } catch (IOException e) { + throw new RuntimeException("Error creating node", e); + } + } + @Override public void tearDownAcceptanceTestBase() { permissionedCluster.stop(); @@ -109,4 +121,12 @@ class NodeSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBas return nodeSmartContractPermissioningConditions.connectionIsForbidden( CONTRACT_ADDRESS, source, target); } + + protected void waitForBlockHeight(final Node node, final long blockchainHeight) { + WaitUtils.waitFor( + 120, + () -> + assertThat(node.execute(ethTransactions.blockNumber())) + .isGreaterThanOrEqualTo(BigInteger.valueOf(blockchainHeight))); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java index c5f64c4383..0f2c1270d9 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java @@ -12,13 +12,8 @@ */ package tech.pegasys.pantheon.tests.acceptance.permissioning; -import static org.assertj.core.api.Assertions.assertThat; - -import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import java.math.BigInteger; - import org.junit.Before; import org.junit.Test; @@ -47,11 +42,7 @@ public class NodeSmartContractPermissioningOutOfSyncAcceptanceTest @Test public void addNodeToClusterAndVerifyNonBootNodePeerConnectionWorksAfterSync() { final long blockchainHeight = 50L; - WaitUtils.waitFor( - 120, - () -> - assertThat(currentHeight(permissionedNodeA)) - .isGreaterThanOrEqualTo(BigInteger.valueOf(blockchainHeight))); + waitForBlockHeight(permissionedNodeA, blockchainHeight); // Add Node B permissionedCluster.addNode(permissionedNodeB); @@ -62,15 +53,7 @@ public class NodeSmartContractPermissioningOutOfSyncAcceptanceTest permissionedNodeB.verify(connectionIsForbidden(permissionedNodeA, permissionedNodeB)); // connection should be allowed after node B syncs - WaitUtils.waitFor( - () -> - assertThat(currentHeight(permissionedNodeB)) - .isGreaterThanOrEqualTo(BigInteger.valueOf(blockchainHeight))); - + waitForBlockHeight(permissionedNodeB, blockchainHeight); permissionedNodeB.verify(connectionIsAllowed(permissionedNodeA, permissionedNodeB)); } - - private BigInteger currentHeight(final Node node) { - return node.execute(ethTransactions.blockNumber()); - } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java new file mode 100644 index 0000000000..176ca59547 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java @@ -0,0 +1,81 @@ +/* + * 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 static java.util.stream.Collectors.toList; + +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.RunnableNode; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; + +import org.jetbrains.annotations.NotNull; +import org.junit.Before; +import org.junit.Test; + +public class NodesSmartContractPermissioningStaticNodesAcceptanceTest + extends NodeSmartContractPermissioningAcceptanceTestBase { + + private Node miner; + private Node permissionedNode; + + @Before + public void setUp() { + miner = miner("miner"); + permissionedCluster.start(miner); + } + + @Test + public void onlyTrustStaticNodesWhileOutOfSync() { + // wait for some blocks so the permissioned node has some syncing to do + waitForBlockHeight(miner, 50); + stopMining(miner); + + // start permissioned node with miner node in the static nodes list + permissionedNode = permissionedNodeWithStaticNodes(Arrays.asList(miner)); + permissionedCluster.addNode(permissionedNode); + + // as soon as we start the node should connect to static nodes + permissionedNode.verify(net.awaitPeerCount(1)); + waitForBlockHeight(permissionedNode, 50); + + // after syncing up with the network the node won't trust static nodes anymore + permissionedNode.verify(net.awaitPeerCount(0)); + } + + private void stopMining(final Node node) { + node.execute(minerTransactions.minerStop()); + node.verify(eth.miningStatus(false)); + } + + private Node permissionedNodeWithStaticNodes(final List staticNodes) { + return permissionedNodeBuilder + .name("node-with-static-nodes") + .genesisFile(GENESIS_FILE) + .nodesContractEnabled(CONTRACT_ADDRESS) + .staticNodes(mapNodesToEnodeURLs(staticNodes)) + .disableMining() + .build(); + } + + @NotNull + private List mapNodesToEnodeURLs(final List staticNodes) { + return staticNodes.stream() + .map(node -> (RunnableNode) node) + .map(RunnableNode::enodeUrl) + .map(URI::toASCIIString) + .collect(toList()); + } +}