From 8699cb800eb8a900f4395c67999e1010021d8ede Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Tue, 16 Oct 2018 16:06:31 +1000 Subject: [PATCH 01/41] [NC-1524] Clique miner acceptance test --- .../clique/CliqueMiningAcceptanceTest.java | 43 + .../tests/acceptance/dsl/node/Cluster.java | 11 +- .../acceptance/dsl/node/PantheonNode.java | 58 +- .../dsl/node/PantheonNodeConfig.java | 77 +- .../dsl/node/ThreadPantheonNodeRunner.java | 25 +- .../src/test/resources/clique/node0_key | 1 + .../test/resources/clique/one_node_poa.json | 810 ++++++++++++++++++ .../pantheon/cli/EthNetworkConfig.java | 4 + .../pegasys/pantheon/cli/PantheonCommand.java | 2 +- 9 files changed, 988 insertions(+), 43 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java create mode 100644 acceptance-tests/src/test/resources/clique/node0_key create mode 100644 acceptance-tests/src/test/resources/clique/one_node_poa.json diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java new file mode 100644 index 0000000000..b106b538b5 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -0,0 +1,43 @@ +package tech.pegasys.pantheon.tests.acceptance.clique; + +import static org.web3j.utils.Convert.Unit.ETHER; +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueNode; + +import org.junit.Before; +import org.junit.Test; +import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { + private PantheonNode minerNode; + + @Before + public void setUp() throws Exception { + minerNode = cluster.create(pantheonCliqueNode("miner1", "clique/one_node_poa.json", + "clique/node0_key")); + cluster.start(minerNode); + } + + @Test + public void shouldMineTransactions() { + final Account fromAccount = accounts.createAccount("account1", "50", ETHER, minerNode); + final Account toAccount = accounts.createAccount("account2", "0", ETHER, minerNode); + accounts.waitForAccountBalance(fromAccount, 50, minerNode); + + accounts.incrementalTransfer(fromAccount, toAccount, 1, minerNode); + accounts.waitForAccountBalance(toAccount, 1, minerNode); + + accounts.incrementalTransfer(fromAccount, toAccount, 2, minerNode); + accounts.waitForAccountBalance(toAccount, 3, minerNode); + + accounts.incrementalTransfer(fromAccount, toAccount, 3, minerNode); + accounts.waitForAccountBalance(toAccount, 6, minerNode); + + accounts.incrementalTransfer(fromAccount, toAccount, 4, minerNode); + accounts.waitForAccountBalance(toAccount, 10, minerNode); + + accounts.incrementalTransfer(fromAccount, toAccount, 5, minerNode); + accounts.waitForAccountBalance(toAccount, 15, minerNode); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index 8e8249ab82..14a6ddd77c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -4,18 +4,16 @@ import static org.web3j.utils.Convert.toWei; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; -import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; -import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; - import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.web3j.utils.Convert.Unit; +import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; +import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; public class Cluster implements AutoCloseable { @@ -67,7 +65,10 @@ public PantheonNode create(final PantheonNodeConfig config) throws IOException { config.getSocketPort(), config.getMiningParameters(), config.getJsonRpcConfiguration(), - config.getWebSocketConfiguration()); + config.getWebSocketConfiguration(), + config.getEthNetworkConfig(), + config.isDevMode(), + config.getKeyPath()); config.closeSocket(); return node; } 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 3514ca530e..dfe11e1007 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 @@ -6,14 +6,9 @@ import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST; import static org.web3j.utils.Numeric.toHexString; -import tech.pegasys.pantheon.controller.KeyPairUtil; -import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; -import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; -import tech.pegasys.pantheon.ethereum.core.Hash; -import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; -import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; - +import com.google.common.base.MoreObjects; +import com.google.common.io.MoreFiles; +import com.google.common.io.RecursiveDeleteOption; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -26,10 +21,6 @@ import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; - -import com.google.common.base.MoreObjects; -import com.google.common.io.MoreFiles; -import com.google.common.io.RecursiveDeleteOption; import org.apache.logging.log4j.Logger; import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.web3j.crypto.RawTransaction; @@ -42,6 +33,14 @@ import org.web3j.utils.Async; import org.web3j.utils.Convert; import org.web3j.utils.Convert.Unit; +import tech.pegasys.pantheon.cli.EthNetworkConfig; +import tech.pegasys.pantheon.controller.KeyPairUtil; +import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; +import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; +import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; +import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; +import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; public class PantheonNode implements AutoCloseable { @@ -60,6 +59,8 @@ public class PantheonNode implements AutoCloseable { private final boolean jsonRpcEnabled; private final boolean wsRpcEnabled; private final Properties portsProperties = new Properties(); + private final EthNetworkConfig ethNetworkConfig; + private final boolean devMode; private List bootnodes = new ArrayList<>(); private Eth eth; @@ -71,10 +72,15 @@ public PantheonNode( final int p2pPort, final MiningParameters miningParameters, final JsonRpcConfiguration jsonRpcConfiguration, - final WebSocketConfiguration webSocketConfiguration) - throws IOException { + final WebSocketConfiguration webSocketConfiguration, + final EthNetworkConfig ethNetworkConfig, + final boolean devMode, + final Optional keyPath + ) throws IOException { + Path homeDirectory = Files.createTempDirectory("acctest"); + copyKey(keyPath, homeDirectory); this.name = name; - this.homeDirectory = Files.createTempDirectory("acctest"); + this.homeDirectory = homeDirectory; this.keyPair = KeyPairUtil.loadKeyPair(homeDirectory); this.p2pPort = p2pPort; this.miningParameters = miningParameters; @@ -82,9 +88,21 @@ public PantheonNode( this.webSocketConfiguration = webSocketConfiguration; this.jsonRpcEnabled = jsonRpcConfiguration.isEnabled(); this.wsRpcEnabled = webSocketConfiguration.isEnabled(); + this.ethNetworkConfig = ethNetworkConfig; + this.devMode = devMode; LOG.info("Created PantheonNode {}", this.toString()); } + private void copyKey(Optional keyPath, Path homeDirectory) { + keyPath.ifPresent(key -> { + try { + Files.copy(key, homeDirectory.resolve("key")); + } catch (IOException e) { + throw new RuntimeException("Can't copy node0_key file to data directory", e); + } + }); + } + public String getName() { return name; } @@ -302,6 +320,15 @@ public MiningParameters getMiningParameters() { return miningParameters; } + public EthNetworkConfig getEthNetworkConfig() { + return ethNetworkConfig; + } + + + public boolean isDevMode() { + return devMode; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -347,4 +374,5 @@ public Eth eth() { return eth; } + } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index e471bc5bde..2ad995dde6 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -1,23 +1,52 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static tech.pegasys.pantheon.cli.EthNetworkConfig.mainnet; + +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Optional; +import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration.RpcApis; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import java.io.IOException; -import java.net.ServerSocket; -import java.util.Arrays; - public class PantheonNodeConfig { - + private static final int NETWORK_ID = 10; private final String name; private final MiningParameters miningParameters; private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; + private final EthNetworkConfig ethNetworkConfig; + private final boolean devMode; + private final Optional keyPath; private ServerSocket serverSocket; + private PantheonNodeConfig( + final String name, + final MiningParameters miningParameters, + final JsonRpcConfiguration jsonRpcConfiguration, + final WebSocketConfiguration webSocketConfiguration, + final EthNetworkConfig ethNetworkConfig, + final boolean devMode, + final Path keyPath + ) { + this.name = name; + this.miningParameters = miningParameters; + this.jsonRpcConfiguration = jsonRpcConfiguration; + this.webSocketConfiguration = webSocketConfiguration; + this.ethNetworkConfig = ethNetworkConfig; + this.devMode = devMode; + this.keyPath = Optional.of(keyPath); + } + private PantheonNodeConfig( final String name, final MiningParameters miningParameters, @@ -27,6 +56,9 @@ private PantheonNodeConfig( this.miningParameters = miningParameters; this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; + this.ethNetworkConfig = createEthNetworkConfig(); + this.devMode = true; + this.keyPath = Optional.empty(); } private PantheonNodeConfig(final String name, final MiningParameters miningParameters) { @@ -34,6 +66,9 @@ private PantheonNodeConfig(final String name, final MiningParameters miningParam this.miningParameters = miningParameters; this.jsonRpcConfiguration = createJsonRpcConfig(); this.webSocketConfiguration = createWebSocketConfig(); + this.ethNetworkConfig = createEthNetworkConfig(); + this.devMode = true; + this.keyPath = Optional.empty(); } private static MiningParameters createMiningParameters(final boolean miner) { @@ -67,6 +102,22 @@ public static PantheonNodeConfig patheonNodeWithRpcApis( name, createMiningParameters(false), jsonRpcConfig, webSocketConfig); } + public static PantheonNodeConfig pantheonCliqueNode(final String name, final String cliqueGenesis, final String keyFile) throws URISyntaxException { + final URI genesisConfig = Resources.getResource(cliqueGenesis).toURI(); + final Path keyPath = Paths.get(Resources.getResource(keyFile).toURI()); + final EthNetworkConfig ethNetworkConfig = new EthNetworkConfig.Builder(EthNetworkConfig.defaultConfig()) + .setGenesisConfig(genesisConfig).build(); + return new PantheonNodeConfig( + name, + createMiningParameters(true), + createJsonRpcConfig(), + createWebSocketConfig(), + ethNetworkConfig, + false, + keyPath + ); + } + private static JsonRpcConfiguration createJsonRpcConfig() { final JsonRpcConfiguration config = JsonRpcConfiguration.createDefault(); config.setEnabled(true); @@ -81,6 +132,10 @@ private static WebSocketConfiguration createWebSocketConfig() { return config; } + private EthNetworkConfig createEthNetworkConfig() { + return new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build(); + } + public void initSocket() throws IOException { serverSocket = new ServerSocket(0); } @@ -108,4 +163,16 @@ public JsonRpcConfiguration getJsonRpcConfiguration() { public WebSocketConfiguration getWebSocketConfiguration() { return webSocketConfiguration; } + + public EthNetworkConfig getEthNetworkConfig() { + return ethNetworkConfig; + } + + public boolean isDevMode() { + return devMode; + } + + public Optional getKeyPath() { + return keyPath; + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index 8651e53a48..b4c03e6091 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -1,29 +1,22 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.node; -import static tech.pegasys.pantheon.cli.EthNetworkConfig.mainnet; - -import tech.pegasys.pantheon.Runner; -import tech.pegasys.pantheon.RunnerBuilder; -import tech.pegasys.pantheon.cli.EthNetworkConfig; -import tech.pegasys.pantheon.cli.PantheonControllerBuilder; -import tech.pegasys.pantheon.controller.PantheonController; -import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration.Builder; - +import io.vertx.core.Vertx; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; - -import io.vertx.core.Vertx; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import tech.pegasys.pantheon.Runner; +import tech.pegasys.pantheon.RunnerBuilder; +import tech.pegasys.pantheon.cli.PantheonControllerBuilder; +import tech.pegasys.pantheon.controller.PantheonController; +import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration.Builder; public class ThreadPantheonNodeRunner implements PantheonNodeRunner { - private static final int NETWORK_ID = 10; - private final Logger LOG = LogManager.getLogger(); private final Map pantheonRunners = new HashMap<>(); private ExecutorService nodeExecutor = Executors.newCachedThreadPool(); @@ -36,18 +29,16 @@ public void startNode(final PantheonNode node) { } final PantheonControllerBuilder builder = new PantheonControllerBuilder(); - final EthNetworkConfig ethNetworkConfig = - new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build(); PantheonController pantheonController; try { pantheonController = builder.build( new Builder().build(), node.homeDirectory(), - ethNetworkConfig, + node.getEthNetworkConfig(), false, node.getMiningParameters(), - true); + node.isDevMode()); } catch (final IOException e) { throw new RuntimeException("Error building PantheonController", e); } diff --git a/acceptance-tests/src/test/resources/clique/node0_key b/acceptance-tests/src/test/resources/clique/node0_key new file mode 100644 index 0000000000..8258370089 --- /dev/null +++ b/acceptance-tests/src/test/resources/clique/node0_key @@ -0,0 +1 @@ +0x04af5cf13dda58b3f9df1a9d156e98800dbca662d9cc4ade1e89ec475f11825a \ No newline at end of file diff --git a/acceptance-tests/src/test/resources/clique/one_node_poa.json b/acceptance-tests/src/test/resources/clique/one_node_poa.json new file mode 100644 index 0000000000..5f70c7184c --- /dev/null +++ b/acceptance-tests/src/test/resources/clique/one_node_poa.json @@ -0,0 +1,810 @@ +{ + "config": { + "chainId": 4, + "homesteadBlock": 1, + "eip150Block": 2, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 3, + "eip158Block": 3, + "byzantiumBlock": 1035301, + "clique": { + "period": 1, + "epoch": 30000 + } + }, + "nonce": "0x0", + "timestamp": "0x58ee40ba", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000be068f726a13c8d46c44be6ce9d275600e1735a40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "0x47b760", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0000000000000000000000000000000000000000": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000001": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000002": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000003": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000004": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000005": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000006": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000007": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000008": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000009": { + "balance": "0x1" + }, + "000000000000000000000000000000000000000a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000000b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000000c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000000d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000000e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000000f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000010": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000011": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000012": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000013": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000014": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000015": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000016": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000017": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000018": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000019": { + "balance": "0x1" + }, + "000000000000000000000000000000000000001a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000001b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000001c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000001d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000001e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000001f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000020": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000021": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000022": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000023": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000024": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000025": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000026": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000027": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000028": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000029": { + "balance": "0x1" + }, + "000000000000000000000000000000000000002a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000002b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000002c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000002d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000002e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000002f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000030": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000031": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000032": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000033": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000034": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000035": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000036": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000037": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000038": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000039": { + "balance": "0x1" + }, + "000000000000000000000000000000000000003a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000003b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000003c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000003d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000003e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000003f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000040": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000041": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000042": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000043": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000044": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000045": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000046": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000047": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000048": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000049": { + "balance": "0x1" + }, + "000000000000000000000000000000000000004a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000004b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000004c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000004d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000004e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000004f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000050": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000051": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000052": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000053": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000054": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000055": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000056": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000057": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000058": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000059": { + "balance": "0x1" + }, + "000000000000000000000000000000000000005a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000005b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000005c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000005d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000005e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000005f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000060": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000061": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000062": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000063": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000064": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000065": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000066": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000067": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000068": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000069": { + "balance": "0x1" + }, + "000000000000000000000000000000000000006a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000006b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000006c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000006d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000006e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000006f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000070": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000071": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000072": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000073": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000074": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000075": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000076": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000077": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000078": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000079": { + "balance": "0x1" + }, + "000000000000000000000000000000000000007a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000007b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000007c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000007d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000007e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000007f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000080": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000081": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000082": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000083": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000084": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000085": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000086": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000087": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000088": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000089": { + "balance": "0x1" + }, + "000000000000000000000000000000000000008a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000008b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000008c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000008d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000008e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000008f": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000090": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000091": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000092": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000093": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000094": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000095": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000096": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000097": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000098": { + "balance": "0x1" + }, + "0000000000000000000000000000000000000099": { + "balance": "0x1" + }, + "000000000000000000000000000000000000009a": { + "balance": "0x1" + }, + "000000000000000000000000000000000000009b": { + "balance": "0x1" + }, + "000000000000000000000000000000000000009c": { + "balance": "0x1" + }, + "000000000000000000000000000000000000009d": { + "balance": "0x1" + }, + "000000000000000000000000000000000000009e": { + "balance": "0x1" + }, + "000000000000000000000000000000000000009f": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a0": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a1": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a2": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a3": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a4": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a5": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a6": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a7": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a8": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000a9": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000aa": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ab": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ac": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ad": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ae": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000af": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b0": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b1": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b2": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b3": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b4": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b5": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b6": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b7": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b8": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000b9": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ba": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000bb": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000bc": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000bd": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000be": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000bf": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c0": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c1": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c2": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c3": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c4": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c5": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c6": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c7": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c8": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000c9": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ca": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000cb": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000cc": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000cd": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ce": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000cf": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d0": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d1": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d2": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d3": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d4": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d5": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d6": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d7": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d8": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000d9": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000da": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000db": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000dc": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000dd": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000de": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000df": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e0": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e1": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e2": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e3": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e4": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e5": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e6": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e7": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e8": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000e9": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ea": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000eb": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ec": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ed": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ee": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000ef": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f0": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f1": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f2": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f3": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f4": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f5": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f6": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f7": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f8": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000f9": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000fa": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000fb": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000fc": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000fd": { + "balance": "0x1" + }, + "00000000000000000000000000000000000000fe": { + "balance": "0x1" + }, + "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { + "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "0xad78ebc5ac6200000" + }, + "627306090abaB3A6e1400e9345bC60c78a8BEf57": { + "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + }, + "f17f52151EbEF6C7334FAD080c5704D77216b732": { + "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + }, + "31b98d14007bdee637298086988a0bbd31184523": { + "balance": "0x200000000000000000000000000000000000000000000000000000000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java index 17569a551a..dc5d6d7723 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java @@ -90,6 +90,10 @@ private static URI jsonConfigURI(final String resourceName) { } } + public static EthNetworkConfig defaultConfig() { + return mainnet(); + } + public static class Builder { private URI genesisConfig; diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index d6bd6a8daf..724af5b0e7 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -525,7 +525,7 @@ private Path getDefaultPantheonDataDir() { private EthNetworkConfig ethNetworkConfig() { final EthNetworkConfig predefinedNetworkConfig = - rinkeby ? EthNetworkConfig.rinkeby() : EthNetworkConfig.mainnet(); + rinkeby ? EthNetworkConfig.rinkeby() : EthNetworkConfig.defaultConfig(); return updateNetworkConfig(predefinedNetworkConfig); } From 907739db709525665c122daf49f73fea5722be6f Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 18 Oct 2018 10:57:12 +1000 Subject: [PATCH 02/41] [NC-1524] Clique miner acceptance test - create clique extra data dynamically --- .../clique/CliqueMiningAcceptanceTest.java | 53 +- .../tests/acceptance/dsl/node/Cluster.java | 29 +- .../acceptance/dsl/node/PantheonNode.java | 45 +- .../dsl/node/PantheonNodeConfig.java | 71 +- .../dsl/node/ProcessPantheonNodeRunner.java | 12 +- .../dsl/node/ThreadPantheonNodeRunner.java | 8 +- .../src/test/resources/clique/clique.json | 42 + .../src/test/resources/clique/node0_key | 1 - .../test/resources/clique/one_node_poa.json | 810 ------------------ .../consensus/clique/CliqueExtraData.java | 27 +- .../pantheon/cli/EthNetworkConfig.java | 35 +- .../pegasys/pantheon/cli/PantheonCommand.java | 10 +- .../cli/PantheonControllerBuilder.java | 4 +- 13 files changed, 235 insertions(+), 912 deletions(-) create mode 100644 acceptance-tests/src/test/resources/clique/clique.json delete mode 100644 acceptance-tests/src/test/resources/clique/node0_key delete mode 100644 acceptance-tests/src/test/resources/clique/one_node_poa.json diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index b106b538b5..5a9d5bca89 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -1,43 +1,50 @@ package tech.pegasys.pantheon.tests.acceptance.clique; -import static org.web3j.utils.Convert.Unit.ETHER; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueNode; +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; -import org.junit.Before; +import java.io.IOException; import org.junit.Test; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { - private PantheonNode minerNode; - @Before - public void setUp() throws Exception { - minerNode = cluster.create(pantheonCliqueNode("miner1", "clique/one_node_poa.json", - "clique/node0_key")); + @Test + public void shouldMineTransactionsOnSingleNode() throws IOException { + final PantheonNode minerNode = cluster.create(pantheonCliqueMinerNode("miner1")); cluster.start(minerNode); + + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); + + minerNode.execute(transactions.createTransfer(sender, 50)); + cluster.verify(sender.balanceEquals(50)); + + minerNode.execute(transactions.createIncrementalTransfers(sender, receiver, 1)); + cluster.verify(receiver.balanceEquals(1)); + + minerNode.execute(transactions.createIncrementalTransfers(sender, receiver, 2)); + cluster.verify(receiver.balanceEquals(3)); } @Test - public void shouldMineTransactions() { - final Account fromAccount = accounts.createAccount("account1", "50", ETHER, minerNode); - final Account toAccount = accounts.createAccount("account2", "0", ETHER, minerNode); - accounts.waitForAccountBalance(fromAccount, 50, minerNode); - - accounts.incrementalTransfer(fromAccount, toAccount, 1, minerNode); - accounts.waitForAccountBalance(toAccount, 1, minerNode); + public void shouldMineTransactionsOnMultipleNodes() throws IOException { + final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); + final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); + final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); + cluster.start(minerNode1, minerNode2, minerNode3); - accounts.incrementalTransfer(fromAccount, toAccount, 2, minerNode); - accounts.waitForAccountBalance(toAccount, 3, minerNode); + final Account sender = accounts.createAccount("account1"); + final Account receiver = accounts.createAccount("account2"); - accounts.incrementalTransfer(fromAccount, toAccount, 3, minerNode); - accounts.waitForAccountBalance(toAccount, 6, minerNode); + minerNode1.execute(transactions.createTransfer(sender, 50)); + cluster.verify(sender.balanceEquals(50)); - accounts.incrementalTransfer(fromAccount, toAccount, 4, minerNode); - accounts.waitForAccountBalance(toAccount, 10, minerNode); + minerNode2.execute(transactions.createIncrementalTransfers(sender, receiver, 1)); + cluster.verify(receiver.balanceEquals(1)); - accounts.incrementalTransfer(fromAccount, toAccount, 5, minerNode); - accounts.waitForAccountBalance(toAccount, 15, minerNode); + minerNode3.execute(transactions.createIncrementalTransfers(sender, receiver, 2)); + cluster.verify(receiver.balanceEquals(3)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index 5d199759d5..60dbce3755 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -16,15 +16,26 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.web3j.utils.Convert.Unit; +import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; public class Cluster implements AutoCloseable { + private static final Logger LOG = LogManager.getLogger(Cluster.class); + public static final int NETWORK_ID = 10; + private final Map nodes = new HashMap<>(); private final PantheonNodeRunner pantheonNodeRunner = PantheonNodeRunner.instance(); @@ -38,8 +49,23 @@ public void start(final PantheonNode... nodes) { bootNodes.add(node.enodeUrl()); } + // TODO create clique genesis file + // TODO how do we know it's a clique config? + + // TODO provide a config file creator? + // (nodes[] -> genesis file) + // need to know it's a clique cluster? + // only apply to clique nodes? + // each node could use same factory? cache result if needed to improve performance? + // need to handle null case? + // factory to create ethNod + for (final PantheonNode node : nodes) { node.bootnodes(bootNodes); + Optional ethNetworkConfig = node.getGenesisConfig() + .apply(Arrays.asList(nodes)) + .map(config -> new EthNetworkConfig(() -> config, NETWORK_ID, bootNodes)); + node.ethNetworkConfig(ethNetworkConfig); node.start(pantheonNodeRunner); } @@ -72,9 +98,8 @@ public PantheonNode create(final PantheonNodeConfig config) throws IOException { config.getMiningParameters(), config.getJsonRpcConfiguration(), config.getWebSocketConfiguration(), - config.getEthNetworkConfig(), config.isDevMode(), - config.getKeyPath()); + config.getGenesisConfig()); config.closeSocket(); return node; } 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 9755d2af7c..a946815282 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 @@ -31,6 +31,7 @@ import java.util.List; import java.util.Optional; import java.util.Properties; +import java.util.function.Function; import java.util.stream.Collectors; import org.apache.logging.log4j.Logger; import org.java_websocket.exceptions.WebsocketNotConnectedException; @@ -44,6 +45,8 @@ import tech.pegasys.pantheon.controller.KeyPairUtil; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; @@ -64,13 +67,14 @@ public class PantheonNode implements Node, AutoCloseable { private final boolean jsonRpcEnabled; private final boolean wsRpcEnabled; private final Properties portsProperties = new Properties(); - private final EthNetworkConfig ethNetworkConfig; + private final Function, Optional> genesisConfig; private final boolean devMode; private List bootnodes = new ArrayList<>(); private Eth eth; private Web3 web3; private Web3j web3j; + private Optional ethNetworkConfig = Optional.empty(); public PantheonNode( final String name, @@ -78,12 +82,10 @@ public PantheonNode( final MiningParameters miningParameters, final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, - final EthNetworkConfig ethNetworkConfig, final boolean devMode, - final Optional keyPath + final Function, Optional> genesisConfig ) throws IOException { - Path homeDirectory = Files.createTempDirectory("acctest"); - copyKey(keyPath, homeDirectory); + final Path homeDirectory = Files.createTempDirectory("acctest"); this.name = name; this.homeDirectory = homeDirectory; this.keyPair = KeyPairUtil.loadKeyPair(homeDirectory); @@ -93,21 +95,11 @@ public PantheonNode( this.webSocketConfiguration = webSocketConfiguration; this.jsonRpcEnabled = jsonRpcConfiguration.isEnabled(); this.wsRpcEnabled = webSocketConfiguration.isEnabled(); - this.ethNetworkConfig = ethNetworkConfig; + this.genesisConfig = genesisConfig; this.devMode = devMode; LOG.info("Created PantheonNode {}", this.toString()); } - private void copyKey(Optional keyPath, Path homeDirectory) { - keyPath.ifPresent(key -> { - try { - Files.copy(key, homeDirectory.resolve("key")); - } catch (IOException e) { - throw new RuntimeException("Can't copy node0_key file to data directory", e); - } - }); - } - public String getName() { return name; } @@ -116,6 +108,10 @@ String enodeUrl() { return "enode://" + keyPair.getPublicKey().toString() + "@" + LOCALHOST + ":" + p2pPort; } + KeyPair keyPair() { + return keyPair; + } + private Optional jsonRpcBaseUrl() { if (jsonRpcEnabled) { return Optional.of( @@ -307,11 +303,12 @@ MiningParameters getMiningParameters() { return miningParameters; } - public EthNetworkConfig getEthNetworkConfig() { - return ethNetworkConfig; + public Address nodeAddress() { + return Address.extract(Hash.hash(keyPair.getPrivateKey().getEncodedBytes())); } + public boolean isDevMode() { return devMode; } @@ -362,6 +359,18 @@ public Eth eth() { return eth; } + public Function, Optional> getGenesisConfig() { + return genesisConfig; + } + + public void ethNetworkConfig(Optional ethNetworkConfig) { + this.ethNetworkConfig = ethNetworkConfig; + } + + public Optional ethNetworkConfig() { + return ethNetworkConfig; + } + @Override public T execute(final Transaction transaction) { return transaction.execute(web3j()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index bbbd5a852d..c907892376 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -12,33 +12,37 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; -import static tech.pegasys.pantheon.cli.EthNetworkConfig.mainnet; +import static java.util.stream.Collectors.toList; +import static java.util.stream.StreamSupport.stream; import com.google.common.io.Resources; import java.io.IOException; import java.net.ServerSocket; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.nio.charset.Charset; import java.util.Arrays; +import java.util.List; import java.util.Optional; -import tech.pegasys.pantheon.cli.EthNetworkConfig; +import java.util.function.Function; +import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; +import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration.RpcApis; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; +import tech.pegasys.pantheon.util.bytes.BytesValue; public class PantheonNodeConfig { - private static final int NETWORK_ID = 10; private final String name; private final MiningParameters miningParameters; private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; - private final EthNetworkConfig ethNetworkConfig; + private final Function, Optional> genesisConfig; private final boolean devMode; - private final Optional keyPath; private ServerSocket serverSocket; private PantheonNodeConfig( @@ -46,17 +50,15 @@ private PantheonNodeConfig( final MiningParameters miningParameters, final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, - final EthNetworkConfig ethNetworkConfig, - final boolean devMode, - final Path keyPath + final Function, Optional> genesisConfig, + final boolean devMode ) { this.name = name; this.miningParameters = miningParameters; this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; - this.ethNetworkConfig = ethNetworkConfig; + this.genesisConfig = genesisConfig; this.devMode = devMode; - this.keyPath = Optional.of(keyPath); } private PantheonNodeConfig( @@ -68,9 +70,8 @@ private PantheonNodeConfig( this.miningParameters = miningParameters; this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; - this.ethNetworkConfig = createEthNetworkConfig(); + this.genesisConfig = (ignore) -> Optional.empty(); this.devMode = true; - this.keyPath = Optional.empty(); } private PantheonNodeConfig(final String name, final MiningParameters miningParameters) { @@ -78,9 +79,8 @@ private PantheonNodeConfig(final String name, final MiningParameters miningParam this.miningParameters = miningParameters; this.jsonRpcConfiguration = createJsonRpcConfig(); this.webSocketConfiguration = createWebSocketConfig(); - this.ethNetworkConfig = createEthNetworkConfig(); + this.genesisConfig = (ignore) -> Optional.empty(); this.devMode = true; - this.keyPath = Optional.empty(); } private static MiningParameters createMiningParameters(final boolean miner) { @@ -114,19 +114,14 @@ public static PantheonNodeConfig patheonNodeWithRpcApis( name, createMiningParameters(false), jsonRpcConfig, webSocketConfig); } - public static PantheonNodeConfig pantheonCliqueNode(final String name, final String cliqueGenesis, final String keyFile) throws URISyntaxException { - final URI genesisConfig = Resources.getResource(cliqueGenesis).toURI(); - final Path keyPath = Paths.get(Resources.getResource(keyFile).toURI()); - final EthNetworkConfig ethNetworkConfig = new EthNetworkConfig.Builder(EthNetworkConfig.defaultConfig()) - .setGenesisConfig(genesisConfig).build(); + public static PantheonNodeConfig pantheonCliqueMinerNode(final String name) { return new PantheonNodeConfig( name, createMiningParameters(true), createJsonRpcConfig(), createWebSocketConfig(), - ethNetworkConfig, - false, - keyPath + PantheonNodeConfig::createGenesisConfig, + false ); } @@ -144,8 +139,25 @@ private static WebSocketConfiguration createWebSocketConfig() { return config; } - private EthNetworkConfig createEthNetworkConfig() { - return new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build(); + private static Optional createGenesisConfig(Iterable pantheonNodes) { + String genesisTemplate = cliqueGenesisTemplateConfig(); + String cliqueExtraData = encodeCliqueExtraData(pantheonNodes); + String genesis = genesisTemplate.replaceAll("%cliqueExtraData%", cliqueExtraData); + return Optional.of(genesis); + } + + private static String cliqueGenesisTemplateConfig() { + try { + URI uri = Resources.getResource("clique/clique.json").toURI(); + return Resources.toString(uri.toURL(), Charset.defaultCharset()); + } catch (URISyntaxException | IOException e) { + throw new IllegalStateException("Unable to get test clique genesis config"); + } + } + + private static String encodeCliqueExtraData(Iterable nodes) { + final List privateKeys = stream(nodes.spliterator(), false).map(node -> node.keyPair().getPrivateKey()).collect(toList()); + return CliqueExtraData.createGenesisExtraDataString(privateKeys); } public void initSocket() throws IOException { @@ -176,15 +188,12 @@ public WebSocketConfiguration getWebSocketConfiguration() { return webSocketConfiguration; } - public EthNetworkConfig getEthNetworkConfig() { - return ethNetworkConfig; + public Function, Optional> getGenesisConfig() { + return genesisConfig; } public boolean isDevMode() { return devMode; } - public Optional getKeyPath() { - return keyPath; - } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index 5bc348554c..18582125ea 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration.RpcApis; import java.io.File; @@ -48,7 +49,9 @@ public void startNode(final PantheonNode node) { params.add("--datadir"); params.add(dataDir.toAbsolutePath().toString()); - params.add("--dev-mode"); + if (node.isDevMode()) { + params.add("--dev-mode"); + } params.add("--p2p-listen"); params.add(node.p2pListenAddress()); @@ -78,6 +81,13 @@ public void startNode(final PantheonNode node) { params.add(apiList(node.webSocketConfiguration().getRpcApis())); } + EthNetworkConfig ethNetworkConfig = null; + if (!ethNetworkConfig.equals(EthNetworkConfig.defaultConfig())) { + // TODO this needs to be a file, copy the uri to a temporary file so that resources can be used in acceptance tests + params.add("--genesis" + ethNetworkConfig.getGenesisConfig()); + params.add("--network-id" + ethNetworkConfig.getNetworkId()); + } + final ProcessBuilder processBuilder = new ProcessBuilder(params) .directory(new File(System.getProperty("user.dir")).getParentFile()) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index 0aa1a6d2d0..a5c7981d4a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -12,6 +12,8 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static tech.pegasys.pantheon.cli.EthNetworkConfig.mainnet; + import io.vertx.core.Vertx; import java.io.IOException; import java.util.HashMap; @@ -23,12 +25,15 @@ import org.apache.logging.log4j.Logger; import tech.pegasys.pantheon.Runner; import tech.pegasys.pantheon.RunnerBuilder; +import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.cli.PantheonControllerBuilder; import tech.pegasys.pantheon.controller.PantheonController; import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration.Builder; public class ThreadPantheonNodeRunner implements PantheonNodeRunner { + private static final int NETWORK_ID = 10; + private final Logger LOG = LogManager.getLogger(); private final Map pantheonRunners = new HashMap<>(); private ExecutorService nodeExecutor = Executors.newCachedThreadPool(); @@ -41,13 +46,14 @@ public void startNode(final PantheonNode node) { } final PantheonControllerBuilder builder = new PantheonControllerBuilder(); + final EthNetworkConfig ethNetworkConfig = node.ethNetworkConfig().orElse(new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build()); PantheonController pantheonController; try { pantheonController = builder.build( new Builder().build(), node.homeDirectory(), - node.getEthNetworkConfig(), + ethNetworkConfig, false, node.getMiningParameters(), node.isDevMode()); diff --git a/acceptance-tests/src/test/resources/clique/clique.json b/acceptance-tests/src/test/resources/clique/clique.json new file mode 100644 index 0000000000..cde67aa457 --- /dev/null +++ b/acceptance-tests/src/test/resources/clique/clique.json @@ -0,0 +1,42 @@ +{ + "config": { + "chainId": 4, + "homesteadBlock": 1, + "eip150Block": 2, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 3, + "eip158Block": 3, + "byzantiumBlock": 1035301, + "clique": { + "period": 5, + "epoch": 30000 + } + }, + "nonce": "0x0", + "timestamp": "0x58ee40ba", + "extraData": "%cliqueExtraData%", + "gasLimit": "0x47b760", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { + "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "0xad78ebc5ac6200000" + }, + "627306090abaB3A6e1400e9345bC60c78a8BEf57": { + "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + }, + "f17f52151EbEF6C7334FAD080c5704D77216b732": { + "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", + "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", + "balance": "90000000000000000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/acceptance-tests/src/test/resources/clique/node0_key b/acceptance-tests/src/test/resources/clique/node0_key deleted file mode 100644 index 8258370089..0000000000 --- a/acceptance-tests/src/test/resources/clique/node0_key +++ /dev/null @@ -1 +0,0 @@ -0x04af5cf13dda58b3f9df1a9d156e98800dbca662d9cc4ade1e89ec475f11825a \ No newline at end of file diff --git a/acceptance-tests/src/test/resources/clique/one_node_poa.json b/acceptance-tests/src/test/resources/clique/one_node_poa.json deleted file mode 100644 index 5f70c7184c..0000000000 --- a/acceptance-tests/src/test/resources/clique/one_node_poa.json +++ /dev/null @@ -1,810 +0,0 @@ -{ - "config": { - "chainId": 4, - "homesteadBlock": 1, - "eip150Block": 2, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 3, - "eip158Block": 3, - "byzantiumBlock": 1035301, - "clique": { - "period": 1, - "epoch": 30000 - } - }, - "nonce": "0x0", - "timestamp": "0x58ee40ba", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000be068f726a13c8d46c44be6ce9d275600e1735a40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x47b760", - "difficulty": "0x1", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "0000000000000000000000000000000000000000": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000001": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000002": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000003": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000004": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000005": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000006": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000007": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000008": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000009": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000000f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000010": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000011": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000012": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000013": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000014": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000015": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000016": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000017": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000018": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000019": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000001f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000020": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000021": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000022": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000023": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000024": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000025": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000026": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000027": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000028": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000029": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000002f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000030": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000031": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000032": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000033": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000034": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000035": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000036": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000037": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000038": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000039": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000003f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000040": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000041": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000042": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000043": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000044": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000045": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000046": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000047": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000048": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000049": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000004f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000050": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000051": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000052": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000053": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000054": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000055": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000056": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000057": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000058": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000059": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000005f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000060": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000061": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000062": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000063": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000064": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000065": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000066": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000067": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000068": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000069": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000006f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000070": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000071": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000072": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000073": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000074": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000075": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000076": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000077": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000078": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000079": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000007f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000080": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000081": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000082": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000083": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000084": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000085": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000086": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000087": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000088": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000089": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000008f": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000090": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000091": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000092": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000093": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000094": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000095": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000096": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000097": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000098": { - "balance": "0x1" - }, - "0000000000000000000000000000000000000099": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009a": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009b": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009c": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009d": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009e": { - "balance": "0x1" - }, - "000000000000000000000000000000000000009f": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000a9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000aa": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ab": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ac": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ad": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ae": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000af": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000b9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ba": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000be": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000bf": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000c9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ca": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ce": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000cf": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000d9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000da": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000db": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000dc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000dd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000de": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000df": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000e9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ea": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000eb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ec": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ed": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ee": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000ef": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f0": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f1": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f2": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f3": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f4": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f5": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f6": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f7": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f8": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000f9": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fa": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fb": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fc": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fd": { - "balance": "0x1" - }, - "00000000000000000000000000000000000000fe": { - "balance": "0x1" - }, - "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { - "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", - "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", - "balance": "0xad78ebc5ac6200000" - }, - "627306090abaB3A6e1400e9345bC60c78a8BEf57": { - "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", - "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", - "balance": "90000000000000000000000" - }, - "f17f52151EbEF6C7334FAD080c5704D77216b732": { - "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", - "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", - "balance": "90000000000000000000000" - }, - "31b98d14007bdee637298086988a0bbd31184523": { - "balance": "0x200000000000000000000000000000000000000000000000000000000000000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java index bd18a99fdb..9fe6f56451 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java @@ -15,16 +15,17 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.Lists; +import java.util.List; +import java.util.Optional; +import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; +import tech.pegasys.pantheon.crypto.SECP256K1.PublicKey; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.BytesValues; -import java.util.List; -import java.util.Optional; - -import com.google.common.collect.Lists; - /** * Represents the data structure stored in the extraData field of the BlockHeader used when * operating under an Clique consensus mechanism. @@ -95,6 +96,22 @@ public BytesValue encode() { .orElse(BytesValue.wrap(new byte[Signature.BYTES_REQUIRED]))); } + public static String createGenesisExtraDataString(final List privKeys) { + List
validators = convertPrivKeysToAddresses(privKeys); + CliqueExtraData cliqueExtraData = new CliqueExtraData(BytesValue.wrap(new byte[32]), + null, validators); + BytesValue output = cliqueExtraData.encode(); + return output.toString(); + } + private static List
convertPrivKeysToAddresses(final List privKeys) { + List
validators = Lists.newArrayList(); + for (PrivateKey privKey : privKeys) { + PublicKey pubKey = PublicKey.create(privKey); + validators.add(Util.publicKeyToAddress(pubKey)); + } + return validators; + } + public BytesValue getVanityData() { return vanityData; } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java index 93101f9f3d..16ce965e91 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java @@ -12,28 +12,30 @@ */ package tech.pegasys.pantheon.cli; +import static java.nio.charset.StandardCharsets.UTF_8; import static tech.pegasys.pantheon.controller.CliquePantheonController.RINKEBY_NETWORK_ID; import static tech.pegasys.pantheon.controller.MainnetPantheonController.MAINNET_NETWORK_ID; import static tech.pegasys.pantheon.ethereum.p2p.config.DiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES; import static tech.pegasys.pantheon.ethereum.p2p.config.DiscoveryConfiguration.RINKEBY_BOOTSTRAP_NODES; +import com.google.common.base.Preconditions; +import com.google.common.io.Resources; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.Collection; import java.util.Objects; - -import com.google.common.base.Preconditions; -import com.google.common.io.Resources; +import java.util.function.Supplier; public class EthNetworkConfig { private static final String MAINNET_GENESIS = "mainnet.json"; private static final String RINKEBY_GENESIS = "rinkeby.json"; - private final URI genesisConfig; + private final Supplier genesisConfig; private final int networkId; private final Collection bootNodes; public EthNetworkConfig( - final URI genesisConfig, final int networkId, final Collection bootNodes) { + final Supplier genesisConfig, final int networkId, final Collection bootNodes) { Preconditions.checkNotNull(genesisConfig); Preconditions.checkNotNull(bootNodes); this.genesisConfig = genesisConfig; @@ -41,8 +43,8 @@ public EthNetworkConfig( this.bootNodes = bootNodes; } - public URI getGenesisConfig() { - return genesisConfig; + public String getGenesisConfig() { + return genesisConfig.get(); } public int getNetworkId() { @@ -85,19 +87,18 @@ public String toString() { } public static EthNetworkConfig mainnet() { - final URI genesisConfig = jsonConfigURI(MAINNET_GENESIS); - return new EthNetworkConfig(genesisConfig, MAINNET_NETWORK_ID, MAINNET_BOOTSTRAP_NODES); + return new EthNetworkConfig(() -> jsonConfig(MAINNET_GENESIS), MAINNET_NETWORK_ID, MAINNET_BOOTSTRAP_NODES); } public static EthNetworkConfig rinkeby() { - final URI genesisConfig = jsonConfigURI(RINKEBY_GENESIS); - return new EthNetworkConfig(genesisConfig, RINKEBY_NETWORK_ID, RINKEBY_BOOTSTRAP_NODES); + return new EthNetworkConfig(() -> jsonConfig(RINKEBY_GENESIS), RINKEBY_NETWORK_ID, RINKEBY_BOOTSTRAP_NODES); } - private static URI jsonConfigURI(final String resourceName) { + private static String jsonConfig(final String resourceName) { try { - return Resources.getResource(resourceName).toURI(); - } catch (URISyntaxException e) { + URI uri = Resources.getResource(resourceName).toURI(); + return Resources.toString(uri.toURL(), UTF_8); + } catch (URISyntaxException | IOException e) { throw new IllegalStateException(e); } } @@ -108,7 +109,7 @@ public static EthNetworkConfig defaultConfig() { public static class Builder { - private URI genesisConfig; + private Supplier genesisConfig; private int networkId; private Collection bootNodes; @@ -118,7 +119,9 @@ public Builder(final EthNetworkConfig ethNetworkConfig) { this.bootNodes = ethNetworkConfig.bootNodes; } - public Builder setGenesisConfig(final URI genesisConfig) { + public Builder() {} + + public Builder setGenesisConfig(final Supplier genesisConfig) { this.genesisConfig = genesisConfig; return this; } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index be3c018980..d04d9d0c08 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -13,7 +13,9 @@ package tech.pegasys.pantheon.cli; import static com.google.common.base.Preconditions.checkNotNull; +import static java.nio.charset.StandardCharsets.UTF_8; +import com.google.common.io.Resources; import tech.pegasys.pantheon.Runner; import tech.pegasys.pantheon.RunnerBuilder; import tech.pegasys.pantheon.cli.custom.CorsAllowedOriginsProperty; @@ -544,7 +546,13 @@ private EthNetworkConfig ethNetworkConfig() { private EthNetworkConfig updateNetworkConfig(final EthNetworkConfig ethNetworkConfig) { EthNetworkConfig.Builder builder = new EthNetworkConfig.Builder(ethNetworkConfig); if (genesisFile != null) { - builder.setGenesisConfig(genesisFile.toPath().toUri()); + builder.setGenesisConfig(() -> { + try { + return Resources.toString(genesisFile.toURI().toURL(), UTF_8); + } catch (IOException e) { + throw new IllegalStateException(""); + } + }); } if (networkId != null) { builder.setNetworkId(networkId); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java index bdd04b87f3..de2c57bc0e 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java @@ -49,11 +49,9 @@ public class PantheonControllerBuilder { ethNetworkConfig.getNetworkId(), nodeKeys); } else { - final String genesisConfig = - Resources.toString(ethNetworkConfig.getGenesisConfig().toURL(), UTF_8); return PantheonController.fromConfig( synchronizerConfiguration, - genesisConfig, + ethNetworkConfig.getGenesisConfig(), homePath, syncWithOttoman, ethNetworkConfig.getNetworkId(), From 3440d5fc9d94f3e31bbc44520e0790fa4283d86a Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 18 Oct 2018 14:57:14 +1000 Subject: [PATCH 03/41] [NC-1524] Clique miner acceptance test - spotless and error prone --- acceptance-tests/build.gradle | 1 + .../clique/CliqueMiningAcceptanceTest.java | 18 ++++++++- .../tests/acceptance/dsl/node/Cluster.java | 39 +++++++------------ .../acceptance/dsl/node/PantheonNode.java | 36 ++++++++--------- .../dsl/node/PantheonNodeConfig.java | 37 +++++++++--------- .../dsl/node/ProcessPantheonNodeRunner.java | 25 +++++++++--- .../dsl/node/ThreadPantheonNodeRunner.java | 20 ++++++---- .../consensus/clique/CliqueExtraData.java | 13 ++++--- .../pantheon/cli/EthNetworkConfig.java | 11 ++++-- .../pegasys/pantheon/cli/PantheonCommand.java | 17 ++++---- .../cli/PantheonControllerBuilder.java | 3 -- 11 files changed, 122 insertions(+), 98 deletions(-) diff --git a/acceptance-tests/build.gradle b/acceptance-tests/build.gradle index 79a1388dd8..78f5fd49a3 100644 --- a/acceptance-tests/build.gradle +++ b/acceptance-tests/build.gradle @@ -9,6 +9,7 @@ dependencies { testImplementation project(':ethereum:jsonrpc') testImplementation project(':pantheon') testImplementation project(':util') + testImplementation project(':consensus:clique') testImplementation project( path: ':ethereum:core', configuration: 'testSupportArtifacts') testImplementation 'junit:junit' diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 5a9d5bca89..004fa38b6a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -1,13 +1,27 @@ +/* + * 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.clique; import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; -import java.io.IOException; -import org.junit.Test; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import java.io.IOException; + +import org.junit.Test; + public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index 60dbce3755..e4f5d1d6f2 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -12,28 +12,22 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.cli.EthNetworkConfig; +import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; + import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.web3j.utils.Convert.Unit; -import tech.pegasys.pantheon.cli.EthNetworkConfig; -import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; - public class Cluster implements AutoCloseable { - - private static final Logger LOG = LogManager.getLogger(Cluster.class); public static final int NETWORK_ID = 10; private final Map nodes = new HashMap<>(); @@ -49,22 +43,15 @@ public void start(final PantheonNode... nodes) { bootNodes.add(node.enodeUrl()); } - // TODO create clique genesis file - // TODO how do we know it's a clique config? - - // TODO provide a config file creator? - // (nodes[] -> genesis file) - // need to know it's a clique cluster? - // only apply to clique nodes? - // each node could use same factory? cache result if needed to improve performance? - // need to handle null case? - // factory to create ethNod - for (final PantheonNode node : nodes) { node.bootnodes(bootNodes); - Optional ethNetworkConfig = node.getGenesisConfig() - .apply(Arrays.asList(nodes)) - .map(config -> new EthNetworkConfig(() -> config, NETWORK_ID, bootNodes)); + Optional ethNetworkConfig = + node.getGenesisConfig() + .apply( + stream(nodes) + .filter(n -> n.getMiningParameters().isMiningEnabled()) + .collect(toList())) + .map(config -> new EthNetworkConfig(() -> config, NETWORK_ID, bootNodes)); node.ethNetworkConfig(ethNetworkConfig); node.start(pantheonNodeRunner); } 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 a946815282..59657480fc 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 @@ -17,9 +17,17 @@ import static org.assertj.core.api.Assertions.catchThrowable; import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST; -import com.google.common.base.MoreObjects; -import com.google.common.io.MoreFiles; -import com.google.common.io.RecursiveDeleteOption; +import tech.pegasys.pantheon.cli.EthNetworkConfig; +import tech.pegasys.pantheon.controller.KeyPairUtil; +import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; +import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; +import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; +import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -33,6 +41,10 @@ import java.util.Properties; import java.util.function.Function; import java.util.stream.Collectors; + +import com.google.common.base.MoreObjects; +import com.google.common.io.MoreFiles; +import com.google.common.io.RecursiveDeleteOption; import org.apache.logging.log4j.Logger; import org.java_websocket.exceptions.WebsocketNotConnectedException; import org.web3j.protocol.Web3j; @@ -41,16 +53,6 @@ import org.web3j.protocol.http.HttpService; import org.web3j.protocol.websocket.WebSocketService; import org.web3j.utils.Async; -import tech.pegasys.pantheon.cli.EthNetworkConfig; -import tech.pegasys.pantheon.controller.KeyPairUtil; -import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; -import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; -import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Hash; -import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; -import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; public class PantheonNode implements Node, AutoCloseable { @@ -83,8 +85,8 @@ public PantheonNode( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final boolean devMode, - final Function, Optional> genesisConfig - ) throws IOException { + final Function, Optional> genesisConfig) + throws IOException { final Path homeDirectory = Files.createTempDirectory("acctest"); this.name = name; this.homeDirectory = homeDirectory; @@ -307,8 +309,6 @@ public Address nodeAddress() { return Address.extract(Hash.hash(keyPair.getPrivateKey().getEncodedBytes())); } - - public boolean isDevMode() { return devMode; } @@ -363,7 +363,7 @@ public Function, Optional> getGenesisConfig() { return genesisConfig; } - public void ethNetworkConfig(Optional ethNetworkConfig) { + public void ethNetworkConfig(final Optional ethNetworkConfig) { this.ethNetworkConfig = ethNetworkConfig; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index c907892376..278b1e2bcd 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -15,7 +15,14 @@ import static java.util.stream.Collectors.toList; import static java.util.stream.StreamSupport.stream; -import com.google.common.io.Resources; +import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; +import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; +import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; +import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder; +import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; +import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration.RpcApis; +import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; + import java.io.IOException; import java.net.ServerSocket; import java.net.URI; @@ -25,16 +32,8 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; -import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; -import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; -import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; -import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Hash; -import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder; -import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; -import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration.RpcApis; -import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.util.bytes.BytesValue; + +import com.google.common.io.Resources; public class PantheonNodeConfig { private final String name; @@ -51,8 +50,7 @@ private PantheonNodeConfig( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final Function, Optional> genesisConfig, - final boolean devMode - ) { + final boolean devMode) { this.name = name; this.miningParameters = miningParameters; this.jsonRpcConfiguration = jsonRpcConfiguration; @@ -121,8 +119,7 @@ public static PantheonNodeConfig pantheonCliqueMinerNode(final String name) { createJsonRpcConfig(), createWebSocketConfig(), PantheonNodeConfig::createGenesisConfig, - false - ); + false); } private static JsonRpcConfiguration createJsonRpcConfig() { @@ -139,7 +136,7 @@ private static WebSocketConfiguration createWebSocketConfig() { return config; } - private static Optional createGenesisConfig(Iterable pantheonNodes) { + private static Optional createGenesisConfig(final Iterable pantheonNodes) { String genesisTemplate = cliqueGenesisTemplateConfig(); String cliqueExtraData = encodeCliqueExtraData(pantheonNodes); String genesis = genesisTemplate.replaceAll("%cliqueExtraData%", cliqueExtraData); @@ -155,8 +152,11 @@ private static String cliqueGenesisTemplateConfig() { } } - private static String encodeCliqueExtraData(Iterable nodes) { - final List privateKeys = stream(nodes.spliterator(), false).map(node -> node.keyPair().getPrivateKey()).collect(toList()); + private static String encodeCliqueExtraData(final Iterable nodes) { + final List privateKeys = + stream(nodes.spliterator(), false) + .map(node -> node.keyPair().getPrivateKey()) + .collect(toList()); return CliqueExtraData.createGenesisExtraDataString(privateKeys); } @@ -195,5 +195,4 @@ public Function, Optional> getGenesisConfig() { public boolean isDevMode() { return devMode; } - } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index 18582125ea..c9de65affa 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -12,11 +12,14 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static java.nio.charset.StandardCharsets.UTF_8; + import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration.RpcApis; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; @@ -81,11 +84,13 @@ public void startNode(final PantheonNode node) { params.add(apiList(node.webSocketConfiguration().getRpcApis())); } - EthNetworkConfig ethNetworkConfig = null; - if (!ethNetworkConfig.equals(EthNetworkConfig.defaultConfig())) { - // TODO this needs to be a file, copy the uri to a temporary file so that resources can be used in acceptance tests - params.add("--genesis" + ethNetworkConfig.getGenesisConfig()); - params.add("--network-id" + ethNetworkConfig.getNetworkId()); + if (node.ethNetworkConfig().isPresent()) { + EthNetworkConfig ethNetworkConfig = node.ethNetworkConfig().get(); + Path genesisFile = createGenesisFile(node, ethNetworkConfig); + params.add("--genesis"); + params.add(genesisFile.toString()); + params.add("--network-id"); + params.add(Integer.toString(ethNetworkConfig.getNetworkId())); } final ProcessBuilder processBuilder = @@ -103,6 +108,16 @@ public void startNode(final PantheonNode node) { waitForPortsFile(dataDir); } + private Path createGenesisFile(final PantheonNode node, final EthNetworkConfig ethNetworkConfig) { + try { + Path genesisFile = Files.createTempFile(node.homeDirectory(), "gensis", ""); + Files.write(genesisFile, ethNetworkConfig.getGenesisConfig().getBytes(UTF_8)); + return genesisFile; + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + private String apiList(final Collection rpcApis) { return String.join(",", rpcApis.stream().map(RpcApis::getValue).collect(Collectors.toList())); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index a5c7981d4a..53af82f4ad 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -14,21 +14,23 @@ import static tech.pegasys.pantheon.cli.EthNetworkConfig.mainnet; -import io.vertx.core.Vertx; +import tech.pegasys.pantheon.Runner; +import tech.pegasys.pantheon.RunnerBuilder; +import tech.pegasys.pantheon.cli.EthNetworkConfig; +import tech.pegasys.pantheon.cli.PantheonControllerBuilder; +import tech.pegasys.pantheon.controller.PantheonController; +import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration.Builder; + import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; + +import io.vertx.core.Vertx; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import tech.pegasys.pantheon.Runner; -import tech.pegasys.pantheon.RunnerBuilder; -import tech.pegasys.pantheon.cli.EthNetworkConfig; -import tech.pegasys.pantheon.cli.PantheonControllerBuilder; -import tech.pegasys.pantheon.controller.PantheonController; -import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration.Builder; public class ThreadPantheonNodeRunner implements PantheonNodeRunner { @@ -46,7 +48,9 @@ public void startNode(final PantheonNode node) { } final PantheonControllerBuilder builder = new PantheonControllerBuilder(); - final EthNetworkConfig ethNetworkConfig = node.ethNetworkConfig().orElse(new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build()); + final EthNetworkConfig ethNetworkConfig = + node.ethNetworkConfig() + .orElse(new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build()); PantheonController pantheonController; try { pantheonController = diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java index 9fe6f56451..933f8ec05b 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java @@ -15,9 +15,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.collect.Lists; -import java.util.List; -import java.util.Optional; import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; import tech.pegasys.pantheon.crypto.SECP256K1.PublicKey; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; @@ -26,6 +23,11 @@ import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.BytesValues; +import java.util.List; +import java.util.Optional; + +import com.google.common.collect.Lists; + /** * Represents the data structure stored in the extraData field of the BlockHeader used when * operating under an Clique consensus mechanism. @@ -98,11 +100,12 @@ public BytesValue encode() { public static String createGenesisExtraDataString(final List privKeys) { List
validators = convertPrivKeysToAddresses(privKeys); - CliqueExtraData cliqueExtraData = new CliqueExtraData(BytesValue.wrap(new byte[32]), - null, validators); + CliqueExtraData cliqueExtraData = + new CliqueExtraData(BytesValue.wrap(new byte[32]), null, validators); BytesValue output = cliqueExtraData.encode(); return output.toString(); } + private static List
convertPrivKeysToAddresses(final List privKeys) { List
validators = Lists.newArrayList(); for (PrivateKey privKey : privKeys) { diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java index 16ce965e91..dd7307cb7b 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java @@ -18,8 +18,6 @@ import static tech.pegasys.pantheon.ethereum.p2p.config.DiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES; import static tech.pegasys.pantheon.ethereum.p2p.config.DiscoveryConfiguration.RINKEBY_BOOTSTRAP_NODES; -import com.google.common.base.Preconditions; -import com.google.common.io.Resources; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -27,6 +25,9 @@ import java.util.Objects; import java.util.function.Supplier; +import com.google.common.base.Preconditions; +import com.google.common.io.Resources; + public class EthNetworkConfig { private static final String MAINNET_GENESIS = "mainnet.json"; private static final String RINKEBY_GENESIS = "rinkeby.json"; @@ -87,11 +88,13 @@ public String toString() { } public static EthNetworkConfig mainnet() { - return new EthNetworkConfig(() -> jsonConfig(MAINNET_GENESIS), MAINNET_NETWORK_ID, MAINNET_BOOTSTRAP_NODES); + return new EthNetworkConfig( + () -> jsonConfig(MAINNET_GENESIS), MAINNET_NETWORK_ID, MAINNET_BOOTSTRAP_NODES); } public static EthNetworkConfig rinkeby() { - return new EthNetworkConfig(() -> jsonConfig(RINKEBY_GENESIS), RINKEBY_NETWORK_ID, RINKEBY_BOOTSTRAP_NODES); + return new EthNetworkConfig( + () -> jsonConfig(RINKEBY_GENESIS), RINKEBY_NETWORK_ID, RINKEBY_BOOTSTRAP_NODES); } private static String jsonConfig(final String resourceName) { diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index d04d9d0c08..7b1224a434 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -15,7 +15,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.common.io.Resources; import tech.pegasys.pantheon.Runner; import tech.pegasys.pantheon.RunnerBuilder; import tech.pegasys.pantheon.cli.custom.CorsAllowedOriginsProperty; @@ -46,6 +45,7 @@ import java.util.Collection; import java.util.List; +import com.google.common.io.Resources; import com.google.common.net.HostAndPort; import io.vertx.core.Vertx; import org.apache.logging.log4j.LogManager; @@ -546,13 +546,14 @@ private EthNetworkConfig ethNetworkConfig() { private EthNetworkConfig updateNetworkConfig(final EthNetworkConfig ethNetworkConfig) { EthNetworkConfig.Builder builder = new EthNetworkConfig.Builder(ethNetworkConfig); if (genesisFile != null) { - builder.setGenesisConfig(() -> { - try { - return Resources.toString(genesisFile.toURI().toURL(), UTF_8); - } catch (IOException e) { - throw new IllegalStateException(""); - } - }); + builder.setGenesisConfig( + () -> { + try { + return Resources.toString(genesisFile.toURI().toURL(), UTF_8); + } catch (IOException e) { + throw new IllegalStateException(""); + } + }); } if (networkId != null) { builder.setNetworkId(networkId); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java index de2c57bc0e..096de04c22 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java @@ -12,7 +12,6 @@ */ package tech.pegasys.pantheon.cli; -import static java.nio.charset.StandardCharsets.UTF_8; import static tech.pegasys.pantheon.controller.KeyPairUtil.loadKeyPair; import tech.pegasys.pantheon.controller.MainnetPantheonController; @@ -25,8 +24,6 @@ import java.io.IOException; import java.nio.file.Path; -import com.google.common.io.Resources; - public class PantheonControllerBuilder { public PantheonController build( From 5b3aefb0429b7bf12b966e6528a4f64a37aa109e Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 19 Oct 2018 16:46:00 +1000 Subject: [PATCH 04/41] [NC-1524] Clique miner acceptance test - rpc tests --- .../clique/CliqueRpcAcceptanceTest.java | 124 ++++++++++++++++++ .../dsl/clique/CliqueValidator.java | 30 +++++ .../dsl/condition/ExpectValidators.java | 41 ++++++ .../condition/ExpectValidatorsAtBlock.java | 42 ++++++ .../tests/acceptance/dsl/node/Clique.java | 83 ++++++++++++ .../tests/acceptance/dsl/node/Cluster.java | 7 +- .../tests/acceptance/dsl/node/Node.java | 2 + .../acceptance/dsl/node/PantheonNode.java | 27 ++-- .../dsl/node/PantheonNodeConfig.java | 43 ++++-- .../pantheon/cli/EthNetworkConfig.java | 15 +-- .../pegasys/pantheon/cli/PantheonCommand.java | 18 +-- .../pantheon/cli/PantheonCommandTest.java | 31 +++-- 12 files changed, 410 insertions(+), 53 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java new file mode 100644 index 0000000000..c795531820 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java @@ -0,0 +1,124 @@ +/* + * 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.clique; + +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; + +import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueValidator; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.io.IOException; + +import org.junit.Test; + +public class CliqueRpcAcceptanceTest extends AcceptanceTestBase { + private final CliqueValidator cliqueValidator = new CliqueValidator(); + + @Test + public void shouldAddValidators() throws IOException { + String[] initialValidators = {"miner1", "miner2"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + minerNode1.clique().propose(minerNode3.getAddress(), true); + minerNode2.clique().propose(minerNode3.getAddress(), true); + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + } + + @Test + public void shouldRemoveValidators() throws IOException { + String[] initialValidators = {"miner1", "miner2", "miner3"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().propose(minerNode3.getAddress(), false); + minerNode2.clique().propose(minerNode3.getAddress(), false); + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + } + + @Test + public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { + String[] initialValidators = {"miner1", "miner2"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + minerNode1.clique().propose(minerNode3.getAddress(), true); + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + } + + @Test + public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { + String[] initialValidators = {"miner1", "miner2", "miner3"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().propose(minerNode3.getAddress(), false); + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + } + + @Test + public void shouldDiscardVotes() throws IOException { + String[] initialValidators = {"miner1", "miner2", "miner3"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().propose(minerNode3.getAddress(), false); + minerNode2.clique().propose(minerNode3.getAddress(), false); + minerNode1.clique().discard(minerNode3.getAddress()); + minerNode2.clique().discard(minerNode3.getAddress()); + cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + } + + @Test + public void shouldBeAbleQueryValidatorAtSpecificBlock() throws IOException { + final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); + final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); + final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify( + cliqueValidator.validatorsAtBlockEqual("0x0", minerNode1, minerNode2, minerNode3)); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java new file mode 100644 index 0000000000..41578e4d2a --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java @@ -0,0 +1,30 @@ +/* + * 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.clique; + +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidators; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlock; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +public class CliqueValidator { + + public Condition validatorsEqual(final PantheonNode... validators) { + return new ExpectValidators(validators); + } + + public Condition validatorsAtBlockEqual( + final String blockNumber, final PantheonNode... validators) { + return new ExpectValidatorsAtBlock(blockNumber, validators); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java new file mode 100644 index 0000000000..32d59a786f --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java @@ -0,0 +1,41 @@ +/* + * 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; + +import static java.util.stream.Collectors.toList; +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.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.util.Arrays; +import java.util.Optional; + +public class ExpectValidators implements Condition { + + private PantheonNode[] validators; + + public ExpectValidators(final PantheonNode... validators) { + this.validators = validators; + } + + @Override + public void verify(final Node node) { + waitFor( + () -> + assertThat(node.clique().signersAtBlock(Optional.empty()).getResult()) + .containsAll( + Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java new file mode 100644 index 0000000000..1a1f070753 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java @@ -0,0 +1,42 @@ +/* + * 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; + +import static java.util.stream.Collectors.toList; +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.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.util.Arrays; +import java.util.Optional; + +public class ExpectValidatorsAtBlock implements Condition { + private String blockParameter; + private PantheonNode[] validators; + + public ExpectValidatorsAtBlock(final String blockNumber, final PantheonNode... validators) { + this.blockParameter = blockNumber; + this.validators = validators; + } + + @Override + public void verify(final Node node) { + waitFor( + () -> + assertThat(node.clique().signersAtBlock(Optional.of(blockParameter)).getResult()) + .containsAll( + Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java new file mode 100644 index 0000000000..b6c6f925cf --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java @@ -0,0 +1,83 @@ +/* + * 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; + +import static java.util.Collections.singletonList; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Hash; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; + +public class Clique { + + private Web3jService web3jService; + + public Clique(final Web3jService web3j) { + this.web3jService = web3j; + } + + public static class ProposeResponse extends Response {} + + public static class DiscardResponse extends Response {} + + public static class SignersBlockResponse extends Response> {} + + public ProposeResponse propose(final Address address, final Boolean auth) throws IOException { + Request request = + new Request<>( + "clique_propose", + Arrays.asList(address.toString(), auth.toString()), + web3jService, + ProposeResponse.class); + return request.send(); + } + + public DiscardResponse discard(final Address address) throws IOException { + Request request = + new Request<>( + "clique_discard", + singletonList(address.toString()), + web3jService, + DiscardResponse.class); + return request.send(); + } + + public SignersBlockResponse signersAtBlock(final Optional blockNumber) + throws IOException { + Request request = + new Request<>( + "clique_getSigners", + singletonList(blockNumber.map(Object::toString).orElse("latest")), + web3jService, + SignersBlockResponse.class); + return request.send(); + } + + public SignersBlockResponse signersAtHash(final Hash hash) throws IOException { + Request request = + new Request<>( + "clique_getSigners", + singletonList(hash.toString()), + web3jService, + SignersBlockResponse.class); + return request.send(); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index e4f5d1d6f2..826483a1fb 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -47,11 +47,8 @@ public void start(final PantheonNode... nodes) { node.bootnodes(bootNodes); Optional ethNetworkConfig = node.getGenesisConfig() - .apply( - stream(nodes) - .filter(n -> n.getMiningParameters().isMiningEnabled()) - .collect(toList())) - .map(config -> new EthNetworkConfig(() -> config, NETWORK_ID, bootNodes)); + .apply(stream(nodes).collect(toList())) + .map(config -> new EthNetworkConfig(config, NETWORK_ID, bootNodes)); node.ethNetworkConfig(ethNetworkConfig); node.start(pantheonNodeRunner); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java index bbccde6966..354ec593ad 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java @@ -22,4 +22,6 @@ public interface Node { T execute(Transaction transaction); BigInteger getAccountBalance(Account account); + + Clique clique(); } 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 59657480fc..b085b38de2 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 @@ -22,7 +22,7 @@ import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.ethereum.blockcreation.MiningParameters; import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Hash; +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.tests.acceptance.dsl.account.Account; @@ -36,6 +36,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.Properties; @@ -69,11 +70,12 @@ public class PantheonNode implements Node, AutoCloseable { private final boolean jsonRpcEnabled; private final boolean wsRpcEnabled; private final Properties portsProperties = new Properties(); - private final Function, Optional> genesisConfig; + private final Function, Optional> genesisConfig; private final boolean devMode; private List bootnodes = new ArrayList<>(); private Eth eth; + private Clique clique; private Web3 web3; private Web3j web3j; private Optional ethNetworkConfig = Optional.empty(); @@ -85,7 +87,7 @@ public PantheonNode( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final boolean devMode, - final Function, Optional> genesisConfig) + final Function, Optional> genesisConfig) throws IOException { final Path homeDirectory = Files.createTempDirectory("acctest"); this.name = name; @@ -250,6 +252,10 @@ public void verifyWsRpcDisabled() { .isInstanceOf(WebsocketNotConnectedException.class); } + public Address getAddress() { + return Util.publicKeyToAddress(keyPair.getPublicKey()); + } + Path homeDirectory() { return homeDirectory; } @@ -305,10 +311,6 @@ MiningParameters getMiningParameters() { return miningParameters; } - public Address nodeAddress() { - return Address.extract(Hash.hash(keyPair.getPrivateKey().getEncodedBytes())); - } - public boolean isDevMode() { return devMode; } @@ -359,7 +361,16 @@ public Eth eth() { return eth; } - public Function, Optional> getGenesisConfig() { + @Override + public Clique clique() { + if (clique == null) { + clique = new Clique(new HttpService(jsonRpcBaseUrl().get())); + } + + return clique; + } + + public Function, Optional> getGenesisConfig() { return genesisConfig; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index 278b1e2bcd..d1faa4f944 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -12,8 +12,8 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; -import static java.util.stream.StreamSupport.stream; import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; @@ -28,7 +28,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; -import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.function.Function; @@ -40,7 +40,7 @@ public class PantheonNodeConfig { private final MiningParameters miningParameters; private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; - private final Function, Optional> genesisConfig; + private final Function, Optional> genesisConfig; private final boolean devMode; private ServerSocket serverSocket; @@ -49,7 +49,7 @@ private PantheonNodeConfig( final MiningParameters miningParameters, final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, - final Function, Optional> genesisConfig, + final Function, Optional> genesisConfig, final boolean devMode) { this.name = name; this.miningParameters = miningParameters; @@ -104,9 +104,9 @@ public static PantheonNodeConfig pantheonRpcDisabledNode(final String name) { public static PantheonNodeConfig patheonNodeWithRpcApis( final String name, final RpcApis... enabledRpcApis) { final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); - jsonRpcConfig.setRpcApis(Arrays.asList(enabledRpcApis)); + jsonRpcConfig.setRpcApis(asList(enabledRpcApis)); final WebSocketConfiguration webSocketConfig = createWebSocketConfig(); - webSocketConfig.setRpcApis(Arrays.asList(enabledRpcApis)); + webSocketConfig.setRpcApis(asList(enabledRpcApis)); return new PantheonNodeConfig( name, createMiningParameters(false), jsonRpcConfig, webSocketConfig); @@ -118,7 +118,23 @@ public static PantheonNodeConfig pantheonCliqueMinerNode(final String name) { createMiningParameters(true), createJsonRpcConfig(), createWebSocketConfig(), - PantheonNodeConfig::createGenesisConfig, + PantheonNodeConfig::createCliqueGenesisConfig, + false); + } + + public static PantheonNodeConfig pantheonCliqueMinerNodeWithValidators( + final String name, final String... validators) { + return new PantheonNodeConfig( + name, + createMiningParameters(true), + createJsonRpcConfig(), + createWebSocketConfig(), + clusterNodes -> + createCliqueGenesisConfig( + clusterNodes + .stream() + .filter(n -> asList(validators).contains(n.getName())) + .collect(toList())), false); } @@ -136,9 +152,10 @@ private static WebSocketConfiguration createWebSocketConfig() { return config; } - private static Optional createGenesisConfig(final Iterable pantheonNodes) { + private static Optional createCliqueGenesisConfig( + final Collection validators) { String genesisTemplate = cliqueGenesisTemplateConfig(); - String cliqueExtraData = encodeCliqueExtraData(pantheonNodes); + String cliqueExtraData = encodeCliqueExtraData(validators); String genesis = genesisTemplate.replaceAll("%cliqueExtraData%", cliqueExtraData); return Optional.of(genesis); } @@ -152,11 +169,9 @@ private static String cliqueGenesisTemplateConfig() { } } - private static String encodeCliqueExtraData(final Iterable nodes) { + private static String encodeCliqueExtraData(final Collection nodes) { final List privateKeys = - stream(nodes.spliterator(), false) - .map(node -> node.keyPair().getPrivateKey()) - .collect(toList()); + nodes.stream().map(node -> node.keyPair().getPrivateKey()).collect(toList()); return CliqueExtraData.createGenesisExtraDataString(privateKeys); } @@ -188,7 +203,7 @@ public WebSocketConfiguration getWebSocketConfiguration() { return webSocketConfiguration; } - public Function, Optional> getGenesisConfig() { + public Function, Optional> getGenesisConfig() { return genesisConfig; } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java index dd7307cb7b..ea4ee110df 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java @@ -23,7 +23,6 @@ import java.net.URISyntaxException; import java.util.Collection; import java.util.Objects; -import java.util.function.Supplier; import com.google.common.base.Preconditions; import com.google.common.io.Resources; @@ -31,12 +30,12 @@ public class EthNetworkConfig { private static final String MAINNET_GENESIS = "mainnet.json"; private static final String RINKEBY_GENESIS = "rinkeby.json"; - private final Supplier genesisConfig; + private final String genesisConfig; private final int networkId; private final Collection bootNodes; public EthNetworkConfig( - final Supplier genesisConfig, final int networkId, final Collection bootNodes) { + final String genesisConfig, final int networkId, final Collection bootNodes) { Preconditions.checkNotNull(genesisConfig); Preconditions.checkNotNull(bootNodes); this.genesisConfig = genesisConfig; @@ -45,7 +44,7 @@ public EthNetworkConfig( } public String getGenesisConfig() { - return genesisConfig.get(); + return genesisConfig; } public int getNetworkId() { @@ -89,12 +88,12 @@ public String toString() { public static EthNetworkConfig mainnet() { return new EthNetworkConfig( - () -> jsonConfig(MAINNET_GENESIS), MAINNET_NETWORK_ID, MAINNET_BOOTSTRAP_NODES); + jsonConfig(MAINNET_GENESIS), MAINNET_NETWORK_ID, MAINNET_BOOTSTRAP_NODES); } public static EthNetworkConfig rinkeby() { return new EthNetworkConfig( - () -> jsonConfig(RINKEBY_GENESIS), RINKEBY_NETWORK_ID, RINKEBY_BOOTSTRAP_NODES); + jsonConfig(RINKEBY_GENESIS), RINKEBY_NETWORK_ID, RINKEBY_BOOTSTRAP_NODES); } private static String jsonConfig(final String resourceName) { @@ -112,7 +111,7 @@ public static EthNetworkConfig defaultConfig() { public static class Builder { - private Supplier genesisConfig; + private String genesisConfig; private int networkId; private Collection bootNodes; @@ -124,7 +123,7 @@ public Builder(final EthNetworkConfig ethNetworkConfig) { public Builder() {} - public Builder setGenesisConfig(final Supplier genesisConfig) { + public Builder setGenesisConfig(final String genesisConfig) { this.genesisConfig = genesisConfig; return this; } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index 7b1224a434..e1ebf8ef43 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -546,14 +546,7 @@ private EthNetworkConfig ethNetworkConfig() { private EthNetworkConfig updateNetworkConfig(final EthNetworkConfig ethNetworkConfig) { EthNetworkConfig.Builder builder = new EthNetworkConfig.Builder(ethNetworkConfig); if (genesisFile != null) { - builder.setGenesisConfig( - () -> { - try { - return Resources.toString(genesisFile.toURI().toURL(), UTF_8); - } catch (IOException e) { - throw new IllegalStateException(""); - } - }); + builder.setGenesisConfig(genesisConfig()); } if (networkId != null) { builder.setNetworkId(networkId); @@ -563,4 +556,13 @@ private EthNetworkConfig updateNetworkConfig(final EthNetworkConfig ethNetworkCo } return builder.build(); } + + private String genesisConfig() { + try { + return Resources.toString(genesisFile.toURI().toURL(), UTF_8); + } catch (IOException e) { + throw new ParameterException( + new CommandLine(this), String.format("Unable to load genesis file %s.", genesisFile), e); + } + } } diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java index c75f5b6867..c6f19e3262 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java @@ -39,6 +39,7 @@ import java.io.File; import java.io.IOException; import java.io.Writer; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -127,7 +128,6 @@ public void callingPantheonCommandWithoutOptionsMustSyncWithDefaultValues() thro assertThat(miningArg.getValue().getMinTransactionGasPrice()).isEqualTo(Wei.of(1000)); assertThat(miningArg.getValue().getExtraData()).isEqualTo(BytesValue.EMPTY); assertThat(networkArg.getValue().getNetworkId()).isEqualTo(1); - assertThat(networkArg.getValue().getGenesisConfig().toString()).endsWith("mainnet.json"); assertThat(networkArg.getValue().getBootNodes()).isEqualTo(MAINNET_BOOTSTRAP_NODES); } @@ -206,7 +206,12 @@ public void CallingWithConfigOptionButInvalidValueTomlFileShouldDisplayHelp() th @Test public void OverrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException { - final String configFile = Resources.getResource("complete_config.toml").getFile(); + final URL configFile = Resources.getResource("complete_config.toml"); + final Path genesisFile = createFakeGenesisFile(); + final String updatedConfig = + Resources.toString(configFile, UTF_8).replaceAll("~/genesys.json", genesisFile.toString()); + final Path toml = Files.createTempFile("toml", ""); + Files.write(toml, updatedConfig.getBytes(UTF_8)); final JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault(); jsonRpcConfiguration.setEnabled(false); @@ -221,7 +226,7 @@ public void OverrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException webSocketConfiguration.setPort(9101); webSocketConfiguration.setRpcApis(WebSocketConfiguration.DEFAULT_WEBSOCKET_APIS); - parseCommand("--config", configFile); + parseCommand("--config", toml.toString()); verify(mockRunnerBuilder) .build( @@ -242,7 +247,7 @@ public void OverrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException EthNetworkConfig networkConfig = new Builder(EthNetworkConfig.mainnet()) - .setGenesisConfig(new File("~/genesys.json").toPath().toUri()) + .setGenesisConfig("genesis_config") .setBootNodes(nodes) .build(); verify(mockControllerBuilder) @@ -310,16 +315,16 @@ public void dataDirOptionMustBeUsed() throws Exception { @Test public void genesisPathOptionMustBeUsed() throws Exception { - final Path path = Paths.get("."); + final Path genesisFile = createFakeGenesisFile(); final ArgumentCaptor networkArg = ArgumentCaptor.forClass(EthNetworkConfig.class); - parseCommand("--genesis", path.toString()); + parseCommand("--genesis", genesisFile.toString()); verify(mockControllerBuilder) .build(any(), any(), networkArg.capture(), anyBoolean(), any(), anyBoolean()); - assertThat(networkArg.getValue().getGenesisConfig()).isEqualTo(path.toUri()); + assertThat(networkArg.getValue().getGenesisConfig()).isEqualTo("genesis_config"); assertThat(commandOutput.toString()).isEmpty(); assertThat(commandErrorOutput.toString()).isEmpty(); @@ -813,7 +818,7 @@ public void rinkebyValuesAreUsed() throws Exception { @Test public void rinkebyValuesCanBeOverridden() throws Exception { final String[] nodes = {"enode://001@123:4567", "enode://002@123:4567", "enode://003@123:4567"}; - final Path path = Paths.get("."); + final Path genesisFile = createFakeGenesisFile(); parseCommand( "--rinkeby", "--network-id", @@ -821,7 +826,7 @@ public void rinkebyValuesCanBeOverridden() throws Exception { "--bootnodes", String.join(",", nodes), "--genesis", - path.toString()); + genesisFile.toString()); final ArgumentCaptor networkArg = ArgumentCaptor.forClass(EthNetworkConfig.class); @@ -829,8 +834,14 @@ public void rinkebyValuesCanBeOverridden() throws Exception { .build(any(), any(), networkArg.capture(), anyBoolean(), any(), anyBoolean()); assertThat(commandOutput.toString()).isEmpty(); assertThat(commandErrorOutput.toString()).isEmpty(); - assertThat(networkArg.getValue().getGenesisConfig()).isEqualTo(path.toUri()); + assertThat(networkArg.getValue().getGenesisConfig()).isEqualTo("genesis_config"); assertThat(networkArg.getValue().getBootNodes()).isEqualTo(Arrays.asList(nodes)); assertThat(networkArg.getValue().getNetworkId()).isEqualTo(1); } + + private Path createFakeGenesisFile() throws IOException { + final Path genesisFile = Files.createTempFile("genesisFile", ""); + Files.write(genesisFile, "genesis_config".getBytes(UTF_8)); + return genesisFile; + } } From 7a7f7698d0ddec1ee374219919ce70558086835a Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 19 Oct 2018 16:49:37 +1000 Subject: [PATCH 05/41] [NC-1524] Clique miner acceptance test - spotless --- .../tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index b8aace222f..4ce358f584 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -12,11 +12,11 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; -import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi; -import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApis; 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 java.io.File; import java.io.IOException; From 42379150de3c38e3bfbc6e3177ad1ebf6dc0e84c Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 19 Oct 2018 16:54:22 +1000 Subject: [PATCH 06/41] [NC-1524] Clique miner acceptance test - fix bad merge --- .../consensus/clique/CliqueExtraData.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java index d4dfe92f04..dcd59b6af9 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java @@ -98,23 +98,6 @@ public BytesValue encode() { .orElse(BytesValue.wrap(new byte[Signature.BYTES_REQUIRED]))); } - public static String createGenesisExtraDataString(final List privKeys) { - List
validators = convertPrivKeysToAddresses(privKeys); - CliqueExtraData cliqueExtraData = - new CliqueExtraData(BytesValue.wrap(new byte[32]), null, validators); - BytesValue output = cliqueExtraData.encode(); - return output.toString(); - } - - private static List
convertPrivKeysToAddresses(final List privKeys) { - List
validators = Lists.newArrayList(); - for (PrivateKey privKey : privKeys) { - PublicKey pubKey = PublicKey.create(privKey); - validators.add(Util.publicKeyToAddress(pubKey)); - } - return validators; - } - public BytesValue getVanityData() { return vanityData; } From 6eaad43dc5cfe08e68008d82ca8e8c2ed01cd5e9 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 19 Oct 2018 17:56:07 +1000 Subject: [PATCH 07/41] [NC-1524] Clique miner acceptance test - enable clique rpc --- .../acceptance/dsl/node/PantheonNodeConfig.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index 051fafbfe4..f3243e5742 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -14,6 +14,7 @@ import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; +import static tech.pegasys.pantheon.consensus.clique.jsonrpc.CliqueRpcApis.CLIQUE; import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; @@ -28,6 +29,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -116,7 +118,7 @@ public static PantheonNodeConfig pantheonCliqueMinerNode(final String name) { return new PantheonNodeConfig( name, createMiningParameters(true), - createJsonRpcConfig(), + jsonRpcConfigWithClique(), createWebSocketConfig(), PantheonNodeConfig::createCliqueGenesisConfig, false); @@ -127,7 +129,7 @@ public static PantheonNodeConfig pantheonCliqueMinerNodeWithValidators( return new PantheonNodeConfig( name, createMiningParameters(true), - createJsonRpcConfig(), + jsonRpcConfigWithClique(), createWebSocketConfig(), clusterNodes -> createCliqueGenesisConfig( @@ -175,6 +177,14 @@ private static String encodeCliqueExtraData(final Collection nodes return CliqueExtraData.createGenesisExtraDataString(privateKeys); } + private static JsonRpcConfiguration jsonRpcConfigWithClique() { + final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); + final List rpcApis = new ArrayList<>(jsonRpcConfig.getRpcApis()); + rpcApis.add(CLIQUE); + jsonRpcConfig.setRpcApis(rpcApis); + return jsonRpcConfig; + } + public void initSocket() throws IOException { serverSocket = new ServerSocket(0); } From 5f3d5bbb74ee7dda1c19ffd0a1d30146957676a9 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 24 Oct 2018 09:15:57 +1000 Subject: [PATCH 08/41] [NC-1524] Clique miner acceptance test - discard and proposals rcp tests --- .../CliqueDiscardRpcAcceptanceTest.java | 58 ++++++++++++++++++ .../clique/CliqueGetSignersRpcTest.java | 59 +++++++++++++++++++ .../CliqueProposalRpcAcceptanceTest.java | 48 +++++++++++++++ ...va => CliqueProposeRpcAcceptanceTest.java} | 53 ++++------------- ...ueValidator.java => CliqueConditions.java} | 20 ++++++- .../dsl/condition/ExpectProposals.java | 51 ++++++++++++++++ .../dsl/condition/ExpectValidators.java | 6 +- .../condition/ExpectValidatorsAtBlock.java | 6 +- .../ExpectValidatorsAtBlockHash.java | 42 +++++++++++++ .../tests/acceptance/dsl/node/Clique.java | 19 ++++-- .../acceptance/dsl/node/PantheonNode.java | 5 ++ .../tests/acceptance/dsl/node/Web3.java | 18 +++++- 12 files changed, 328 insertions(+), 57 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/{CliqueRpcAcceptanceTest.java => CliqueProposeRpcAcceptanceTest.java} (59%) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/{CliqueValidator.java => CliqueConditions.java} (61%) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java new file mode 100644 index 0000000000..3b5010370b --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -0,0 +1,58 @@ +/* + * 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.clique; + +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; + +import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.io.IOException; +import java.math.BigInteger; + +import com.google.common.collect.ImmutableMap; +import org.junit.Test; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.response.EthBlock.Block; + +public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBase { + private final CliqueConditions clique = new CliqueConditions(); + + @Test + public void shouldDiscardVotes() throws IOException { + String[] initialValidators = {"miner1", "miner2"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + minerNode1.clique().propose(minerNode2.getAddress(), false); + minerNode1.clique().propose(minerNode3.getAddress(), true); + minerNode2.clique().propose(minerNode2.getAddress(), false); + minerNode2.clique().propose(minerNode3.getAddress(), true); + minerNode1.clique().discard(minerNode2.getAddress()); + minerNode1.clique().discard(minerNode3.getAddress()); + + final DefaultBlockParameter latest = DefaultBlockParameter.valueOf("latest"); + final Block latestBlock = minerNode1.web3().ethGetBlockByNumber(latest, false); + final BigInteger futureBlockNumber = latestBlock.getNumber().add(BigInteger.valueOf(2)); + cluster.verify( + clique.validatorsAtBlockEquals(futureBlockNumber.toString(), minerNode1, minerNode2)); + minerNode1.verify(clique.proposalsEqual(ImmutableMap.of())); + minerNode2.verify(clique.proposalsEqual(ImmutableMap.of(minerNode2, false, minerNode3, true))); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java new file mode 100644 index 0000000000..ec4c8ccc7c --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -0,0 +1,59 @@ +/* + * 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.clique; + +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; + +import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.io.IOException; + +import org.junit.Test; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.response.EthBlock.Block; + +public class CliqueGetSignersRpcTest extends AcceptanceTestBase { + private final CliqueConditions cliqueConditions = new CliqueConditions(); + + @Test + public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { + final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); + final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); + final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); + cluster.start(minerNode1, minerNode2, minerNode3); + + final Block latest = + minerNode1.web3().ethGetBlockByNumber(DefaultBlockParameter.valueOf("latest"), false); + cluster.verify( + cliqueConditions.validatorsAtBlockEquals("0x0", minerNode1, minerNode2, minerNode3)); + cluster.verify( + cliqueConditions.validatorsAtBlockEquals("latest", minerNode1, minerNode2, minerNode3)); + cluster.verify( + cliqueConditions.validatorsAtBlockEquals( + latest.getNumber().toString(), minerNode1, minerNode2, minerNode3)); + } + + @Test + public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { + final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); + final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); + cluster.start(minerNode1, minerNode2); + + final DefaultBlockParameter latest = DefaultBlockParameter.valueOf("latest"); + final Block latestBlock = minerNode1.web3().ethGetBlockByNumber(latest, false); + final String hash = latestBlock.getHash(); + cluster.verify(cliqueConditions.validatorsAtBlockHashEquals(hash, minerNode1, minerNode2)); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java new file mode 100644 index 0000000000..d3771dd087 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -0,0 +1,48 @@ +/* + * 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.clique; + +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; + +import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.io.IOException; + +import com.google.common.collect.ImmutableMap; +import org.junit.Test; + +public class CliqueProposalRpcAcceptanceTest extends AcceptanceTestBase { + private final CliqueConditions clique = new CliqueConditions(); + + @Test + public void shouldReturnProposals() throws IOException { + String[] initialValidators = {"miner1", "miner2"}; + final PantheonNode minerNode1 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + final PantheonNode minerNode2 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + final PantheonNode minerNode3 = + cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); + cluster.start(minerNode1, minerNode2, minerNode3); + + cluster.verify(clique.proposalsEqual(ImmutableMap.of())); + minerNode1.clique().propose(minerNode3.getAddress(), true); + minerNode1.clique().propose(minerNode2.getAddress(), false); + minerNode2.clique().propose(minerNode3.getAddress(), false); + minerNode1.verify(clique.proposalsEqual(ImmutableMap.of(minerNode3, true, minerNode2, false))); + minerNode2.verify(clique.proposalsEqual(ImmutableMap.of(minerNode3, false))); + minerNode3.verify(clique.proposalsEqual(ImmutableMap.of())); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java similarity index 59% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index c795531820..2d07f9476d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -12,19 +12,18 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueValidator; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; import org.junit.Test; -public class CliqueRpcAcceptanceTest extends AcceptanceTestBase { - private final CliqueValidator cliqueValidator = new CliqueValidator(); +public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { + private final CliqueConditions cliqueConditions = new CliqueConditions(); @Test public void shouldAddValidators() throws IOException { @@ -37,10 +36,10 @@ public void shouldAddValidators() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(minerNode1, minerNode2, minerNode3); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); minerNode1.clique().propose(minerNode3.getAddress(), true); minerNode2.clique().propose(minerNode3.getAddress(), true); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); } @Test @@ -54,10 +53,10 @@ public void shouldRemoveValidators() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(minerNode1, minerNode2, minerNode3); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); minerNode1.clique().propose(minerNode3.getAddress(), false); minerNode2.clique().propose(minerNode3.getAddress(), false); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); } @Test @@ -71,9 +70,9 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(minerNode1, minerNode2, minerNode3); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); minerNode1.clique().propose(minerNode3.getAddress(), true); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); } @Test @@ -87,38 +86,8 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(minerNode1, minerNode2, minerNode3); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); minerNode1.clique().propose(minerNode3.getAddress(), false); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); - } - - @Test - public void shouldDiscardVotes() throws IOException { - String[] initialValidators = {"miner1", "miner2", "miner3"}; - final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); - final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); - final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); - - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); - minerNode1.clique().propose(minerNode3.getAddress(), false); - minerNode2.clique().propose(minerNode3.getAddress(), false); - minerNode1.clique().discard(minerNode3.getAddress()); - minerNode2.clique().discard(minerNode3.getAddress()); - cluster.verify(cliqueValidator.validatorsEqual(minerNode1, minerNode2, minerNode3)); - } - - @Test - public void shouldBeAbleQueryValidatorAtSpecificBlock() throws IOException { - final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); - final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - cluster.start(minerNode1, minerNode2, minerNode3); - - cluster.verify( - cliqueValidator.validatorsAtBlockEqual("0x0", minerNode1, minerNode2, minerNode3)); + cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java similarity index 61% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java index 41578e4d2a..f759e7060b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueValidator.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java @@ -12,19 +12,33 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.clique; +import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectProposals; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlock; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlockHash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; -public class CliqueValidator { +import java.util.Map; - public Condition validatorsEqual(final PantheonNode... validators) { +public class CliqueConditions { + + public Condition validatorsEquals(final PantheonNode... validators) { return new ExpectValidators(validators); } - public Condition validatorsAtBlockEqual( + public Condition validatorsAtBlockEquals( final String blockNumber, final PantheonNode... validators) { return new ExpectValidatorsAtBlock(blockNumber, validators); } + + public Condition validatorsAtBlockHashEquals( + final String blockHash, final PantheonNode... validators) { + return new ExpectValidatorsAtBlockHash(Hash.fromHexString(blockHash), validators); + } + + public Condition proposalsEqual(final Map proposals) { + return new ExpectProposals(proposals); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java new file mode 100644 index 0000000000..a546118c51 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java @@ -0,0 +1,51 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +public class ExpectProposals implements Condition { + private Map proposers; + + public ExpectProposals(final Map proposers) { + this.proposers = proposers; + } + + @Override + public void verify(final Node node) { + Map expectedProposers = + proposers + .entrySet() + .stream() + .collect(Collectors.toMap(p -> p.getKey().getAddress().toString(), Entry::getValue)); + waitFor( + () -> { + Map result = node.clique().proposals().getResult(); + Map proposers = + result + .entrySet() + .stream() + .collect(Collectors.toMap(p -> p.getKey().toString(), Entry::getValue)); + assertThat(proposers).isEqualTo(expectedProposers); + }); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java index 32d59a786f..b983ceb578 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java @@ -24,7 +24,7 @@ public class ExpectValidators implements Condition { - private PantheonNode[] validators; + private final PantheonNode[] validators; public ExpectValidators(final PantheonNode... validators) { this.validators = validators; @@ -34,8 +34,8 @@ public ExpectValidators(final PantheonNode... validators) { public void verify(final Node node) { waitFor( () -> - assertThat(node.clique().signersAtBlock(Optional.empty()).getResult()) - .containsAll( + assertThat(node.clique().getSigners(Optional.empty()).getResult()) + .containsExactlyInAnyOrderElementsOf( Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java index 1a1f070753..7d1653fbce 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java @@ -23,7 +23,7 @@ import java.util.Optional; public class ExpectValidatorsAtBlock implements Condition { - private String blockParameter; + private final String blockParameter; private PantheonNode[] validators; public ExpectValidatorsAtBlock(final String blockNumber, final PantheonNode... validators) { @@ -35,8 +35,8 @@ public ExpectValidatorsAtBlock(final String blockNumber, final PantheonNode... v public void verify(final Node node) { waitFor( () -> - assertThat(node.clique().signersAtBlock(Optional.of(blockParameter)).getResult()) - .containsAll( + assertThat(node.clique().getSigners(Optional.of(blockParameter)).getResult()) + .containsExactlyInAnyOrderElementsOf( Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java new file mode 100644 index 0000000000..2366bcf2c9 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java @@ -0,0 +1,42 @@ +/* + * 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; + +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +import java.util.Arrays; + +public class ExpectValidatorsAtBlockHash implements Condition { + private final Hash blockHash; + private final PantheonNode[] validators; + + public ExpectValidatorsAtBlockHash(final Hash blockHash, final PantheonNode... validators) { + this.blockHash = blockHash; + this.validators = validators; + } + + @Override + public void verify(final Node node) { + waitFor( + () -> + assertThat(node.clique().getSignersAtHash(blockHash).getResult()) + .containsExactlyInAnyOrderElementsOf( + Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java index b6c6f925cf..942a11a6de 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import tech.pegasys.pantheon.ethereum.core.Address; @@ -20,6 +21,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Optional; import org.web3j.protocol.Web3jService; @@ -28,7 +30,7 @@ public class Clique { - private Web3jService web3jService; + private final Web3jService web3jService; public Clique(final Web3jService web3j) { this.web3jService = web3j; @@ -40,6 +42,8 @@ public static class DiscardResponse extends Response {} public static class SignersBlockResponse extends Response> {} + public static class ProposalsResponse extends Response> {} + public ProposeResponse propose(final Address address, final Boolean auth) throws IOException { Request request = new Request<>( @@ -60,8 +64,13 @@ public DiscardResponse discard(final Address address) throws IOException { return request.send(); } - public SignersBlockResponse signersAtBlock(final Optional blockNumber) - throws IOException { + public ProposalsResponse proposals() throws IOException { + Request request = + new Request<>("clique_proposals", emptyList(), web3jService, ProposalsResponse.class); + return request.send(); + } + + public SignersBlockResponse getSigners(final Optional blockNumber) throws IOException { Request request = new Request<>( "clique_getSigners", @@ -71,10 +80,10 @@ public SignersBlockResponse signersAtBlock(final Optional blockNumber) return request.send(); } - public SignersBlockResponse signersAtHash(final Hash hash) throws IOException { + public SignersBlockResponse getSignersAtHash(final Hash hash) throws IOException { Request request = new Request<>( - "clique_getSigners", + "clique_getSignersAtHash", singletonList(hash.toString()), web3jService, SignersBlockResponse.class); 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 b085b38de2..2e92754adb 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 @@ -26,6 +26,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.File; @@ -386,4 +387,8 @@ public Optional ethNetworkConfig() { public T execute(final Transaction transaction) { return transaction.execute(web3j()); } + + public void verify(final Condition expected) { + expected.verify(this); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java index a14487161b..f8507267cf 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java @@ -17,6 +17,10 @@ import java.io.IOException; import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.Response; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthBlock.Block; import org.web3j.protocol.core.methods.response.Web3Sha3; public class Web3 { @@ -29,8 +33,20 @@ public Web3(final Web3j web3) { public String web3Sha3(final String input) throws IOException { final Web3Sha3 result = web3j.web3Sha3(input).send(); + assertResponseHasResult(result); + return result.getResult(); + } + + public Block ethGetBlockByNumber( + final DefaultBlockParameter blockParameter, final boolean fullTransactionData) + throws IOException { + EthBlock result = web3j.ethGetBlockByNumber(blockParameter, fullTransactionData).send(); + assertResponseHasResult(result); + return result.getBlock(); + } + + private void assertResponseHasResult(final Response result) { assertThat(result).isNotNull(); assertThat(result.hasError()).isFalse(); - return result.getResult(); } } From 73aa6663bb2c4fc33c7a1d18e7a911ce328adfe5 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 24 Oct 2018 13:59:14 +1000 Subject: [PATCH 09/41] [NC-1524] Clique miner acceptance test - spotless --- .../pantheon/tests/acceptance/dsl/node/PantheonNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bedb770d02..0647e40b62 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 @@ -20,8 +20,8 @@ import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.controller.KeyPairUtil; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; -import tech.pegasys.pantheon.ethereum.core.MiningParameters; import tech.pegasys.pantheon.ethereum.core.Address; +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; From d19fa8a6aabf70407968fbc6a06fb3898a887dae Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 25 Oct 2018 13:57:37 +1000 Subject: [PATCH 10/41] [NC-1524] Clique miner acceptance test - PR improvements --- .../CreateAccountAcceptanceTest.java | 2 +- .../PantheonClusterAcceptanceTest.java | 2 +- .../RpcApisTogglesAcceptanceTest.java | 2 +- .../CliqueDiscardRpcAcceptanceTest.java | 26 ++++----- .../clique/CliqueGetSignersRpcTest.java | 20 +++---- .../clique/CliqueMiningAcceptanceTest.java | 4 +- .../CliqueProposalRpcAcceptanceTest.java | 22 ++++---- .../CliqueProposeRpcAcceptanceTest.java | 46 ++++++++-------- .../acceptance/dsl/AcceptanceTestBase.java | 3 + .../dsl/clique/CliqueConditions.java | 55 ++++++++++++++++--- .../dsl/condition/ExpectProposals.java | 21 ++----- .../dsl/condition/ExpectValidators.java | 11 ++-- .../condition/ExpectValidatorsAtBlock.java | 11 ++-- .../ExpectValidatorsAtBlockHash.java | 12 ++-- .../tests/acceptance/dsl/node/Clique.java | 38 ++++++++----- .../tests/acceptance/dsl/node/Cluster.java | 28 +++++----- .../acceptance/dsl/node/PantheonNode.java | 11 +--- .../dsl/node/PantheonNodeConfig.java | 7 +-- .../dsl/node/ProcessPantheonNodeRunner.java | 4 +- .../dsl/node/ThreadPantheonNodeRunner.java | 2 +- .../jsonrpc/EthGetWorkAcceptanceTest.java | 2 +- .../jsonrpc/Web3Sha3AcceptanceTest.java | 2 +- .../mining/MiningAcceptanceTest.java | 2 +- .../NewPendingTransactionAcceptanceTest.java | 2 +- .../src/test/resources/clique/clique.json | 6 +- .../consensus/clique/CliqueExtraData.java | 15 +---- .../consensus/clique/CliqueExtraDataTest.java | 22 +++----- .../pantheon/cli/EthNetworkConfig.java | 6 -- .../pegasys/pantheon/cli/PantheonCommand.java | 2 +- .../pantheon/cli/PantheonCommandTest.java | 20 +++---- .../src/test/resources/complete_config.toml | 2 +- 31 files changed, 198 insertions(+), 210 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/CreateAccountAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/CreateAccountAcceptanceTest.java index 0b109dec2c..a398c2d5ca 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/CreateAccountAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/CreateAccountAcceptanceTest.java @@ -34,7 +34,7 @@ public class CreateAccountAcceptanceTest extends AcceptanceTestBase { public void setUp() throws Exception { minerNode = cluster.create(pantheonMinerNode("node1")); fullNode = cluster.create(pantheonNode("node2")); - cluster.start(minerNode, fullNode); + cluster.start(); } @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/PantheonClusterAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/PantheonClusterAcceptanceTest.java index a07ba5f671..6b14742a7e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/PantheonClusterAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/PantheonClusterAcceptanceTest.java @@ -30,7 +30,7 @@ public class PantheonClusterAcceptanceTest extends AcceptanceTestBase { public void setUp() throws Exception { minerNode = cluster.create(pantheonMinerNode("node1")); fullNode = cluster.create(pantheonNode("node2")); - cluster.start(minerNode, fullNode); + cluster.start(); } @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/RpcApisTogglesAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/RpcApisTogglesAcceptanceTest.java index 80b07cd8d5..2fe2569cb7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/RpcApisTogglesAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/RpcApisTogglesAcceptanceTest.java @@ -40,7 +40,7 @@ public void before() throws Exception { rpcEnabledNode = cluster.create(pantheonNode("rpc-enabled")); rpcDisabledNode = cluster.create(pantheonRpcDisabledNode("rpc-disabled")); ethApiDisabledNode = cluster.create(patheonNodeWithRpcApis("eth-api-disabled", RpcApis.NET)); - cluster.start(rpcEnabledNode, rpcDisabledNode, ethApiDisabledNode); + cluster.start(); } @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index 3b5010370b..1208d468bb 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -15,44 +15,42 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; import java.math.BigInteger; -import com.google.common.collect.ImmutableMap; import org.junit.Test; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.methods.response.EthBlock.Block; public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBase { - private final CliqueConditions clique = new CliqueConditions(); @Test public void shouldDiscardVotes() throws IOException { - String[] initialValidators = {"miner1", "miner2"}; + final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); - minerNode1.clique().propose(minerNode2.getAddress(), false); - minerNode1.clique().propose(minerNode3.getAddress(), true); - minerNode2.clique().propose(minerNode2.getAddress(), false); - minerNode2.clique().propose(minerNode3.getAddress(), true); - minerNode1.clique().discard(minerNode2.getAddress()); - minerNode1.clique().discard(minerNode3.getAddress()); + minerNode1.clique().proposeRemove(minerNode2); + minerNode1.clique().proposeAdd(minerNode3); + minerNode2.clique().proposeRemove(minerNode2); + minerNode2.clique().proposeAdd(minerNode3); + minerNode1.clique().discard(minerNode2); + minerNode1.clique().discard(minerNode3); final DefaultBlockParameter latest = DefaultBlockParameter.valueOf("latest"); final Block latestBlock = minerNode1.web3().ethGetBlockByNumber(latest, false); final BigInteger futureBlockNumber = latestBlock.getNumber().add(BigInteger.valueOf(2)); cluster.verify( - clique.validatorsAtBlockEquals(futureBlockNumber.toString(), minerNode1, minerNode2)); - minerNode1.verify(clique.proposalsEqual(ImmutableMap.of())); - minerNode2.verify(clique.proposalsEqual(ImmutableMap.of(minerNode2, false, minerNode3, true))); + clique.validatorsAtBlockEqual(futureBlockNumber.toString(), minerNode1, minerNode2)); + minerNode1.verify(clique.noProposals()); + minerNode2.verify( + clique.proposalsEqual().removeProposal(minerNode2).addProposal(minerNode3).build()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index ec4c8ccc7c..73f7e59eb9 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -15,7 +15,6 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; @@ -25,35 +24,32 @@ import org.web3j.protocol.core.methods.response.EthBlock.Block; public class CliqueGetSignersRpcTest extends AcceptanceTestBase { - private final CliqueConditions cliqueConditions = new CliqueConditions(); @Test public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - cluster.start(minerNode1, minerNode2, minerNode3); + final PantheonNode[] allNodes = {minerNode1, minerNode2, minerNode3}; + cluster.start(); final Block latest = minerNode1.web3().ethGetBlockByNumber(DefaultBlockParameter.valueOf("latest"), false); - cluster.verify( - cliqueConditions.validatorsAtBlockEquals("0x0", minerNode1, minerNode2, minerNode3)); - cluster.verify( - cliqueConditions.validatorsAtBlockEquals("latest", minerNode1, minerNode2, minerNode3)); - cluster.verify( - cliqueConditions.validatorsAtBlockEquals( - latest.getNumber().toString(), minerNode1, minerNode2, minerNode3)); + cluster.verify(clique.validatorsAtBlockEqual("0x0", allNodes)); + cluster.verify(clique.validatorsAtBlockEqual("latest", allNodes)); + cluster.verify(clique.validatorsAtBlockEqual(latest.getNumber().toString(), allNodes)); } @Test public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - cluster.start(minerNode1, minerNode2); + final PantheonNode[] allNodes = {minerNode1, minerNode2}; + cluster.start(); final DefaultBlockParameter latest = DefaultBlockParameter.valueOf("latest"); final Block latestBlock = minerNode1.web3().ethGetBlockByNumber(latest, false); final String hash = latestBlock.getHash(); - cluster.verify(cliqueConditions.validatorsAtBlockHashEquals(hash, minerNode1, minerNode2)); + cluster.verify(clique.validatorsAtBlockHashEqual(hash, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 004fa38b6a..7037e3393e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -27,7 +27,7 @@ public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { @Test public void shouldMineTransactionsOnSingleNode() throws IOException { final PantheonNode minerNode = cluster.create(pantheonCliqueMinerNode("miner1")); - cluster.start(minerNode); + cluster.start(); final Account sender = accounts.createAccount("account1"); final Account receiver = accounts.createAccount("account2"); @@ -47,7 +47,7 @@ public void shouldMineTransactionsOnMultipleNodes() throws IOException { final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); final Account sender = accounts.createAccount("account1"); final Account receiver = accounts.createAccount("account2"); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index d3771dd087..6c552c8797 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -15,34 +15,32 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; -import com.google.common.collect.ImmutableMap; import org.junit.Test; public class CliqueProposalRpcAcceptanceTest extends AcceptanceTestBase { - private final CliqueConditions clique = new CliqueConditions(); @Test public void shouldReturnProposals() throws IOException { - String[] initialValidators = {"miner1", "miner2"}; + final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); - cluster.verify(clique.proposalsEqual(ImmutableMap.of())); - minerNode1.clique().propose(minerNode3.getAddress(), true); - minerNode1.clique().propose(minerNode2.getAddress(), false); - minerNode2.clique().propose(minerNode3.getAddress(), false); - minerNode1.verify(clique.proposalsEqual(ImmutableMap.of(minerNode3, true, minerNode2, false))); - minerNode2.verify(clique.proposalsEqual(ImmutableMap.of(minerNode3, false))); - minerNode3.verify(clique.proposalsEqual(ImmutableMap.of())); + cluster.verify(clique.noProposals()); + minerNode1.clique().proposeAdd(minerNode3); + minerNode1.clique().proposeRemove(minerNode2); + minerNode2.clique().proposeRemove(minerNode3); + minerNode1.verify( + clique.proposalsEqual().addProposal(minerNode3).removeProposal(minerNode2).build()); + minerNode2.verify(clique.proposalsEqual().removeProposal(minerNode3).build()); + minerNode3.verify(clique.noProposals()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 2d07f9476d..fe7184694d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -15,7 +15,6 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; @@ -23,71 +22,70 @@ import org.junit.Test; public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { - private final CliqueConditions cliqueConditions = new CliqueConditions(); @Test public void shouldAddValidators() throws IOException { - String[] initialValidators = {"miner1", "miner2"}; + final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); - minerNode1.clique().propose(minerNode3.getAddress(), true); - minerNode2.clique().propose(minerNode3.getAddress(), true); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + minerNode1.clique().proposeAdd(minerNode3); + minerNode2.clique().proposeAdd(minerNode3); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @Test public void shouldRemoveValidators() throws IOException { - String[] initialValidators = {"miner1", "miner2", "miner3"}; + final String[] initialValidators = {"miner1", "miner2", "miner3"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); - minerNode1.clique().propose(minerNode3.getAddress(), false); - minerNode2.clique().propose(minerNode3.getAddress(), false); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().proposeRemove(minerNode3); + minerNode2.clique().proposeRemove(minerNode3); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @Test public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { - String[] initialValidators = {"miner1", "miner2"}; + final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); - minerNode1.clique().propose(minerNode3.getAddress(), true); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + minerNode1.clique().proposeAdd(minerNode3); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @Test public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { - String[] initialValidators = {"miner1", "miner2", "miner3"}; + final String[] initialValidators = {"miner1", "miner2", "miner3"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(minerNode1, minerNode2, minerNode3); + cluster.start(); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); - minerNode1.clique().propose(minerNode3.getAddress(), false); - cluster.verify(cliqueConditions.validatorsEquals(minerNode1, minerNode2, minerNode3)); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().proposeRemove(minerNode3); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } } 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 8ebbb1aa70..70606bd2e6 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 @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.tests.acceptance.dsl; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Cluster; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; @@ -24,12 +25,14 @@ public class AcceptanceTestBase { protected final Cluster cluster; protected final Transactions transactions; protected final JsonRpc jsonRpc; + protected final CliqueConditions clique; protected AcceptanceTestBase() { accounts = new Accounts(); cluster = new Cluster(); transactions = new Transactions(accounts); jsonRpc = new JsonRpc(cluster); + clique = new CliqueConditions(); } @After diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java index f759e7060b..43cf4c455b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.clique; +import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectProposals; @@ -20,25 +21,63 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlockHash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import java.util.Arrays; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import com.google.common.collect.ImmutableMap; public class CliqueConditions { - public Condition validatorsEquals(final PantheonNode... validators) { - return new ExpectValidators(validators); + public Condition validatorsEqual(final PantheonNode... validators) { + return new ExpectValidators(validatorAddresses(validators)); } - public Condition validatorsAtBlockEquals( + public Condition validatorsAtBlockEqual( final String blockNumber, final PantheonNode... validators) { - return new ExpectValidatorsAtBlock(blockNumber, validators); + return new ExpectValidatorsAtBlock(blockNumber, validatorAddresses(validators)); } - public Condition validatorsAtBlockHashEquals( + public Condition validatorsAtBlockHashEqual( final String blockHash, final PantheonNode... validators) { - return new ExpectValidatorsAtBlockHash(Hash.fromHexString(blockHash), validators); + return new ExpectValidatorsAtBlockHash( + Hash.fromHexString(blockHash), validatorAddresses(validators)); + } + + public ProposalsConfig proposalsEqual() { + return new ProposalsConfig(); + } + + public Condition noProposals() { + return new ExpectProposals(ImmutableMap.of()); } - public Condition proposalsEqual(final Map proposals) { - return new ExpectProposals(proposals); + private Address[] validatorAddresses(final PantheonNode[] validators) { + return Arrays.stream(validators).map(PantheonNode::getAddress).sorted().toArray(Address[]::new); + } + + public static class ProposalsConfig { + private final Map proposals = new HashMap<>(); + + public ProposalsConfig addProposal(final PantheonNode node) { + proposals.put(node, true); + return this; + } + + public ProposalsConfig removeProposal(final PantheonNode node) { + proposals.put(node, false); + return this; + } + + public Condition build() { + final Map proposalsAsAddress = + this.proposals + .entrySet() + .stream() + .collect(Collectors.toMap(p -> p.getKey().getAddress(), Entry::getValue)); + return new ExpectProposals(proposalsAsAddress); + } } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java index a546118c51..204e3ec35e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java @@ -17,35 +17,22 @@ import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; public class ExpectProposals implements Condition { - private Map proposers; + private final Map proposers; - public ExpectProposals(final Map proposers) { + public ExpectProposals(final Map proposers) { this.proposers = proposers; } @Override public void verify(final Node node) { - Map expectedProposers = - proposers - .entrySet() - .stream() - .collect(Collectors.toMap(p -> p.getKey().getAddress().toString(), Entry::getValue)); waitFor( () -> { - Map result = node.clique().proposals().getResult(); - Map proposers = - result - .entrySet() - .stream() - .collect(Collectors.toMap(p -> p.getKey().toString(), Entry::getValue)); - assertThat(proposers).isEqualTo(expectedProposers); + final Map result = node.clique().proposals().getResult(); + assertThat(result).isEqualTo(proposers); }); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java index b983ceb578..eb0eaa37d7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java @@ -12,21 +12,19 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; -import java.util.Arrays; import java.util.Optional; public class ExpectValidators implements Condition { - private final PantheonNode[] validators; + private final Address[] validators; - public ExpectValidators(final PantheonNode... validators) { + public ExpectValidators(final Address... validators) { this.validators = validators; } @@ -35,7 +33,6 @@ public void verify(final Node node) { waitFor( () -> assertThat(node.clique().getSigners(Optional.empty()).getResult()) - .containsExactlyInAnyOrderElementsOf( - Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); + .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java index 7d1653fbce..dd08309183 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java @@ -12,21 +12,19 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; -import java.util.Arrays; import java.util.Optional; public class ExpectValidatorsAtBlock implements Condition { private final String blockParameter; - private PantheonNode[] validators; + private final Address[] validators; - public ExpectValidatorsAtBlock(final String blockNumber, final PantheonNode... validators) { + public ExpectValidatorsAtBlock(final String blockNumber, final Address... validators) { this.blockParameter = blockNumber; this.validators = validators; } @@ -36,7 +34,6 @@ public void verify(final Node node) { waitFor( () -> assertThat(node.clique().getSigners(Optional.of(blockParameter)).getResult()) - .containsExactlyInAnyOrderElementsOf( - Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); + .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java index 2366bcf2c9..169c29c082 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java @@ -12,21 +12,18 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; - -import java.util.Arrays; public class ExpectValidatorsAtBlockHash implements Condition { private final Hash blockHash; - private final PantheonNode[] validators; + private final Address[] validators; - public ExpectValidatorsAtBlockHash(final Hash blockHash, final PantheonNode... validators) { + public ExpectValidatorsAtBlockHash(final Hash blockHash, final Address... validators) { this.blockHash = blockHash; this.validators = validators; } @@ -36,7 +33,6 @@ public void verify(final Node node) { waitFor( () -> assertThat(node.clique().getSignersAtHash(blockHash).getResult()) - .containsExactlyInAnyOrderElementsOf( - Arrays.stream(validators).map(PantheonNode::getAddress).collect(toList()))); + .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java index 942a11a6de..81be017b6e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java @@ -36,42 +36,42 @@ public Clique(final Web3jService web3j) { this.web3jService = web3j; } - public static class ProposeResponse extends Response {} - - public static class DiscardResponse extends Response {} - - public static class SignersBlockResponse extends Response> {} + public ProposeResponse proposeAdd(final PantheonNode node) throws IOException { + return propose(node, true); + } - public static class ProposalsResponse extends Response> {} + public ProposeResponse proposeRemove(final PantheonNode node) throws IOException { + return propose(node, false); + } - public ProposeResponse propose(final Address address, final Boolean auth) throws IOException { - Request request = + private ProposeResponse propose(final PantheonNode node, final Boolean auth) throws IOException { + final Request request = new Request<>( "clique_propose", - Arrays.asList(address.toString(), auth.toString()), + Arrays.asList(node.getAddress().toString(), auth.toString()), web3jService, ProposeResponse.class); return request.send(); } - public DiscardResponse discard(final Address address) throws IOException { - Request request = + public DiscardResponse discard(final PantheonNode node) throws IOException { + final Request request = new Request<>( "clique_discard", - singletonList(address.toString()), + singletonList(node.getAddress().toString()), web3jService, DiscardResponse.class); return request.send(); } public ProposalsResponse proposals() throws IOException { - Request request = + final Request request = new Request<>("clique_proposals", emptyList(), web3jService, ProposalsResponse.class); return request.send(); } public SignersBlockResponse getSigners(final Optional blockNumber) throws IOException { - Request request = + final Request request = new Request<>( "clique_getSigners", singletonList(blockNumber.map(Object::toString).orElse("latest")), @@ -81,7 +81,7 @@ public SignersBlockResponse getSigners(final Optional blockNumber) throw } public SignersBlockResponse getSignersAtHash(final Hash hash) throws IOException { - Request request = + final Request request = new Request<>( "clique_getSignersAtHash", singletonList(hash.toString()), @@ -89,4 +89,12 @@ public SignersBlockResponse getSignersAtHash(final Hash hash) throws IOException SignersBlockResponse.class); return request.send(); } + + public static class ProposeResponse extends Response {} + + public static class DiscardResponse extends Response {} + + public static class SignersBlockResponse extends Response> {} + + public static class ProposalsResponse extends Response> {} } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index 826483a1fb..ab8bc76151 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -12,8 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import tech.pegasys.pantheon.cli.EthNetworkConfig; @@ -22,24 +20,25 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Optional; public class Cluster implements AutoCloseable { public static final int NETWORK_ID = 10; - private final Map nodes = new HashMap<>(); + private final List nodes = new ArrayList<>(); private final PantheonNodeRunner pantheonNodeRunner = PantheonNodeRunner.instance(); - public void start(final PantheonNode... nodes) { - this.nodes.clear(); + public void start(final PantheonNode... startNodes) { + if (startNodes.length != 0) { + this.nodes.clear(); + this.nodes.addAll(Arrays.asList(startNodes)); + } final List bootNodes = new ArrayList<>(); for (final PantheonNode node : nodes) { - this.nodes.put(node.getName(), node); bootNodes.add(node.enodeUrl()); } @@ -47,19 +46,19 @@ public void start(final PantheonNode... nodes) { node.bootnodes(bootNodes); Optional ethNetworkConfig = node.getGenesisConfig() - .apply(stream(nodes).collect(toList())) + .apply(nodes) .map(config -> new EthNetworkConfig(config, NETWORK_ID, bootNodes)); - node.ethNetworkConfig(ethNetworkConfig); + node.setEthNetworkConfig(ethNetworkConfig); node.start(pantheonNodeRunner); } for (final PantheonNode node : nodes) { - awaitPeerDiscovery(node, nodes.length); + awaitPeerDiscovery(node, nodes.size()); } } public void stop() { - for (final PantheonNode node : nodes.values()) { + for (final PantheonNode node : this.nodes) { node.stop(); } pantheonNodeRunner.shutdown(); @@ -67,7 +66,7 @@ public void stop() { @Override public void close() { - for (final PantheonNode node : nodes.values()) { + for (final PantheonNode node : nodes) { node.close(); } pantheonNodeRunner.shutdown(); @@ -85,6 +84,7 @@ public PantheonNode create(final PantheonNodeConfig config) throws IOException { config.isDevMode(), config.getGenesisConfig()); config.closeSocket(); + nodes.add(node); return node; } @@ -95,7 +95,7 @@ private void awaitPeerDiscovery(final PantheonNode node, final int nodeCount) { } public void verify(final Condition expected) { - for (final Node node : nodes.values()) { + for (final Node node : nodes) { expected.verify(node); } } 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 0647e40b62..02c972f84f 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 @@ -90,9 +90,8 @@ public PantheonNode( final boolean devMode, final Function, Optional> genesisConfig) throws IOException { - final Path homeDirectory = Files.createTempDirectory("acctest"); this.name = name; - this.homeDirectory = homeDirectory; + this.homeDirectory = Files.createTempDirectory("acctest"); this.keyPair = KeyPairUtil.loadKeyPair(homeDirectory); this.p2pPort = p2pPort; this.miningParameters = miningParameters; @@ -113,10 +112,6 @@ String enodeUrl() { return "enode://" + keyPair.getPublicKey().toString() + "@" + LOCALHOST + ":" + p2pPort; } - KeyPair keyPair() { - return keyPair; - } - private Optional jsonRpcBaseUrl() { if (jsonRpcEnabled) { return Optional.of( @@ -375,11 +370,11 @@ public Function, Optional> getGenesisConfig() { return genesisConfig; } - public void ethNetworkConfig(final Optional ethNetworkConfig) { + public void setEthNetworkConfig(final Optional ethNetworkConfig) { this.ethNetworkConfig = ethNetworkConfig; } - public Optional ethNetworkConfig() { + public Optional getEthNetworkConfig() { return ethNetworkConfig; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index 246b722df5..6558b2ff8a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -17,7 +17,7 @@ import static tech.pegasys.pantheon.consensus.clique.jsonrpc.CliqueRpcApis.CLIQUE; import tech.pegasys.pantheon.consensus.clique.CliqueExtraData; -import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; +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; @@ -172,9 +172,8 @@ private static String cliqueGenesisTemplateConfig() { } private static String encodeCliqueExtraData(final Collection nodes) { - final List privateKeys = - nodes.stream().map(node -> node.keyPair().getPrivateKey()).collect(toList()); - return CliqueExtraData.createGenesisExtraDataString(privateKeys); + final List
addresses = nodes.stream().map(PantheonNode::getAddress).collect(toList()); + return CliqueExtraData.createGenesisExtraDataString(addresses); } private static JsonRpcConfiguration jsonRpcConfigWithClique() { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index 4ce358f584..37ca9f4b32 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -85,8 +85,8 @@ public void startNode(final PantheonNode node) { params.add(apiList(node.webSocketConfiguration().getRpcApis())); } - if (node.ethNetworkConfig().isPresent()) { - EthNetworkConfig ethNetworkConfig = node.ethNetworkConfig().get(); + if (node.getEthNetworkConfig().isPresent()) { + EthNetworkConfig ethNetworkConfig = node.getEthNetworkConfig().get(); Path genesisFile = createGenesisFile(node, ethNetworkConfig); params.add("--genesis"); params.add(genesisFile.toString()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index 53af82f4ad..b1732af412 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -49,7 +49,7 @@ public void startNode(final PantheonNode node) { final PantheonControllerBuilder builder = new PantheonControllerBuilder(); final EthNetworkConfig ethNetworkConfig = - node.ethNetworkConfig() + node.getEthNetworkConfig() .orElse(new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build()); PantheonController pantheonController; try { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/EthGetWorkAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/EthGetWorkAcceptanceTest.java index 58db8fabd1..a9ee86519f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/EthGetWorkAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/EthGetWorkAcceptanceTest.java @@ -33,7 +33,7 @@ public class EthGetWorkAcceptanceTest extends AcceptanceTestBase { public void setUp() throws Exception { minerNode = cluster.create(pantheonMinerNode("node1")); fullNode = cluster.create(pantheonNode("node2")); - cluster.start(minerNode, fullNode); + cluster.start(); } @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/Web3Sha3AcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/Web3Sha3AcceptanceTest.java index 459c8c78e7..5f4bf01ee4 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/Web3Sha3AcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/jsonrpc/Web3Sha3AcceptanceTest.java @@ -30,7 +30,7 @@ public class Web3Sha3AcceptanceTest extends AcceptanceTestBase { @Before public void setUp() throws Exception { node = cluster.create(pantheonNode("node1")); - cluster.start(node); + cluster.start(); } @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/mining/MiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/mining/MiningAcceptanceTest.java index 53a229ca67..33d0a16318 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/mining/MiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/mining/MiningAcceptanceTest.java @@ -30,7 +30,7 @@ public class MiningAcceptanceTest extends AcceptanceTestBase { @Before public void setUp() throws Exception { minerNode = cluster.create(pantheonMinerNode("miner1")); - cluster.start(minerNode); + cluster.start(); } @Test diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/pubsub/NewPendingTransactionAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/pubsub/NewPendingTransactionAcceptanceTest.java index d676d8f0f1..a6541cd33b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/pubsub/NewPendingTransactionAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/pubsub/NewPendingTransactionAcceptanceTest.java @@ -46,7 +46,7 @@ public void setUp() throws Exception { vertx = Vertx.vertx(); minerNode = cluster.create(pantheonMinerNode("miner-node1")); archiveNode = cluster.create(pantheonNode("full-node1")); - cluster.start(minerNode, archiveNode); + cluster.start(); accountOne = accounts.createAccount("account-one"); minerWebSocket = new WebSocket(vertx, minerNode); archiveWebSocket = new WebSocket(vertx, archiveNode); diff --git a/acceptance-tests/src/test/resources/clique/clique.json b/acceptance-tests/src/test/resources/clique/clique.json index cde67aa457..108363cf38 100644 --- a/acceptance-tests/src/test/resources/clique/clique.json +++ b/acceptance-tests/src/test/resources/clique/clique.json @@ -4,9 +4,9 @@ "homesteadBlock": 1, "eip150Block": 2, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 3, - "eip158Block": 3, - "byzantiumBlock": 1035301, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, "clique": { "period": 5, "epoch": 30000 diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java index 544c38fd13..efd3489243 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraData.java @@ -15,11 +15,8 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; -import tech.pegasys.pantheon.crypto.SECP256K1.PublicKey; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.BytesValues; @@ -110,20 +107,10 @@ public List
getValidators() { return validators; } - public static String createGenesisExtraDataString(final List privKeys) { - final List
validators = convertPrivKeysToAddresses(privKeys); + public static String createGenesisExtraDataString(final List
validators) { final CliqueExtraData cliqueExtraData = new CliqueExtraData(BytesValue.wrap(new byte[32]), null, validators); final BytesValue output = cliqueExtraData.encode(); return output.toString(); } - - private static List
convertPrivKeysToAddresses(final List privKeys) { - final List
validators = Lists.newArrayList(); - for (final PrivateKey privKey : privKeys) { - final PublicKey pubKey = PublicKey.create(privKey); - validators.add(Util.publicKeyToAddress(pubKey)); - } - return validators; - } } diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraDataTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraDataTest.java index 2f4c13f135..388aded68b 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraDataTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueExtraDataTest.java @@ -16,7 +16,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; -import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey; import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.AddressHelpers; @@ -95,26 +94,23 @@ public void sufficientlyLargeButIllegallySizedInputThrowsException() { } @Test - public void privKeysToExtraDataString() { + public void addressToExtraDataString() { final List nodeKeys = Lists.newArrayList(); for (int i = 0; i < 4; i++) { nodeKeys.add(KeyPair.generate()); } - final List privKeys = - nodeKeys.stream().map(k -> k.getPrivateKey()).collect(Collectors.toList()); - - final String hexOutput = CliqueExtraData.createGenesisExtraDataString(privKeys); - - final CliqueExtraData extraData = CliqueExtraData.decode(BytesValue.fromHexString(hexOutput)); - - final List
expectedAddresses = + final List
addresses = nodeKeys .stream() - .map(k -> Util.publicKeyToAddress(k.getPublicKey())) + .map(KeyPair::getPublicKey) + .map(Util::publicKeyToAddress) .collect(Collectors.toList()); - assertThat(extraData.getValidators()) - .containsExactly(expectedAddresses.toArray(new Address[expectedAddresses.size()])); + final String hexOutput = CliqueExtraData.createGenesisExtraDataString(addresses); + + final CliqueExtraData extraData = CliqueExtraData.decode(BytesValue.fromHexString(hexOutput)); + + assertThat(extraData.getValidators()).containsExactly(addresses.toArray(new Address[0])); } } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java index a37571461c..14a360a525 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/EthNetworkConfig.java @@ -105,10 +105,6 @@ private static String jsonConfig(final String resourceName) { } } - public static EthNetworkConfig defaultConfig() { - return mainnet(); - } - public static class Builder { private String genesisConfig; @@ -121,8 +117,6 @@ public Builder(final EthNetworkConfig ethNetworkConfig) { this.bootNodes = ethNetworkConfig.bootNodes; } - public Builder() {} - public Builder setGenesisConfig(final String genesisConfig) { this.genesisConfig = genesisConfig; return this; diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index da878c5487..67e97f741e 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -566,7 +566,7 @@ private Path getDefaultPantheonDataDir() { private EthNetworkConfig ethNetworkConfig() { final EthNetworkConfig predefinedNetworkConfig = - rinkeby ? EthNetworkConfig.rinkeby() : EthNetworkConfig.defaultConfig(); + rinkeby ? EthNetworkConfig.rinkeby() : EthNetworkConfig.mainnet(); return updateNetworkConfig(predefinedNetworkConfig); } diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java index 08c245465c..8fdfa747c6 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java @@ -62,10 +62,10 @@ @Ignore("temporarily ignored because tests hang if working dir path too long") public class PantheonCommandTest extends CommandTestAbstract { - @Rule public final TemporaryFolder temp = new TemporaryFolder(); private static final JsonRpcConfiguration defaultJsonRpcConfiguration; private static final WebSocketConfiguration defaultWebSocketConfiguration; + private static final String GENESIS_CONFIG_TESTDATA = "genesis_config"; static { final JsonRpcConfiguration rpcConf = JsonRpcConfiguration.createDefault(); @@ -150,7 +150,7 @@ public void callingPantheonCommandWithoutOptionsMustSyncWithDefaultValues() thro // Testing each option @Test - public void CallingWithConfigOptionButNoConfigFileShouldDisplayHelp() { + public void callingWithConfigOptionButNoConfigFileShouldDisplayHelp() { parseCommand("--config"); @@ -160,7 +160,7 @@ public void CallingWithConfigOptionButNoConfigFileShouldDisplayHelp() { } @Test - public void CallingWithConfigOptionButNonExistingFileShouldDisplayHelp() throws IOException { + public void callingWithConfigOptionButNonExistingFileShouldDisplayHelp() throws IOException { final File tempConfigFile = temp.newFile("an-invalid-file-name-without-extension"); parseCommand("--config", tempConfigFile.getPath()); @@ -170,7 +170,7 @@ public void CallingWithConfigOptionButNonExistingFileShouldDisplayHelp() throws } @Test - public void CallingWithConfigOptionButTomlFileNotFoundShouldDisplayHelp() { + public void callingWithConfigOptionButTomlFileNotFoundShouldDisplayHelp() { parseCommand("--config", "./an-invalid-file-name-sdsd87sjhqoi34io23.toml"); @@ -180,7 +180,7 @@ public void CallingWithConfigOptionButTomlFileNotFoundShouldDisplayHelp() { } @Test - public void CallingWithConfigOptionButInvalidContentTomlFileShouldDisplayHelp() throws Exception { + public void callingWithConfigOptionButInvalidContentTomlFileShouldDisplayHelp() throws Exception { // We write a config file to prevent an invalid file in resource folder to raise errors in // code checks (CI + IDE) @@ -201,7 +201,7 @@ public void CallingWithConfigOptionButInvalidContentTomlFileShouldDisplayHelp() } @Test - public void CallingWithConfigOptionButInvalidValueTomlFileShouldDisplayHelp() throws Exception { + public void callingWithConfigOptionButInvalidValueTomlFileShouldDisplayHelp() throws Exception { // We write a config file to prevent an invalid file in resource folder to raise errors in // code checks (CI + IDE) @@ -222,11 +222,11 @@ public void CallingWithConfigOptionButInvalidValueTomlFileShouldDisplayHelp() th } @Test - public void OverrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException { + public void overrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException { final URL configFile = Resources.getResource("complete_config.toml"); final Path genesisFile = createFakeGenesisFile(); final String updatedConfig = - Resources.toString(configFile, UTF_8).replaceAll("~/genesys.json", genesisFile.toString()); + Resources.toString(configFile, UTF_8).replaceAll("~/genesis.json", genesisFile.toString()); final Path toml = Files.createTempFile("toml", ""); Files.write(toml, updatedConfig.getBytes(UTF_8)); @@ -268,7 +268,7 @@ public void OverrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException final EthNetworkConfig networkConfig = new Builder(EthNetworkConfig.mainnet()) - .setGenesisConfig("genesis_config") + .setGenesisConfig(GENESIS_CONFIG_TESTDATA) .setBootNodes(nodes) .build(); verify(mockControllerBuilder) @@ -290,7 +290,7 @@ public void OverrideDefaultValuesIfKeyIsPresentInConfigFile() throws IOException } @Test - public void NoOverrideDefaultValuesIfKeyIsNotPresentInConfigFile() throws IOException { + public void noOverrideDefaultValuesIfKeyIsNotPresentInConfigFile() throws IOException { final String configFile = Resources.getResource("partial_config.toml").getFile(); parseCommand("--config", configFile); diff --git a/pantheon/src/test/resources/complete_config.toml b/pantheon/src/test/resources/complete_config.toml index 1824f6099f..15b1cb99cc 100644 --- a/pantheon/src/test/resources/complete_config.toml +++ b/pantheon/src/test/resources/complete_config.toml @@ -13,7 +13,7 @@ rpc-listen="5.6.7.8:5678" # IP:port ws-listen="9.10.11.12:9101" # IP:port # chain -genesis="~/genesys.json" # Path +genesis="~/genesis.json" # Path sync-mode="fast"# should be FAST or FULL (or fast or full) ottoman=false # true means using ottoman testnet if genesys file uses iBFT From 7807a18f93441be416e8a3610e69968caee24101 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 26 Oct 2018 14:24:39 +1000 Subject: [PATCH 11/41] [NC-1524] clean up PantheonNodeConfig constructors --- .../dsl/node/PantheonNodeConfig.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java index 6558b2ff8a..e0c189b4b4 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeConfig.java @@ -66,21 +66,23 @@ private PantheonNodeConfig( final MiningParameters miningParameters, final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration) { - this.name = name; - this.miningParameters = miningParameters; - this.jsonRpcConfiguration = jsonRpcConfiguration; - this.webSocketConfiguration = webSocketConfiguration; - this.genesisConfig = (ignore) -> Optional.empty(); - this.devMode = true; + this( + name, + miningParameters, + jsonRpcConfiguration, + webSocketConfiguration, + (ignore) -> Optional.empty(), + true); } private PantheonNodeConfig(final String name, final MiningParameters miningParameters) { - this.name = name; - this.miningParameters = miningParameters; - this.jsonRpcConfiguration = createJsonRpcConfig(); - this.webSocketConfiguration = createWebSocketConfig(); - this.genesisConfig = (ignore) -> Optional.empty(); - this.devMode = true; + this( + name, + miningParameters, + createJsonRpcConfig(), + createWebSocketConfig(), + (ignore) -> Optional.empty(), + true); } private static MiningParameters createMiningParameters(final boolean miner) { From 03f9eae75fb9097e126c5313417f3d2f1619388d Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 26 Oct 2018 16:22:24 +1000 Subject: [PATCH 12/41] [NC-1524] refactor to add a waitForChainHeadToProgress method --- .../CliqueDiscardRpcAcceptanceTest.java | 11 ++++------ .../dsl/condition/ExpectBlockNumber.java | 22 +++++++++++++++++++ .../tests/acceptance/dsl/node/Node.java | 2 ++ .../acceptance/dsl/node/PantheonNode.java | 9 ++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index 1208d468bb..88635101fc 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -44,13 +44,10 @@ public void shouldDiscardVotes() throws IOException { minerNode1.clique().discard(minerNode2); minerNode1.clique().discard(minerNode3); - final DefaultBlockParameter latest = DefaultBlockParameter.valueOf("latest"); - final Block latestBlock = minerNode1.web3().ethGetBlockByNumber(latest, false); - final BigInteger futureBlockNumber = latestBlock.getNumber().add(BigInteger.valueOf(2)); - cluster.verify( - clique.validatorsAtBlockEqual(futureBlockNumber.toString(), minerNode1, minerNode2)); + minerNode1.waitForChainHeadToProgress(2); + + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.verify(clique.noProposals()); - minerNode2.verify( - clique.proposalsEqual().removeProposal(minerNode2).addProposal(minerNode3).build()); + minerNode2.verify(clique.proposalsEqual().removeProposal(minerNode2).addProposal(minerNode3).build()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java new file mode 100644 index 0000000000..d8a2b4e248 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java @@ -0,0 +1,22 @@ +package tech.pegasys.pantheon.tests.acceptance.dsl.condition; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +import java.math.BigInteger; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; + +public class ExpectBlockNumber implements Condition { + private BigInteger blockNumber; + + public ExpectBlockNumber(final BigInteger blockNumber) { + this.blockNumber = blockNumber; + } + + @Override + public void verify(final Node node) { + waitFor( + () -> assertThat(node.eth().blockNumber()).isEqualTo(blockNumber) + ); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java index 354ec593ad..2434f54240 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java @@ -24,4 +24,6 @@ public interface Node { BigInteger getAccountBalance(Account account); Clique clique(); + + Eth eth(); } 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 02c972f84f..d958654cb2 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 @@ -16,7 +16,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import org.assertj.core.api.Assertions; +import org.assertj.core.api.Java6Assertions; import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.controller.KeyPairUtil; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; @@ -27,6 +30,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.File; @@ -386,4 +390,9 @@ public T execute(final Transaction transaction) { public void verify(final Condition expected) { expected.verify(this); } + + public void waitForChainHeadToProgress(final int blocksAheadOfLatest) throws IOException { + final BigInteger futureBlock = eth().blockNumber().add(BigInteger.valueOf(blocksAheadOfLatest)); + new ExpectBlockNumber(futureBlock).verify(this); + } } From de5a1e8bd1d9721184ecf3c84c974b5a91a1c668 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 26 Oct 2018 16:50:49 +1000 Subject: [PATCH 13/41] [NC-1524] change validator state and wait until blocks progress for a more accurate clique getSigners test --- .../CliqueDiscardRpcAcceptanceTest.java | 6 +-- .../clique/CliqueGetSignersRpcTest.java | 46 +++++++++++-------- .../dsl/condition/ExpectBlockNumber.java | 19 ++++++-- .../tests/acceptance/dsl/node/Eth.java | 11 +++++ .../acceptance/dsl/node/PantheonNode.java | 3 -- .../tests/acceptance/dsl/node/Web3.java | 19 +------- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index 88635101fc..e066ea1a8a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -18,11 +18,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; -import java.math.BigInteger; import org.junit.Test; -import org.web3j.protocol.core.DefaultBlockParameter; -import org.web3j.protocol.core.methods.response.EthBlock.Block; public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBase { @@ -48,6 +45,7 @@ public void shouldDiscardVotes() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.verify(clique.noProposals()); - minerNode2.verify(clique.proposalsEqual().removeProposal(minerNode2).addProposal(minerNode3).build()); + minerNode2.verify( + clique.proposalsEqual().removeProposal(minerNode2).addProposal(minerNode3).build()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index 73f7e59eb9..45d6b1fd21 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -12,44 +12,50 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; +import org.junit.Before; import org.junit.Test; -import org.web3j.protocol.core.DefaultBlockParameter; -import org.web3j.protocol.core.methods.response.EthBlock.Block; public class CliqueGetSignersRpcTest extends AcceptanceTestBase { + private PantheonNode minerNode1; + private PantheonNode minerNode2; + private PantheonNode minerNode3; + private PantheonNode[] allNodes; + + @Before + public void setUp() throws Exception { + final String[] validators = {"miner1", "miner2"}; + minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", validators)); + minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", validators)); + minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", validators)); + allNodes = new PantheonNode[] {minerNode1, minerNode2, minerNode3}; + cluster.start(); + } + @Test public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { - final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); - final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - final PantheonNode[] allNodes = {minerNode1, minerNode2, minerNode3}; - cluster.start(); + minerNode1.clique().proposeAdd(minerNode3); + minerNode2.clique().proposeAdd(minerNode3); + minerNode1.waitForChainHeadToProgress(2); - final Block latest = - minerNode1.web3().ethGetBlockByNumber(DefaultBlockParameter.valueOf("latest"), false); - cluster.verify(clique.validatorsAtBlockEqual("0x0", allNodes)); + cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); cluster.verify(clique.validatorsAtBlockEqual("latest", allNodes)); - cluster.verify(clique.validatorsAtBlockEqual(latest.getNumber().toString(), allNodes)); } @Test public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { - final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); - final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - final PantheonNode[] allNodes = {minerNode1, minerNode2}; - cluster.start(); + minerNode1.clique().proposeAdd(minerNode3); + minerNode2.clique().proposeAdd(minerNode3); + minerNode1.waitForChainHeadToProgress(2); - final DefaultBlockParameter latest = DefaultBlockParameter.valueOf("latest"); - final Block latestBlock = minerNode1.web3().ethGetBlockByNumber(latest, false); - final String hash = latestBlock.getHash(); - cluster.verify(clique.validatorsAtBlockHashEqual(hash, allNodes)); + final String latestBlockHash = minerNode1.eth().blockHash(); + cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java index d8a2b4e248..7d171c3904 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java @@ -1,11 +1,24 @@ +/* + * 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; import static org.assertj.core.api.Java6Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; -import java.math.BigInteger; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import java.math.BigInteger; + public class ExpectBlockNumber implements Condition { private BigInteger blockNumber; @@ -15,8 +28,6 @@ public ExpectBlockNumber(final BigInteger blockNumber) { @Override public void verify(final Node node) { - waitFor( - () -> assertThat(node.eth().blockNumber()).isEqualTo(blockNumber) - ); + waitFor(() -> assertThat(node.eth().blockNumber()).isEqualTo(blockNumber)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java index 057034d90b..2e8176b585 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java @@ -12,12 +12,15 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static java.util.jar.Pack200.Packer.LATEST; import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import java.math.BigInteger; import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.EthBlockNumber; import org.web3j.protocol.core.methods.response.EthGetWork; @@ -36,6 +39,14 @@ public BigInteger blockNumber() throws IOException { return result.getBlockNumber(); } + public String blockHash() throws IOException { + final DefaultBlockParameter latest = DefaultBlockParameter.valueOf(LATEST); + EthBlock result = web3j.ethGetBlockByNumber(latest, false).send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getBlock().getHash(); + } + public String[] getWork() throws IOException { final EthGetWork result = web3j.ethGetWork().send(); assertThat(result).isNotNull(); 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 d958654cb2..c32a0928e4 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 @@ -16,10 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST; -import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; -import org.assertj.core.api.Assertions; -import org.assertj.core.api.Java6Assertions; import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.controller.KeyPairUtil; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java index f8507267cf..88fd1a8b49 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Web3.java @@ -17,10 +17,7 @@ import java.io.IOException; import org.web3j.protocol.Web3j; -import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.Response; -import org.web3j.protocol.core.methods.response.EthBlock; -import org.web3j.protocol.core.methods.response.EthBlock.Block; import org.web3j.protocol.core.methods.response.Web3Sha3; public class Web3 { @@ -33,20 +30,8 @@ public Web3(final Web3j web3) { public String web3Sha3(final String input) throws IOException { final Web3Sha3 result = web3j.web3Sha3(input).send(); - assertResponseHasResult(result); - return result.getResult(); - } - - public Block ethGetBlockByNumber( - final DefaultBlockParameter blockParameter, final boolean fullTransactionData) - throws IOException { - EthBlock result = web3j.ethGetBlockByNumber(blockParameter, fullTransactionData).send(); - assertResponseHasResult(result); - return result.getBlock(); - } - - private void assertResponseHasResult(final Response result) { - assertThat(result).isNotNull(); + assertThat((Response) result).isNotNull(); assertThat(result.hasError()).isFalse(); + return result.getResult(); } } From ba6a232be0b8b7b104db0495e1e65a50eacdd963 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 29 Oct 2018 16:21:53 +1000 Subject: [PATCH 14/41] [NC-1524] test to confirm clique vote details are in block header --- .../clique/CliqueGetSignersRpcTest.java | 2 +- .../CliqueProposeRpcAcceptanceTest.java | 29 ++++++++++++-- .../acceptance/dsl/AcceptanceTestBase.java | 3 ++ .../dsl/blockchain/BlockChainConditions.java | 24 +++++++++++ .../dsl/clique/CliqueConditions.java | 6 +++ .../dsl/condition/ExpectBeneficiary.java | 36 +++++++++++++++++ .../dsl/condition/ExpectNonceVote.java | 40 +++++++++++++++++++ .../tests/acceptance/dsl/node/Eth.java | 11 ++++- 8 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index 45d6b1fd21..ce55c3514e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -55,7 +55,7 @@ public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { minerNode2.clique().proposeAdd(minerNode3); minerNode1.waitForChainHeadToProgress(2); - final String latestBlockHash = minerNode1.eth().blockHash(); + final String latestBlockHash = minerNode1.eth().latestBlockHash(); cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index fe7184694d..60c5972d75 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -12,9 +12,11 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; +import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; @@ -75,7 +77,19 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { @Test public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { - final String[] initialValidators = {"miner1", "miner2", "miner3"}; + final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); + final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); + final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); + cluster.start(); + + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().proposeRemove(minerNode3); + cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + } + + @Test + public void shouldIncludeVoteInBlockHeader() throws IOException { + final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); final PantheonNode minerNode2 = @@ -84,8 +98,15 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(); - cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - minerNode1.clique().proposeRemove(minerNode3); - cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + minerNode1.clique().proposeAdd(minerNode3); + minerNode1.clique().proposeRemove(minerNode2); + + minerNode1.waitForChainHeadToProgress(1); + minerNode1.verify(blockChain.beneficiaryEquals(minerNode3)); + minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); + + minerNode1.waitForChainHeadToProgress(1); + minerNode1.verify(blockChain.beneficiaryEquals(minerNode2)); + minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); } } 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 70606bd2e6..9c3827ca36 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 @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.tests.acceptance.dsl; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts; +import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.BlockChainConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Cluster; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; @@ -26,6 +27,7 @@ public class AcceptanceTestBase { protected final Transactions transactions; protected final JsonRpc jsonRpc; protected final CliqueConditions clique; + protected final BlockChainConditions blockChain; protected AcceptanceTestBase() { accounts = new Accounts(); @@ -33,6 +35,7 @@ protected AcceptanceTestBase() { transactions = new Transactions(accounts); jsonRpc = new JsonRpc(cluster); clique = new CliqueConditions(); + blockChain = new BlockChainConditions(); } @After diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java new file mode 100644 index 0000000000..13a67592bf --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java @@ -0,0 +1,24 @@ +/* + * 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.blockchain; + +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBeneficiary; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +public class BlockChainConditions { + + public Condition beneficiaryEquals(final PantheonNode node) { + return new ExpectBeneficiary(node); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java index 43cf4c455b..570b046d4e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java @@ -15,6 +15,8 @@ import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectProposals; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlock; @@ -54,6 +56,10 @@ public Condition noProposals() { return new ExpectProposals(ImmutableMap.of()); } + public Condition nonceVoteEquals(final CLIQUE_NONCE_VOTE clique_nonce_vote) { + return new ExpectNonceVote(clique_nonce_vote); + } + private Address[] validatorAddresses(final PantheonNode[] validators) { return Arrays.stream(validators).map(PantheonNode::getAddress).sorted().toArray(Address[]::new); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java new file mode 100644 index 0000000000..a039096e8b --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.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; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; + +public class ExpectBeneficiary implements Condition { + private String beneficiary; + + public ExpectBeneficiary(final PantheonNode node) { + this.beneficiary = node.getAddress().toString(); + } + + @Override + public void verify(final Node node) { + waitFor( + () -> { + String miner = node.eth().latestBlock().getMiner(); + assertThat(miner).isEqualTo(beneficiary); + }); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java new file mode 100644 index 0000000000..9453905045 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java @@ -0,0 +1,40 @@ +/* + * 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; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; + +public class ExpectNonceVote implements Condition { + private String expectedNonce; + + public enum CLIQUE_NONCE_VOTE { + AUTH, + DROP + } + + public ExpectNonceVote(final CLIQUE_NONCE_VOTE vote) { + this.expectedNonce = + vote == CLIQUE_NONCE_VOTE.AUTH ? "0xffffffffffffffff" : "0x0000000000000000"; + } + + @Override + public void verify(final Node node) { + waitFor( + () -> { + assertThat(node.eth().latestBlock().getNonceRaw()).isEqualTo(expectedNonce); + }); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java index 2e8176b585..c335328582 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Eth.java @@ -21,6 +21,7 @@ import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthBlock.Block; import org.web3j.protocol.core.methods.response.EthBlockNumber; import org.web3j.protocol.core.methods.response.EthGetWork; @@ -39,7 +40,7 @@ public BigInteger blockNumber() throws IOException { return result.getBlockNumber(); } - public String blockHash() throws IOException { + public String latestBlockHash() throws IOException { final DefaultBlockParameter latest = DefaultBlockParameter.valueOf(LATEST); EthBlock result = web3j.ethGetBlockByNumber(latest, false).send(); assertThat(result).isNotNull(); @@ -47,6 +48,14 @@ public String blockHash() throws IOException { return result.getBlock().getHash(); } + public Block latestBlock() throws IOException { + final DefaultBlockParameter latest = DefaultBlockParameter.valueOf(LATEST); + EthBlock result = web3j.ethGetBlockByNumber(latest, false).send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getBlock(); + } + public String[] getWork() throws IOException { final EthGetWork result = web3j.ethGetWork().send(); assertThat(result).isNotNull(); From af45272148e5aed26d3a44c0364fa8162b649606 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 29 Oct 2018 17:17:24 +1000 Subject: [PATCH 15/41] [NC-1524] test clique stalls if insufficient validators --- .../clique/CliqueMiningAcceptanceTest.java | 19 +++++++++++++++++++ .../dsl/blockchain/BlockChainConditions.java | 7 +++++++ .../tests/acceptance/dsl/node/Cluster.java | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 7037e3393e..6947169de7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -19,6 +19,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; +import java.math.BigInteger; import org.junit.Test; @@ -61,4 +62,22 @@ public void shouldMineTransactionsOnMultipleNodes() throws IOException { minerNode3.execute(transactions.createIncrementalTransfers(sender, receiver, 2)); cluster.verify(receiver.balanceEquals(3)); } + + @Test + public void shouldStallMiningWhenInsufficientValidators() + throws IOException, InterruptedException { + final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); + final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); + final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); + cluster.start(); + + cluster.stopNode(minerNode2); + cluster.stopNode(minerNode3); + + BigInteger lastBlockNumber = minerNode1.eth().blockNumber(); + Thread.sleep(20_000); + minerNode1.verify(blockChain.blockNumberEquals(lastBlockNumber)); + Thread.sleep(20_000); + minerNode1.verify(blockChain.blockNumberEquals(lastBlockNumber)); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java index 13a67592bf..ed9854af79 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/BlockChainConditions.java @@ -14,11 +14,18 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBeneficiary; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import java.math.BigInteger; + public class BlockChainConditions { public Condition beneficiaryEquals(final PantheonNode node) { return new ExpectBeneficiary(node); } + + public Condition blockNumberEquals(final BigInteger blockNumber) { + return new ExpectBlockNumber(blockNumber); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index ab8bc76151..2ead923420 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -64,6 +64,10 @@ public void stop() { pantheonNodeRunner.shutdown(); } + public void stopNode(final PantheonNode node) { + pantheonNodeRunner.stopNode(node); + } + @Override public void close() { for (final PantheonNode node : nodes) { From 74af4e5321e848d4f360e65c176dd52f6d5d6863 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 29 Oct 2018 17:38:53 +1000 Subject: [PATCH 16/41] [NC-1524] cleanup --- .../tests/acceptance/dsl/condition/ExpectNonceVote.java | 8 +++++--- .../pantheon/tests/acceptance/dsl/node/PantheonNode.java | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java index 9453905045..93ec078f08 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java @@ -14,11 +14,14 @@ import static org.assertj.core.api.Java6Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import static tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE.AUTH; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; public class ExpectNonceVote implements Condition { - private String expectedNonce; + private static final String NONCE_AUTH = "0xffffffffffffffff"; + private static final String NONCE_DROP = "0x0000000000000000"; + private final String expectedNonce; public enum CLIQUE_NONCE_VOTE { AUTH, @@ -26,8 +29,7 @@ public enum CLIQUE_NONCE_VOTE { } public ExpectNonceVote(final CLIQUE_NONCE_VOTE vote) { - this.expectedNonce = - vote == CLIQUE_NONCE_VOTE.AUTH ? "0xffffffffffffffff" : "0x0000000000000000"; + this.expectedNonce = vote == AUTH ? NONCE_AUTH : NONCE_DROP; } @Override 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 c32a0928e4..71795a3632 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 @@ -350,6 +350,7 @@ public Web3 web3() { return web3; } + @Override public Eth eth() { if (eth == null) { eth = new Eth(web3j()); From 83aa0ae84ec40eb41bd6f064e99751c18c7f468f Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 31 Oct 2018 17:09:07 +1000 Subject: [PATCH 17/41] [NC-1524] cleanup --- .../clique/CliqueGetSignersRpcTest.java | 4 ++-- .../clique/CliqueMiningAcceptanceTest.java | 12 +++++----- .../CliqueProposeRpcAcceptanceTest.java | 4 ++-- .../acceptance/dsl/AcceptanceTestBase.java | 7 ++---- .../acceptance/dsl/blockchain/Blockchain.java | 13 +++++++++++ .../dsl/clique/CliqueConditions.java | 8 ++++++- .../dsl/condition/ExpectBeneficiary.java | 12 +++++----- .../dsl/condition/ExpectBlockNumber.java | 8 +++++-- .../dsl/condition/ExpectNonceVote.java | 10 ++++---- .../acceptance/dsl/node/PantheonNode.java | 23 ++++++------------- .../eth/EthGetBlockTransaction.java | 14 +++++------ .../dsl/transaction/eth/EthTransactions.java | 6 +++++ 12 files changed, 69 insertions(+), 52 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index ce55c3514e..ad8926fc00 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -55,7 +55,7 @@ public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { minerNode2.clique().proposeAdd(minerNode3); minerNode1.waitForChainHeadToProgress(2); - final String latestBlockHash = minerNode1.eth().latestBlockHash(); - cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); + // TODO requires DSL changes for this test to work + // cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 6947169de7..ae81351a4d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -16,10 +16,10 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; -import java.math.BigInteger; import org.junit.Test; @@ -74,10 +74,10 @@ public void shouldStallMiningWhenInsufficientValidators() cluster.stopNode(minerNode2); cluster.stopNode(minerNode3); - BigInteger lastBlockNumber = minerNode1.eth().blockNumber(); - Thread.sleep(20_000); - minerNode1.verify(blockChain.blockNumberEquals(lastBlockNumber)); - Thread.sleep(20_000); - minerNode1.verify(blockChain.blockNumberEquals(lastBlockNumber)); + final Condition lastBlockNumber = blockchain.blockNumberMustBeLatest(minerNode1); + Thread.sleep(15_000); + minerNode1.verify(lastBlockNumber); + Thread.sleep(15_000); + minerNode1.verify(lastBlockNumber); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 60c5972d75..2528617aa0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -102,11 +102,11 @@ public void shouldIncludeVoteInBlockHeader() throws IOException { minerNode1.clique().proposeRemove(minerNode2); minerNode1.waitForChainHeadToProgress(1); - minerNode1.verify(blockChain.beneficiaryEquals(minerNode3)); + minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); minerNode1.waitForChainHeadToProgress(1); - minerNode1.verify(blockChain.beneficiaryEquals(minerNode2)); + minerNode1.verify(blockchain.beneficiaryEquals(minerNode2)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); } } 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 d4b25da90c..69396d73e0 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 @@ -14,10 +14,9 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts; import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Blockchain; +import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.JsonRpc; -import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.BlockChainConditions; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; 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; @@ -35,7 +34,6 @@ public class AcceptanceTestBase { protected final Cluster cluster; protected final JsonRpc jsonRpc; protected final CliqueConditions clique; - protected final BlockChainConditions blockChain; protected final Transactions transactions; protected final Web3 web3; protected final Eth eth; @@ -48,8 +46,7 @@ protected AcceptanceTestBase() { cluster = new Cluster(); eth = new Eth(ethTransactions); jsonRpc = new JsonRpc(cluster); - clique = new CliqueConditions(); - blockChain = new BlockChainConditions(); + clique = new CliqueConditions(ethTransactions); net = new Net(new NetTransactions()); transactions = new Transactions(accounts); web3 = new Web3(new Web3Transactions()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java index a2d59509bd..6587029f93 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java @@ -13,10 +13,15 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.blockchain; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBeneficiary; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectMinimumBlockNumber; 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.transaction.eth.EthTransactions; +import java.math.BigInteger; + public class Blockchain { private final EthTransactions eth; @@ -28,4 +33,12 @@ public Blockchain(final EthTransactions eth) { public Condition blockNumberMustBeLatest(final Node node) { return new ExpectMinimumBlockNumber(eth, node.execute(eth.blockNumber())); } + + public Condition beneficiaryEquals(final PantheonNode node) { + return new ExpectBeneficiary(eth, node); + } + + public Condition blockNumberEquals(final BigInteger blockNumber) { + return new ExpectBlockNumber(eth, blockNumber); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java index 570b046d4e..0bd3883069 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java @@ -22,6 +22,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlock; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlockHash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.util.Arrays; import java.util.HashMap; @@ -32,6 +33,11 @@ import com.google.common.collect.ImmutableMap; public class CliqueConditions { + private final EthTransactions eth; + + public CliqueConditions(final EthTransactions eth) { + this.eth = eth; + } public Condition validatorsEqual(final PantheonNode... validators) { return new ExpectValidators(validatorAddresses(validators)); @@ -57,7 +63,7 @@ public Condition noProposals() { } public Condition nonceVoteEquals(final CLIQUE_NONCE_VOTE clique_nonce_vote) { - return new ExpectNonceVote(clique_nonce_vote); + return new ExpectNonceVote(eth, clique_nonce_vote); } private Address[] validatorAddresses(final PantheonNode[] validators) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java index a039096e8b..fee9a4dca7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java @@ -17,20 +17,20 @@ 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.transaction.eth.EthTransactions; public class ExpectBeneficiary implements Condition { + + private EthTransactions eth; private String beneficiary; - public ExpectBeneficiary(final PantheonNode node) { + public ExpectBeneficiary(final EthTransactions eth, final PantheonNode node) { + this.eth = eth; this.beneficiary = node.getAddress().toString(); } @Override public void verify(final Node node) { - waitFor( - () -> { - String miner = node.eth().latestBlock().getMiner(); - assertThat(miner).isEqualTo(beneficiary); - }); + waitFor(() -> assertThat(node.execute(eth.block()).getMiner()).isEqualTo(beneficiary)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java index 7d171c3904..909a972db9 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java @@ -16,18 +16,22 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.math.BigInteger; public class ExpectBlockNumber implements Condition { + + private EthTransactions eth; private BigInteger blockNumber; - public ExpectBlockNumber(final BigInteger blockNumber) { + public ExpectBlockNumber(final EthTransactions eth, final BigInteger blockNumber) { + this.eth = eth; this.blockNumber = blockNumber; } @Override public void verify(final Node node) { - waitFor(() -> assertThat(node.eth().blockNumber()).isEqualTo(blockNumber)); + waitFor(() -> assertThat(node.execute(eth.blockNumber())).isEqualTo(blockNumber)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java index 93ec078f08..77eb05af9f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java @@ -17,10 +17,12 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE.AUTH; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; public class ExpectNonceVote implements Condition { private static final String NONCE_AUTH = "0xffffffffffffffff"; private static final String NONCE_DROP = "0x0000000000000000"; + private final EthTransactions eth; private final String expectedNonce; public enum CLIQUE_NONCE_VOTE { @@ -28,15 +30,13 @@ public enum CLIQUE_NONCE_VOTE { DROP } - public ExpectNonceVote(final CLIQUE_NONCE_VOTE vote) { + public ExpectNonceVote(final EthTransactions eth, final CLIQUE_NONCE_VOTE vote) { + this.eth = eth; this.expectedNonce = vote == AUTH ? NONCE_AUTH : NONCE_DROP; } @Override public void verify(final Node node) { - waitFor( - () -> { - assertThat(node.eth().latestBlock().getNonceRaw()).isEqualTo(expectedNonce); - }); + waitFor(() -> assertThat(node.execute(eth.block()).getNonceRaw()).isEqualTo(expectedNonce)); } } 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 a7cf5d621f..a21368e22a 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 @@ -14,7 +14,6 @@ import static org.apache.logging.log4j.LogManager.getLogger; -import java.math.BigInteger; import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.controller.KeyPairUtil; import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; @@ -23,10 +22,8 @@ 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.tests.acceptance.dsl.account.Account; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.File; @@ -205,6 +202,10 @@ private void loadPortsFile() { } } + public Address getAddress() { + return Util.publicKeyToAddress(keyPair.getPublicKey()); + } + Path homeDirectory() { return homeDirectory; } @@ -291,15 +292,6 @@ public void close() { } } - @Override - public Eth eth() { - if (eth == null) { - eth = new Eth(web3j()); - } - - return eth; - } - @Override public Clique clique() { if (clique == null) { @@ -330,8 +322,7 @@ public void verify(final Condition expected) { expected.verify(this); } - public void waitForChainHeadToProgress(final int blocksAheadOfLatest) throws IOException { - final BigInteger futureBlock = eth().blockNumber().add(BigInteger.valueOf(blocksAheadOfLatest)); - new ExpectBlockNumber(futureBlock).verify(this); + public void waitForChainHeadToProgress(final int blocksAheadOfLatest) { + // TODO requires DSL changes for this to work } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java index d1c2a180a1..cd02e78811 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java @@ -13,23 +13,22 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth; import static org.assertj.core.api.Assertions.assertThat; -import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; -import java.math.BigInteger; + import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.EthBlock.Block; -import org.web3j.protocol.core.methods.response.EthGetBalance; -import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; public class EthGetBlockTransaction implements Transaction { private final DefaultBlockParameter blockParameter; private final boolean fullTransactionObjects; - EthGetBlockTransaction(final DefaultBlockParameter blockParameter, final boolean fullTransactionObjects) { + EthGetBlockTransaction( + final DefaultBlockParameter blockParameter, final boolean fullTransactionObjects) { this.blockParameter = blockParameter; this.fullTransactionObjects = fullTransactionObjects; } @@ -37,7 +36,8 @@ public class EthGetBlockTransaction implements Transaction { @Override public Block execute(final Web3j node) { try { - final EthBlock result = node.ethGetBlockByNumber(blockParameter, fullTransactionObjects).send(); + final EthBlock result = + node.ethGetBlockByNumber(blockParameter, fullTransactionObjects).send(); assertThat(result).isNotNull(); assertThat(result.hasError()).isFalse(); return result.getBlock(); 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 80dec048c0..dc29f5dbe8 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 @@ -14,6 +14,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import org.web3j.protocol.core.DefaultBlockParameterName; + public class EthTransactions { public EthGetWorkTransaction getWork() { @@ -24,6 +26,10 @@ public EthBlockNumberTransaction blockNumber() { return new EthBlockNumberTransaction(); } + public EthGetBlockTransaction block() { + return new EthGetBlockTransaction(DefaultBlockParameterName.LATEST, false); + } + public EthGetBalanceTransaction getBalance(final Account account) { return new EthGetBalanceTransaction(account); } From da89fbedf808bea16fb58ca9251ec7082b8d1550 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 07:46:13 +1000 Subject: [PATCH 18/41] [NC-1524] use web3j factory with added clique methods --- .../acceptance/dsl/node/PantheonNode.java | 31 ++++++- .../dsl/transaction/PantheonWeb3j.java | 81 +++++++++++++++++++ .../dsl/transaction/Transaction.java | 4 +- .../account/TransferTransaction.java | 4 +- .../account/TransferTransactionSet.java | 5 +- .../eth/EthAccountsTransaction.java | 4 +- .../eth/EthBlockNumberTransaction.java | 5 +- .../eth/EthGetBalanceTransaction.java | 4 +- .../eth/EthGetBlockTransaction.java | 4 +- .../eth/EthGetWorkTransaction.java | 4 +- .../net/NetVersionTransaction.java | 4 +- .../transaction/web3/Web3Sha3Transaction.java | 4 +- 12 files changed, 129 insertions(+), 25 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java 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 a21368e22a..64a2e816e8 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 @@ -24,6 +24,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.File; @@ -71,6 +72,7 @@ public class PantheonNode implements Node, AutoCloseable { private Eth eth; private Clique clique; private Web3j web3j; + private PantheonWeb3j pantheonWeb3j; private Optional ethNetworkConfig = Optional.empty(); public PantheonNode( @@ -144,7 +146,7 @@ public Web3j web3j() { } if (web3j == null) { - return web3j(new HttpService(jsonRpcBaseUrl().get())); + return web3j(web3jService()); } return web3j; @@ -180,6 +182,31 @@ public void useWebSocketsForJsonRpc() { web3j = Web3j.build(webSocketService, 2000, Async.defaultExecutorService()); } + private PantheonWeb3j pantheonWeb3j() { + if (pantheonWeb3j == null) { + return pantheonWeb3j(web3jService()); + } + + return pantheonWeb3j; + } + + private PantheonWeb3j pantheonWeb3j(final Web3jService web3jService) { + if (pantheonWeb3j == null) { + pantheonWeb3j = new PantheonWeb3j(web3jService, 2000, Async.defaultExecutorService()); + } + + return pantheonWeb3j; + } + + private Web3jService web3jService() { + if (!jsonRpcBaseUrl().isPresent()) { + throw new IllegalStateException( + "Can't create a web3j instance for a node with RPC disabled."); + } + + return new HttpService(jsonRpcBaseUrl().get()); + } + public int getPeerCount() { try { return web3j().netPeerCount().send().getQuantity().intValueExact(); @@ -315,7 +342,7 @@ public Optional getEthNetworkConfig() { @Override public T execute(final Transaction transaction) { - return transaction.execute(web3j()); + return transaction.execute(pantheonWeb3j()); } public void verify(final Condition expected) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java new file mode 100644 index 0000000000..387ffa1e70 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.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.dsl.transaction; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Hash; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledExecutorService; + +import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.JsonRpc2_0Web3j; +import org.web3j.protocol.core.Request; +import org.web3j.protocol.core.Response; + +public class PantheonWeb3j extends JsonRpc2_0Web3j { + + public PantheonWeb3j(final Web3jService web3jService) { + super(web3jService); + } + + public PantheonWeb3j( + final Web3jService web3jService, + final long pollingInterval, + final ScheduledExecutorService scheduledExecutorService) { + super(web3jService, pollingInterval, scheduledExecutorService); + } + + public Request cliquePropose(final String address, final Boolean auth) { + return new Request<>( + "clique_propose", + Arrays.asList(address, auth.toString()), + web3jService, + ProposeResponse.class); + } + + public Request cliqueDiscard(final String address) { + return new Request<>( + "clique_discard", singletonList(address), web3jService, DiscardResponse.class); + } + + public Request cliqueProposals() { + return new Request<>("clique_proposals", emptyList(), web3jService, ProposalsResponse.class); + } + + public Request cliqueGetSigners(final String blockNumber) { + return new Request<>( + "clique_getSigners", singletonList(blockNumber), web3jService, SignersBlockResponse.class); + } + + public Request cliqueGetSignersAtHash(final Hash hash) { + return new Request<>( + "clique_getSignersAtHash", + singletonList(hash.toString()), + web3jService, + SignersBlockResponse.class); + } + + public static class ProposeResponse extends Response {} + + public static class DiscardResponse extends Response {} + + public static class SignersBlockResponse extends Response> {} + + public static class ProposalsResponse extends Response> {} +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/Transaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/Transaction.java index e038d694da..beea7962ff 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/Transaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/Transaction.java @@ -12,9 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.transaction; -import org.web3j.protocol.Web3j; - public interface Transaction { - T execute(final Web3j node); + T execute(final PantheonWeb3j node); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransaction.java index 734495e3fd..037cf9888f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransaction.java @@ -16,6 +16,7 @@ import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; @@ -23,7 +24,6 @@ import org.web3j.crypto.RawTransaction; import org.web3j.crypto.TransactionEncoder; -import org.web3j.protocol.Web3j; import org.web3j.utils.Convert; import org.web3j.utils.Convert.Unit; @@ -46,7 +46,7 @@ public TransferTransaction( } @Override - public Hash execute(final Web3j node) { + public Hash execute(final PantheonWeb3j node) { final RawTransaction transaction = RawTransaction.createEtherTransaction( sender.getNextNonce(), diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransactionSet.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransactionSet.java index 7c0665ce85..b0cab54977 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransactionSet.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/account/TransferTransactionSet.java @@ -13,13 +13,12 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.account; import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.util.ArrayList; import java.util.List; -import org.web3j.protocol.Web3j; - public class TransferTransactionSet implements Transaction> { private final List transactions; @@ -29,7 +28,7 @@ public TransferTransactionSet(final List transactions) { } @Override - public List execute(final Web3j node) { + public List execute(final PantheonWeb3j node) { final List hashes = new ArrayList<>(); for (final TransferTransaction transaction : transactions) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthAccountsTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthAccountsTransaction.java index 1aba152492..b8a9c2dd21 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthAccountsTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthAccountsTransaction.java @@ -14,12 +14,12 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; import java.util.List; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.EthAccounts; public class EthAccountsTransaction implements Transaction> { @@ -27,7 +27,7 @@ public class EthAccountsTransaction implements Transaction> { EthAccountsTransaction() {} @Override - public List execute(final Web3j node) { + public List execute(final PantheonWeb3j node) { try { final EthAccounts result = node.ethAccounts().send(); assertThat(result).isNotNull(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java index d9b6b1cdc1..fe7a1a87ce 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java @@ -14,19 +14,18 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; import java.math.BigInteger; -import org.web3j.protocol.Web3j; - public class EthBlockNumberTransaction implements Transaction { EthBlockNumberTransaction() {} @Override - public BigInteger execute(final Web3j node) { + public BigInteger execute(final PantheonWeb3j node) { try { final org.web3j.protocol.core.methods.response.EthBlockNumber result = node.ethBlockNumber().send(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBalanceTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBalanceTransaction.java index ef875bcf9a..57ea00b0c3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBalanceTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBalanceTransaction.java @@ -16,12 +16,12 @@ import static org.web3j.protocol.core.DefaultBlockParameterName.LATEST; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; import java.math.BigInteger; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.EthGetBalance; public class EthGetBalanceTransaction implements Transaction { @@ -33,7 +33,7 @@ public class EthGetBalanceTransaction implements Transaction { } @Override - public BigInteger execute(final Web3j node) { + public BigInteger execute(final PantheonWeb3j node) { try { final EthGetBalance result = node.ethGetBalance(account.getAddress(), LATEST).send(); assertThat(result).isNotNull(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java index cd02e78811..9cb5e1a623 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetBlockTransaction.java @@ -14,11 +14,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.EthBlock.Block; @@ -34,7 +34,7 @@ public class EthGetBlockTransaction implements Transaction { } @Override - public Block execute(final Web3j node) { + public Block execute(final PantheonWeb3j node) { try { final EthBlock result = node.ethGetBlockByNumber(blockParameter, fullTransactionObjects).send(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetWorkTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetWorkTransaction.java index 6a2140a038..f98199c420 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetWorkTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetWorkTransaction.java @@ -14,11 +14,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.EthGetWork; public class EthGetWorkTransaction implements Transaction { @@ -26,7 +26,7 @@ public class EthGetWorkTransaction implements Transaction { EthGetWorkTransaction() {} @Override - public String[] execute(final Web3j node) { + public String[] execute(final PantheonWeb3j node) { try { final EthGetWork result = node.ethGetWork().send(); assertThat(result).isNotNull(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetVersionTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetVersionTransaction.java index c5657570e7..6effb90bdc 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetVersionTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetVersionTransaction.java @@ -14,11 +14,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.NetVersion; public class NetVersionTransaction implements Transaction { @@ -26,7 +26,7 @@ public class NetVersionTransaction implements Transaction { NetVersionTransaction() {} @Override - public String execute(final Web3j node) { + public String execute(final PantheonWeb3j node) { try { final NetVersion result = node.netVersion().send(); assertThat(result).isNotNull(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/web3/Web3Sha3Transaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/web3/Web3Sha3Transaction.java index ebf3ecbe25..15341a0a65 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/web3/Web3Sha3Transaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/web3/Web3Sha3Transaction.java @@ -14,11 +14,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.Web3Sha3; public class Web3Sha3Transaction implements Transaction { @@ -30,7 +30,7 @@ public class Web3Sha3Transaction implements Transaction { } @Override - public String execute(final Web3j node) { + public String execute(final PantheonWeb3j node) { try { final Web3Sha3 result = node.web3Sha3(input).send(); assertThat(result).isNotNull(); From 2dd7596d378dcfd367059b55f1e14a88ae4afe64 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 08:38:58 +1000 Subject: [PATCH 19/41] [NC-1524] clique transactions --- .../dsl/transaction/CliqueTransactions.java | 52 +++++++++++++++++++ .../dsl/transaction/clique/CliqueDiscard.java | 41 +++++++++++++++ .../transaction/clique/CliqueGetSigners.java | 43 +++++++++++++++ .../clique/CliqueGetSignersAtHash.java | 44 ++++++++++++++++ .../transaction/clique/CliqueProposals.java | 38 ++++++++++++++ .../dsl/transaction/clique/CliquePropose.java | 43 +++++++++++++++ 6 files changed, 261 insertions(+) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueDiscard.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSignersAtHash.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueProposals.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliquePropose.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java new file mode 100644 index 0000000000..bf977825c4 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java @@ -0,0 +1,52 @@ +/* + * 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; + +import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueDiscard; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueGetSigners; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueGetSignersAtHash; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueProposals; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliquePropose; + +public class CliqueTransactions { + + public CliquePropose proposeRemove(final PantheonNode node) { + return propose(node.getAddress().toString(), false); + } + + public CliquePropose proposeAdd(final PantheonNode node) { + return propose(node.getAddress().toString(), true); + } + + public CliquePropose propose(final String address, final boolean auth) { + return new CliquePropose(address, auth); + } + + public CliqueProposals proposals() { + return new CliqueProposals(); + } + + public CliqueGetSigners getSigners(final String blockNumber) { + return new CliqueGetSigners(blockNumber); + } + + public CliqueGetSignersAtHash getSignersAtHash(final Hash blockHash) { + return new CliqueGetSignersAtHash(blockHash); + } + + public CliqueDiscard discard(final PantheonNode node) { + return new CliqueDiscard(node.getAddress().toString()); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueDiscard.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueDiscard.java new file mode 100644 index 0000000000..237c8b15f3 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueDiscard.java @@ -0,0 +1,41 @@ +/* + * 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.clique; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j.DiscardResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; + +public class CliqueDiscard implements Transaction { + private final String address; + + public CliqueDiscard(final String address) { + this.address = address; + } + + @Override + public Boolean execute(final PantheonWeb3j node) { + try { + final DiscardResponse result = node.cliqueDiscard(address).send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getResult(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java new file mode 100644 index 0000000000..0b7ca14f1f --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java @@ -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.tests.acceptance.dsl.transaction.clique; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j.SignersBlockResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; +import java.util.List; + +public class CliqueGetSigners implements Transaction> { + private final String blockNumber; + + public CliqueGetSigners(final String blockNumber) { + this.blockNumber = blockNumber; + } + + @Override + public List
execute(final PantheonWeb3j node) { + try { + final SignersBlockResponse result = node.cliqueGetSigners(blockNumber).send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getResult(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSignersAtHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSignersAtHash.java new file mode 100644 index 0000000000..953903fca9 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSignersAtHash.java @@ -0,0 +1,44 @@ +/* + * 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.clique; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j.SignersBlockResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; +import java.util.List; + +public class CliqueGetSignersAtHash implements Transaction> { + private final Hash hash; + + public CliqueGetSignersAtHash(final Hash hash) { + this.hash = hash; + } + + @Override + public List
execute(final PantheonWeb3j node) { + try { + final SignersBlockResponse result = node.cliqueGetSignersAtHash(hash).send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getResult(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueProposals.java new file mode 100644 index 0000000000..a81f84909b --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueProposals.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.clique; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j.ProposalsResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; +import java.util.Map; + +public class CliqueProposals implements Transaction> { + + @Override + public Map execute(final PantheonWeb3j node) { + try { + final ProposalsResponse result = node.cliqueProposals().send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getResult(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliquePropose.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliquePropose.java new file mode 100644 index 0000000000..e4f4d7212e --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliquePropose.java @@ -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.tests.acceptance.dsl.transaction.clique; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j.ProposeResponse; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; + +import java.io.IOException; + +public class CliquePropose implements Transaction { + private final String address; + private final boolean auth; + + public CliquePropose(final String address, final boolean auth) { + this.address = address; + this.auth = auth; + } + + @Override + public Boolean execute(final PantheonWeb3j node) { + try { + final ProposeResponse result = node.cliquePropose(address, auth).send(); + assertThat(result).isNotNull(); + assertThat(result.hasError()).isFalse(); + return result.getResult(); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } +} From adb87fa69ba2c6fa435be8640d950cf6c573fa95 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 09:02:59 +1000 Subject: [PATCH 20/41] [NC-1524] move blockchain related conditions into package --- .../pantheon/tests/acceptance/dsl/blockchain/Blockchain.java | 4 ++-- .../dsl/condition/{ => blockchain}/ExpectBeneficiary.java | 3 ++- .../dsl/condition/{ => blockchain}/ExpectBlockNumber.java | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => blockchain}/ExpectBeneficiary.java (90%) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => blockchain}/ExpectBlockNumber.java (90%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java index 6587029f93..13f1ffd308 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java @@ -13,8 +13,8 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.blockchain; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBeneficiary; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectBlockNumber; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBeneficiary; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectMinimumBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java index fee9a4dca7..ae0dc16727 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBeneficiary.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java @@ -10,11 +10,12 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain; import static org.assertj.core.api.Java6Assertions.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.node.PantheonNode; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java index 909a972db9..c8db8ac140 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectBlockNumber.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java @@ -10,11 +10,12 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain; import static org.assertj.core.api.Java6Assertions.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.EthTransactions; From d829065573b185119b9dae896b3837b2d378cccb Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 09:13:30 +1000 Subject: [PATCH 21/41] [NC-1524] move clique related conditions into package --- .../clique/CliqueProposeRpcAcceptanceTest.java | 2 +- .../acceptance/dsl/clique/CliqueConditions.java | 12 ++++++------ .../dsl/condition/{ => clique}/ExpectNonceVote.java | 5 +++-- .../dsl/condition/{ => clique}/ExpectProposals.java | 3 ++- .../dsl/condition/{ => clique}/ExpectValidators.java | 3 ++- .../{ => clique}/ExpectValidatorsAtBlock.java | 3 ++- .../{ => clique}/ExpectValidatorsAtBlockHash.java | 3 ++- 7 files changed, 18 insertions(+), 13 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => clique}/ExpectNonceVote.java (89%) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => clique}/ExpectProposals.java (90%) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => clique}/ExpectValidators.java (90%) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => clique}/ExpectValidatorsAtBlock.java (90%) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/{ => clique}/ExpectValidatorsAtBlockHash.java (90%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 2528617aa0..1afe73d36f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -16,7 +16,7 @@ import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java index 0bd3883069..52888a9d1d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java @@ -15,12 +15,12 @@ import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectProposals; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidators; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlock; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectValidatorsAtBlockHash; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectProposals; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectValidators; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectValidatorsAtBlock; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectValidatorsAtBlockHash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java similarity index 89% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java index 77eb05af9f..03757f3e0d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectNonceVote.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectNonceVote.java @@ -10,12 +10,13 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; import static org.assertj.core.api.Java6Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; -import static tech.pegasys.pantheon.tests.acceptance.dsl.condition.ExpectNonceVote.CLIQUE_NONCE_VOTE.AUTH; +import static tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE.AUTH; +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.EthTransactions; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java index 204e3ec35e..045bd394c2 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectProposals.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java @@ -10,12 +10,13 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import java.util.Map; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java index eb0eaa37d7..bc9845f4fb 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java @@ -10,12 +10,13 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import java.util.Optional; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java index dd08309183..7436f7ce8c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java @@ -10,12 +10,13 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import java.util.Optional; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java similarity index 90% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java index 169c29c082..af82bbb637 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/ExpectValidatorsAtBlockHash.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java @@ -10,13 +10,14 @@ * 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; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; public class ExpectValidatorsAtBlockHash implements Condition { From 05cb7ce37a8beeab490905c566377bf0a5f72f2c Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 10:26:46 +1000 Subject: [PATCH 22/41] [NC-1524] change clique conditions to use clique transactions --- .../acceptance/dsl/AcceptanceTestBase.java | 4 +-- .../clique/CliqueConditions.java | 33 +++++++++++-------- .../dsl/condition/clique/ExpectProposals.java | 11 +++---- .../condition/clique/ExpectValidators.java | 10 +++--- .../clique/ExpectValidatorsAtBlock.java | 14 +++++--- .../clique/ExpectValidatorsAtBlockHash.java | 8 +++-- .../dsl/transaction/CliqueTransactions.java | 4 ++- .../dsl/transaction/PantheonWeb3j.java | 9 +++-- .../transaction/clique/CliqueGetSigners.java | 6 ++-- 9 files changed, 62 insertions(+), 37 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/{ => condition}/clique/CliqueConditions.java (71%) 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 69396d73e0..61d983fcb1 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 @@ -14,7 +14,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts; import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Blockchain; -import tech.pegasys.pantheon.tests.acceptance.dsl.clique.CliqueConditions; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.CliqueConditions; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.JsonRpc; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Net; @@ -46,7 +46,7 @@ protected AcceptanceTestBase() { cluster = new Cluster(); eth = new Eth(ethTransactions); jsonRpc = new JsonRpc(cluster); - clique = new CliqueConditions(ethTransactions); + clique = new CliqueConditions(ethTransactions, null); net = new Net(new NetTransactions()); transactions = new Transactions(accounts); web3 = new Web3(new Web3Transactions()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java similarity index 71% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java index 52888a9d1d..86f29ffe61 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -10,18 +10,14 @@ * 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.clique; +package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectProposals; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectValidators; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectValidatorsAtBlock; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectValidatorsAtBlockHash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.util.Arrays; @@ -31,35 +27,39 @@ import java.util.stream.Collectors; import com.google.common.collect.ImmutableMap; +import org.web3j.protocol.core.DefaultBlockParameterName; public class CliqueConditions { private final EthTransactions eth; + private final CliqueTransactions clique; - public CliqueConditions(final EthTransactions eth) { + public CliqueConditions(final EthTransactions eth, final CliqueTransactions clique) { this.eth = eth; + this.clique = clique; } - public Condition validatorsEqual(final PantheonNode... validators) { - return new ExpectValidators(validatorAddresses(validators)); + public ExpectValidators validatorsEqual(final PantheonNode... validators) { + return new ExpectValidators(clique, validatorAddresses(validators)); } public Condition validatorsAtBlockEqual( final String blockNumber, final PantheonNode... validators) { - return new ExpectValidatorsAtBlock(blockNumber, validatorAddresses(validators)); + return new ExpectValidatorsAtBlock( + clique, DefaultBlockParameterName.fromString(blockNumber), validatorAddresses(validators)); } public Condition validatorsAtBlockHashEqual( final String blockHash, final PantheonNode... validators) { return new ExpectValidatorsAtBlockHash( - Hash.fromHexString(blockHash), validatorAddresses(validators)); + clique, Hash.fromHexString(blockHash), validatorAddresses(validators)); } public ProposalsConfig proposalsEqual() { - return new ProposalsConfig(); + return new ProposalsConfig(clique); } public Condition noProposals() { - return new ExpectProposals(ImmutableMap.of()); + return new ExpectProposals(clique, ImmutableMap.of()); } public Condition nonceVoteEquals(final CLIQUE_NONCE_VOTE clique_nonce_vote) { @@ -72,6 +72,11 @@ private Address[] validatorAddresses(final PantheonNode[] validators) { public static class ProposalsConfig { private final Map proposals = new HashMap<>(); + private final CliqueTransactions clique; + + public ProposalsConfig(final CliqueTransactions clique) { + this.clique = clique; + } public ProposalsConfig addProposal(final PantheonNode node) { proposals.put(node, true); @@ -89,7 +94,7 @@ public Condition build() { .entrySet() .stream() .collect(Collectors.toMap(p -> p.getKey().getAddress(), Entry::getValue)); - return new ExpectProposals(proposalsAsAddress); + return new ExpectProposals(clique, proposalsAsAddress); } } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java index 045bd394c2..d4a0996c9c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java @@ -18,22 +18,21 @@ import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; import java.util.Map; public class ExpectProposals implements Condition { + private final CliqueTransactions clique; private final Map proposers; - public ExpectProposals(final Map proposers) { + public ExpectProposals(final CliqueTransactions clique, final Map proposers) { + this.clique = clique; this.proposers = proposers; } @Override public void verify(final Node node) { - waitFor( - () -> { - final Map result = node.clique().proposals().getResult(); - assertThat(result).isEqualTo(proposers); - }); + waitFor(() -> assertThat(node.execute(clique.proposals())).isEqualTo(proposers)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java index bc9845f4fb..0d577989f0 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java @@ -18,14 +18,16 @@ import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; -import java.util.Optional; +import org.web3j.protocol.core.DefaultBlockParameterName; public class ExpectValidators implements Condition { - + private final CliqueTransactions clique; private final Address[] validators; - public ExpectValidators(final Address... validators) { + public ExpectValidators(final CliqueTransactions clique, final Address... validators) { + this.clique = clique; this.validators = validators; } @@ -33,7 +35,7 @@ public ExpectValidators(final Address... validators) { public void verify(final Node node) { waitFor( () -> - assertThat(node.clique().getSigners(Optional.empty()).getResult()) + assertThat(node.execute(clique.getSigners(DefaultBlockParameterName.LATEST))) .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java index 7436f7ce8c..58c6f1f857 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java @@ -18,14 +18,20 @@ import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; -import java.util.Optional; +import org.web3j.protocol.core.DefaultBlockParameter; public class ExpectValidatorsAtBlock implements Condition { - private final String blockParameter; + private final CliqueTransactions clique; + private final DefaultBlockParameter blockParameter; private final Address[] validators; - public ExpectValidatorsAtBlock(final String blockNumber, final Address... validators) { + public ExpectValidatorsAtBlock( + final CliqueTransactions clique, + final DefaultBlockParameter blockNumber, + final Address... validators) { + this.clique = clique; this.blockParameter = blockNumber; this.validators = validators; } @@ -34,7 +40,7 @@ public ExpectValidatorsAtBlock(final String blockNumber, final Address... valida public void verify(final Node node) { waitFor( () -> - assertThat(node.clique().getSigners(Optional.of(blockParameter)).getResult()) + assertThat(node.execute(clique.getSigners(blockParameter))) .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java index af82bbb637..7a97641386 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java @@ -19,12 +19,16 @@ import tech.pegasys.pantheon.ethereum.core.Hash; 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.CliqueTransactions; public class ExpectValidatorsAtBlockHash implements Condition { + private final CliqueTransactions clique; private final Hash blockHash; private final Address[] validators; - public ExpectValidatorsAtBlockHash(final Hash blockHash, final Address... validators) { + public ExpectValidatorsAtBlockHash( + final CliqueTransactions clique, final Hash blockHash, final Address... validators) { + this.clique = clique; this.blockHash = blockHash; this.validators = validators; } @@ -33,7 +37,7 @@ public ExpectValidatorsAtBlockHash(final Hash blockHash, final Address... valida public void verify(final Node node) { waitFor( () -> - assertThat(node.clique().getSignersAtHash(blockHash).getResult()) + assertThat(node.execute(clique.getSignersAtHash(blockHash))) .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java index bf977825c4..e74e1bcae5 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java @@ -20,6 +20,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueProposals; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliquePropose; +import org.web3j.protocol.core.DefaultBlockParameter; + public class CliqueTransactions { public CliquePropose proposeRemove(final PantheonNode node) { @@ -38,7 +40,7 @@ public CliqueProposals proposals() { return new CliqueProposals(); } - public CliqueGetSigners getSigners(final String blockNumber) { + public CliqueGetSigners getSigners(final DefaultBlockParameter blockNumber) { return new CliqueGetSigners(blockNumber); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java index 387ffa1e70..7737a4e07d 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java @@ -24,6 +24,7 @@ import java.util.concurrent.ScheduledExecutorService; import org.web3j.protocol.Web3jService; +import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.JsonRpc2_0Web3j; import org.web3j.protocol.core.Request; import org.web3j.protocol.core.Response; @@ -58,9 +59,13 @@ public Request cliqueProposals() { return new Request<>("clique_proposals", emptyList(), web3jService, ProposalsResponse.class); } - public Request cliqueGetSigners(final String blockNumber) { + public Request cliqueGetSigners( + final DefaultBlockParameter blockNumber) { return new Request<>( - "clique_getSigners", singletonList(blockNumber), web3jService, SignersBlockResponse.class); + "clique_getSigners", + singletonList(blockNumber.getValue()), + web3jService, + SignersBlockResponse.class); } public Request cliqueGetSignersAtHash(final Hash hash) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java index 0b7ca14f1f..2fa44b249f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java @@ -22,10 +22,12 @@ import java.io.IOException; import java.util.List; +import org.web3j.protocol.core.DefaultBlockParameter; + public class CliqueGetSigners implements Transaction> { - private final String blockNumber; + private final DefaultBlockParameter blockNumber; - public CliqueGetSigners(final String blockNumber) { + public CliqueGetSigners(final DefaultBlockParameter blockNumber) { this.blockNumber = blockNumber; } From e3fd3c918853900d23c2f4a6fa6f11515efd18f8 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 15:14:08 +1000 Subject: [PATCH 23/41] [NC-1524] update clique tests to use clique transactions --- .../clique/CliqueDiscardRpcAcceptanceTest.java | 12 ++++++------ .../clique/CliqueGetSignersRpcTest.java | 12 ++++++------ .../clique/CliqueProposalRpcAcceptanceTest.java | 6 +++--- .../clique/CliqueProposeRpcAcceptanceTest.java | 16 ++++++++-------- .../tests/acceptance/dsl/AcceptanceTestBase.java | 5 ++++- .../dsl/condition/clique/CliqueConditions.java | 4 +--- .../dsl/condition/clique/ExpectValidators.java | 8 ++------ .../clique/ExpectValidatorsAtBlock.java | 8 ++------ .../dsl/transaction/CliqueTransactions.java | 5 ++--- .../dsl/transaction/PantheonWeb3j.java | 9 ++------- .../dsl/transaction/clique/CliqueGetSigners.java | 6 ++---- 11 files changed, 38 insertions(+), 53 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index e066ea1a8a..c38ce225d5 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -34,12 +34,12 @@ public void shouldDiscardVotes() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(); - minerNode1.clique().proposeRemove(minerNode2); - minerNode1.clique().proposeAdd(minerNode3); - minerNode2.clique().proposeRemove(minerNode2); - minerNode2.clique().proposeAdd(minerNode3); - minerNode1.clique().discard(minerNode2); - minerNode1.clique().discard(minerNode3); + minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.proposeRemove(minerNode2)); + minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.discard(minerNode2)); + minerNode1.execute(cliqueTransactions.discard(minerNode3)); minerNode1.waitForChainHeadToProgress(2); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index ad8926fc00..ca68101307 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.tests.acceptance.clique; import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -23,7 +24,6 @@ import org.junit.Test; public class CliqueGetSignersRpcTest extends AcceptanceTestBase { - private PantheonNode minerNode1; private PantheonNode minerNode2; private PantheonNode minerNode3; @@ -41,18 +41,18 @@ public void setUp() throws Exception { @Test public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { - minerNode1.clique().proposeAdd(minerNode3); - minerNode2.clique().proposeAdd(minerNode3); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.waitForChainHeadToProgress(2); cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); - cluster.verify(clique.validatorsAtBlockEqual("latest", allNodes)); + cluster.verify(clique.validatorsAtBlockEqual(LATEST, allNodes)); } @Test public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { - minerNode1.clique().proposeAdd(minerNode3); - minerNode2.clique().proposeAdd(minerNode3); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.waitForChainHeadToProgress(2); // TODO requires DSL changes for this test to work diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index 6c552c8797..e8c3868d0c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -35,9 +35,9 @@ public void shouldReturnProposals() throws IOException { cluster.start(); cluster.verify(clique.noProposals()); - minerNode1.clique().proposeAdd(minerNode3); - minerNode1.clique().proposeRemove(minerNode2); - minerNode2.clique().proposeRemove(minerNode3); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); + minerNode2.execute(cliqueTransactions.proposeRemove(minerNode3)); minerNode1.verify( clique.proposalsEqual().addProposal(minerNode3).removeProposal(minerNode2).build()); minerNode2.verify(clique.proposalsEqual().removeProposal(minerNode3).build()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 1afe73d36f..63c5569e71 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -37,8 +37,8 @@ public void shouldAddValidators() throws IOException { cluster.start(); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); - minerNode1.clique().proposeAdd(minerNode3); - minerNode2.clique().proposeAdd(minerNode3); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -54,8 +54,8 @@ public void shouldRemoveValidators() throws IOException { cluster.start(); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - minerNode1.clique().proposeRemove(minerNode3); - minerNode2.clique().proposeRemove(minerNode3); + minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); + minerNode2.execute(cliqueTransactions.proposeRemove(minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -71,7 +71,7 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { cluster.start(); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); - minerNode1.clique().proposeAdd(minerNode3); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -83,7 +83,7 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.start(); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - minerNode1.clique().proposeRemove(minerNode3); + minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -98,8 +98,8 @@ public void shouldIncludeVoteInBlockHeader() throws IOException { cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); cluster.start(); - minerNode1.clique().proposeAdd(minerNode3); - minerNode1.clique().proposeRemove(minerNode2); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); minerNode1.waitForChainHeadToProgress(1); minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); 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 61d983fcb1..b27c9e10c9 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 @@ -20,6 +20,7 @@ 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.transaction.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.NetTransactions; @@ -34,6 +35,7 @@ public class AcceptanceTestBase { protected final Cluster cluster; protected final JsonRpc jsonRpc; protected final CliqueConditions clique; + protected final CliqueTransactions cliqueTransactions; protected final Transactions transactions; protected final Web3 web3; protected final Eth eth; @@ -46,7 +48,8 @@ protected AcceptanceTestBase() { cluster = new Cluster(); eth = new Eth(ethTransactions); jsonRpc = new JsonRpc(cluster); - clique = new CliqueConditions(ethTransactions, null); + cliqueTransactions = new CliqueTransactions(); + clique = new CliqueConditions(ethTransactions, cliqueTransactions); net = new Net(new NetTransactions()); transactions = new Transactions(accounts); web3 = new Web3(new Web3Transactions()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java index 86f29ffe61..e8823322ff 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -27,7 +27,6 @@ import java.util.stream.Collectors; import com.google.common.collect.ImmutableMap; -import org.web3j.protocol.core.DefaultBlockParameterName; public class CliqueConditions { private final EthTransactions eth; @@ -44,8 +43,7 @@ public ExpectValidators validatorsEqual(final PantheonNode... validators) { public Condition validatorsAtBlockEqual( final String blockNumber, final PantheonNode... validators) { - return new ExpectValidatorsAtBlock( - clique, DefaultBlockParameterName.fromString(blockNumber), validatorAddresses(validators)); + return new ExpectValidatorsAtBlock(clique, blockNumber, validatorAddresses(validators)); } public Condition validatorsAtBlockHashEqual( diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java index 0d577989f0..367db8a26e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java @@ -14,14 +14,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; -import org.web3j.protocol.core.DefaultBlockParameterName; - public class ExpectValidators implements Condition { private final CliqueTransactions clique; private final Address[] validators; @@ -33,9 +32,6 @@ public ExpectValidators(final CliqueTransactions clique, final Address... valida @Override public void verify(final Node node) { - waitFor( - () -> - assertThat(node.execute(clique.getSigners(DefaultBlockParameterName.LATEST))) - .containsExactly(validators)); + waitFor(() -> assertThat(node.execute(clique.getSigners(LATEST))).containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java index 58c6f1f857..8857f036f6 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java @@ -20,17 +20,13 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions; -import org.web3j.protocol.core.DefaultBlockParameter; - public class ExpectValidatorsAtBlock implements Condition { private final CliqueTransactions clique; - private final DefaultBlockParameter blockParameter; + private final String blockParameter; private final Address[] validators; public ExpectValidatorsAtBlock( - final CliqueTransactions clique, - final DefaultBlockParameter blockNumber, - final Address... validators) { + final CliqueTransactions clique, final String blockNumber, final Address... validators) { this.clique = clique; this.blockParameter = blockNumber; this.validators = validators; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java index e74e1bcae5..73e4d86e70 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java @@ -20,9 +20,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueProposals; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliquePropose; -import org.web3j.protocol.core.DefaultBlockParameter; - public class CliqueTransactions { + public static final String LATEST = "latest"; public CliquePropose proposeRemove(final PantheonNode node) { return propose(node.getAddress().toString(), false); @@ -40,7 +39,7 @@ public CliqueProposals proposals() { return new CliqueProposals(); } - public CliqueGetSigners getSigners(final DefaultBlockParameter blockNumber) { + public CliqueGetSigners getSigners(final String blockNumber) { return new CliqueGetSigners(blockNumber); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java index 7737a4e07d..387ffa1e70 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/PantheonWeb3j.java @@ -24,7 +24,6 @@ import java.util.concurrent.ScheduledExecutorService; import org.web3j.protocol.Web3jService; -import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.JsonRpc2_0Web3j; import org.web3j.protocol.core.Request; import org.web3j.protocol.core.Response; @@ -59,13 +58,9 @@ public Request cliqueProposals() { return new Request<>("clique_proposals", emptyList(), web3jService, ProposalsResponse.class); } - public Request cliqueGetSigners( - final DefaultBlockParameter blockNumber) { + public Request cliqueGetSigners(final String blockNumber) { return new Request<>( - "clique_getSigners", - singletonList(blockNumber.getValue()), - web3jService, - SignersBlockResponse.class); + "clique_getSigners", singletonList(blockNumber), web3jService, SignersBlockResponse.class); } public Request cliqueGetSignersAtHash(final Hash hash) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java index 2fa44b249f..0b7ca14f1f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueGetSigners.java @@ -22,12 +22,10 @@ import java.io.IOException; import java.util.List; -import org.web3j.protocol.core.DefaultBlockParameter; - public class CliqueGetSigners implements Transaction> { - private final DefaultBlockParameter blockNumber; + private final String blockNumber; - public CliqueGetSigners(final DefaultBlockParameter blockNumber) { + public CliqueGetSigners(final String blockNumber) { this.blockNumber = blockNumber; } From 138e58e12522ba1ceb76e8b596ead7cb9ad76c77 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 1 Nov 2018 15:19:03 +1000 Subject: [PATCH 24/41] [NC-1524] delete clique node --- .../tests/acceptance/dsl/node/Clique.java | 100 ------------------ .../tests/acceptance/dsl/node/Node.java | 3 - .../acceptance/dsl/node/PantheonNode.java | 10 -- 3 files changed, 113 deletions(-) delete mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java deleted file mode 100644 index 81be017b6e..0000000000 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Clique.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Hash; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.web3j.protocol.Web3jService; -import org.web3j.protocol.core.Request; -import org.web3j.protocol.core.Response; - -public class Clique { - - private final Web3jService web3jService; - - public Clique(final Web3jService web3j) { - this.web3jService = web3j; - } - - public ProposeResponse proposeAdd(final PantheonNode node) throws IOException { - return propose(node, true); - } - - public ProposeResponse proposeRemove(final PantheonNode node) throws IOException { - return propose(node, false); - } - - private ProposeResponse propose(final PantheonNode node, final Boolean auth) throws IOException { - final Request request = - new Request<>( - "clique_propose", - Arrays.asList(node.getAddress().toString(), auth.toString()), - web3jService, - ProposeResponse.class); - return request.send(); - } - - public DiscardResponse discard(final PantheonNode node) throws IOException { - final Request request = - new Request<>( - "clique_discard", - singletonList(node.getAddress().toString()), - web3jService, - DiscardResponse.class); - return request.send(); - } - - public ProposalsResponse proposals() throws IOException { - final Request request = - new Request<>("clique_proposals", emptyList(), web3jService, ProposalsResponse.class); - return request.send(); - } - - public SignersBlockResponse getSigners(final Optional blockNumber) throws IOException { - final Request request = - new Request<>( - "clique_getSigners", - singletonList(blockNumber.map(Object::toString).orElse("latest")), - web3jService, - SignersBlockResponse.class); - return request.send(); - } - - public SignersBlockResponse getSignersAtHash(final Hash hash) throws IOException { - final Request request = - new Request<>( - "clique_getSignersAtHash", - singletonList(hash.toString()), - web3jService, - SignersBlockResponse.class); - return request.send(); - } - - public static class ProposeResponse extends Response {} - - public static class DiscardResponse extends Response {} - - public static class SignersBlockResponse extends Response> {} - - public static class ProposalsResponse extends Response> {} -} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java index 2c57e68e51..9a94b47cb5 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java @@ -15,8 +15,5 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; public interface Node { - T execute(Transaction transaction); - - Clique clique(); } 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 64a2e816e8..c3980ce968 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 @@ -70,7 +70,6 @@ public class PantheonNode implements Node, AutoCloseable { private List bootnodes = new ArrayList<>(); private Eth eth; - private Clique clique; private Web3j web3j; private PantheonWeb3j pantheonWeb3j; private Optional ethNetworkConfig = Optional.empty(); @@ -319,15 +318,6 @@ public void close() { } } - @Override - public Clique clique() { - if (clique == null) { - clique = new Clique(new HttpService(jsonRpcBaseUrl().get())); - } - - return clique; - } - public Function, Optional> getGenesisConfig() { return genesisConfig; } From 11ca4498184670c2020a45ed9159edf332789d60 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Sat, 3 Nov 2018 10:08:55 +0100 Subject: [PATCH 25/41] [NC-1524] wait condition --- .../CliqueDiscardRpcAcceptanceTest.java | 2 +- .../clique/CliqueGetSignersRpcTest.java | 8 ++++---- .../CliqueProposeRpcAcceptanceTest.java | 4 ++-- .../acceptance/dsl/AcceptanceTestBase.java | 3 +++ .../acceptance/dsl/node/PantheonNode.java | 6 ++++-- .../dsl/waitcondition/WaitCondition.java | 8 ++++++++ .../dsl/waitcondition/WaitConditions.java | 20 +++++++++++++++++++ 7 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index c38ce225d5..f51fd732a7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -41,7 +41,7 @@ public void shouldDiscardVotes() throws IOException { minerNode1.execute(cliqueTransactions.discard(minerNode2)); minerNode1.execute(cliqueTransactions.discard(minerNode3)); - minerNode1.waitForChainHeadToProgress(2); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.verify(clique.noProposals()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index ca68101307..0ef217f86e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -43,7 +43,7 @@ public void setUp() throws Exception { public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode1.waitForChainHeadToProgress(2); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1,2)); cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); cluster.verify(clique.validatorsAtBlockEqual(LATEST, allNodes)); @@ -53,9 +53,9 @@ public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode1.waitForChainHeadToProgress(2); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); - // TODO requires DSL changes for this test to work - // cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); + // TODO add support for latest block hash +// cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 63c5569e71..1d5667081a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -101,11 +101,11 @@ public void shouldIncludeVoteInBlockHeader() throws IOException { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); - minerNode1.waitForChainHeadToProgress(1); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); - minerNode1.waitForChainHeadToProgress(1); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode2)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); } 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 b27c9e10c9..0d2e2a34e0 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 @@ -27,6 +27,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.web3.Web3Transactions; import org.junit.After; +import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitConditions; public class AcceptanceTestBase { @@ -40,6 +41,7 @@ public class AcceptanceTestBase { protected final Web3 web3; protected final Eth eth; protected final Net net; + protected final WaitConditions wait; protected AcceptanceTestBase() { final EthTransactions ethTransactions = new EthTransactions(); @@ -53,6 +55,7 @@ protected AcceptanceTestBase() { net = new Net(new NetTransactions()); transactions = new Transactions(accounts); web3 = new Web3(new Web3Transactions()); + wait = new WaitConditions(ethTransactions); } @After 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 c3980ce968..b148fa2fd5 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 @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.node; import static org.apache.logging.log4j.LogManager.getLogger; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.controller.KeyPairUtil; @@ -49,6 +50,7 @@ import org.web3j.protocol.http.HttpService; import org.web3j.protocol.websocket.WebSocketService; import org.web3j.utils.Async; +import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition; public class PantheonNode implements Node, AutoCloseable { @@ -339,7 +341,7 @@ public void verify(final Condition expected) { expected.verify(this); } - public void waitForChainHeadToProgress(final int blocksAheadOfLatest) { - // TODO requires DSL changes for this to work + public void waitUntil(final WaitCondition expected) { + waitFor(() -> expected.verify(this)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java new file mode 100644 index 0000000000..35a3b7d83d --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java @@ -0,0 +1,8 @@ +package tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition; + +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; + +@FunctionalInterface +public interface WaitCondition { + void verify(Node node); +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java new file mode 100644 index 0000000000..6ff511a80f --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -0,0 +1,20 @@ +package tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition; + +import java.math.BigInteger; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNumber; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; + +public class WaitConditions { + private EthTransactions eth; + + public WaitConditions(final EthTransactions eth) { + this.eth = eth; + } + + public WaitCondition chainHeadHasProgressed(final PantheonNode node, final int blocksAheadOfLatest) { + final BigInteger futureBlock = + node.execute(eth.blockNumber()).add(BigInteger.valueOf(blocksAheadOfLatest)); + return new ExpectBlockNumber(eth, futureBlock)::verify; + } +} From 40bd5bd6111a7d03df6156c63e3e68488de7af81 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Tue, 20 Nov 2018 11:15:49 +1000 Subject: [PATCH 26/41] [NC-1524] refactor clique tests after acceptance test framework changes --- .../CliqueDiscardRpcAcceptanceTest.java | 10 +- .../clique/CliqueGetSignersRpcTest.java | 13 +-- .../clique/CliqueMiningAcceptanceTest.java | 22 ++-- .../CliqueProposalRpcAcceptanceTest.java | 10 +- .../CliqueProposeRpcAcceptanceTest.java | 43 ++++--- .../acceptance/dsl/AcceptanceTestBase.java | 4 +- .../tests/acceptance/dsl/node/Cluster.java | 8 +- .../dsl/node/GenesisConfigProvider.java | 21 ++++ .../dsl/node/NodeConfiguration.java | 8 ++ .../acceptance/dsl/node/PantheonNode.java | 42 +++---- .../dsl/node/PantheonNodeFactory.java | 109 +++++++++++++++++- .../dsl/node/ProcessPantheonNodeRunner.java | 4 +- .../acceptance/dsl/node/RunnableNode.java | 3 + .../dsl/node/ThreadPantheonNodeRunner.java | 4 +- .../net/NetPeerCountTransaction.java | 4 +- .../dsl/waitcondition/WaitCondition.java | 12 ++ .../dsl/waitcondition/WaitConditions.java | 20 +++- 17 files changed, 238 insertions(+), 99 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/GenesisConfigProvider.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index f51fd732a7..562162ea33 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -12,8 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; - import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -27,12 +25,12 @@ public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBase { public void shouldDiscardVotes() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(); + pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + cluster.start(minerNode1, minerNode2, minerNode3); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index 0ef217f86e..636d7cd903 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -12,7 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; @@ -32,18 +31,18 @@ public class CliqueGetSignersRpcTest extends AcceptanceTestBase { @Before public void setUp() throws Exception { final String[] validators = {"miner1", "miner2"}; - minerNode1 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", validators)); - minerNode2 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", validators)); - minerNode3 = cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", validators)); + minerNode1 = pantheon.createCliqueMinerNodeWithValidators("miner1", validators); + minerNode2 = pantheon.createCliqueMinerNodeWithValidators("miner2", validators); + minerNode3 = pantheon.createCliqueMinerNodeWithValidators("miner3", validators); allNodes = new PantheonNode[] {minerNode1, minerNode2, minerNode3}; - cluster.start(); + cluster.start(allNodes); } @Test public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1,2)); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); cluster.verify(clique.validatorsAtBlockEqual(LATEST, allNodes)); @@ -56,6 +55,6 @@ public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); // TODO add support for latest block hash -// cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); + // cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index ae81351a4d..46174e2cae 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -12,8 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; - import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; @@ -27,8 +25,8 @@ public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { @Test public void shouldMineTransactionsOnSingleNode() throws IOException { - final PantheonNode minerNode = cluster.create(pantheonCliqueMinerNode("miner1")); - cluster.start(); + final PantheonNode minerNode = pantheon.createMinerNode("miner1"); + cluster.start(minerNode); final Account sender = accounts.createAccount("account1"); final Account receiver = accounts.createAccount("account2"); @@ -45,10 +43,10 @@ public void shouldMineTransactionsOnSingleNode() throws IOException { @Test public void shouldMineTransactionsOnMultipleNodes() throws IOException { - final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); - final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - cluster.start(); + final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); + final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); + final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); + cluster.start(minerNode1, minerNode2, minerNode3); final Account sender = accounts.createAccount("account1"); final Account receiver = accounts.createAccount("account2"); @@ -66,10 +64,10 @@ public void shouldMineTransactionsOnMultipleNodes() throws IOException { @Test public void shouldStallMiningWhenInsufficientValidators() throws IOException, InterruptedException { - final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); - final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - cluster.start(); + final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); + final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); + final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); + cluster.start(minerNode1, minerNode2, minerNode3); cluster.stopNode(minerNode2); cluster.stopNode(minerNode3); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index e8c3868d0c..d01c2705c1 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -12,8 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; - import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -27,12 +25,12 @@ public class CliqueProposalRpcAcceptanceTest extends AcceptanceTestBase { public void shouldReturnProposals() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(); + pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.noProposals()); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 1d5667081a..b2ea4b137a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -12,9 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNode; -import static tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeConfig.pantheonCliqueMinerNodeWithValidators; - import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -29,12 +26,12 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { public void shouldAddValidators() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(); + pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); @@ -46,12 +43,12 @@ public void shouldAddValidators() throws IOException { public void shouldRemoveValidators() throws IOException { final String[] initialValidators = {"miner1", "miner2", "miner3"}; final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(); + pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); @@ -63,12 +60,12 @@ public void shouldRemoveValidators() throws IOException { public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(); + pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); @@ -77,10 +74,10 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { @Test public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { - final PantheonNode minerNode1 = cluster.create(pantheonCliqueMinerNode("miner1")); - final PantheonNode minerNode2 = cluster.create(pantheonCliqueMinerNode("miner2")); - final PantheonNode minerNode3 = cluster.create(pantheonCliqueMinerNode("miner3")); - cluster.start(); + final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); + final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); + final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); + cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); @@ -91,12 +88,12 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { public void shouldIncludeVoteInBlockHeader() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner1", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner2", initialValidators)); + pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - cluster.create(pantheonCliqueMinerNodeWithValidators("miner3", initialValidators)); - cluster.start(); + pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + cluster.start(minerNode1, minerNode2, minerNode3); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); 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 529380b639..b03a9a1f33 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 @@ -19,15 +19,15 @@ 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.transaction.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNodeFactory; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.NetTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.web3.Web3Transactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitConditions; import org.junit.After; -import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitConditions; public class AcceptanceTestBase { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index 0039b19e6c..d0e037cd6c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -15,7 +15,6 @@ import static org.assertj.core.api.Assertions.assertThat; import tech.pegasys.pantheon.cli.EthNetworkConfig; -import tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Net; @@ -23,8 +22,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; -import java.util.Optional; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; public class Cluster implements AutoCloseable { @@ -62,8 +61,9 @@ public void start(final List nodes) { for (final RunnableNode node : nodes) { node.getConfiguration().bootnodes(bootNodes); Optional ethNetworkConfig = - node.getConfiguration().genesisConfig() - .apply(nodes) + node.getConfiguration() + .genesisConfigProvider() + .createGenesisConfig(nodes) .map(config -> new EthNetworkConfig(config, NETWORK_ID, bootNodes)); node.getConfiguration().ethNetworkConfig(ethNetworkConfig); node.start(pantheonNodeRunner); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/GenesisConfigProvider.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/GenesisConfigProvider.java new file mode 100644 index 0000000000..c4790045a8 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/GenesisConfigProvider.java @@ -0,0 +1,21 @@ +/* + * 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; + +import java.util.List; +import java.util.Optional; + +@FunctionalInterface +public interface GenesisConfigProvider { + Optional createGenesisConfig(final List validators); +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/NodeConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/NodeConfiguration.java index 08349095a4..bde4baf19c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/NodeConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/NodeConfiguration.java @@ -12,6 +12,8 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import tech.pegasys.pantheon.cli.EthNetworkConfig; + import java.util.List; import java.util.Optional; @@ -28,4 +30,10 @@ public interface NodeConfiguration { String hostName(); boolean jsonRpcEnabled(); + + GenesisConfigProvider genesisConfigProvider(); + + Optional ethNetworkConfig(); + + void ethNetworkConfig(Optional ethNetworkConfig); } 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 e590f3c0c1..a30bbe5946 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 @@ -27,6 +27,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition; import java.io.File; import java.io.FileInputStream; @@ -34,11 +35,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.Properties; -import java.util.function.Function; import java.util.stream.Collectors; import com.google.common.base.MoreObjects; @@ -50,7 +49,6 @@ import org.web3j.protocol.http.HttpService; import org.web3j.protocol.websocket.WebSocketService; import org.web3j.utils.Async; -import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition; public class PantheonNode implements Node, NodeConfiguration, RunnableNode, AutoCloseable { @@ -66,10 +64,7 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto private final MiningParameters miningParameters; private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; - private final boolean jsonRpcEnabled; - private final boolean wsRpcEnabled; - private final Properties portsProperties = new Properties(); - private final Function, Optional> genesisConfig; + private final GenesisConfigProvider genesisConfigProvider; private final boolean devMode; private List bootnodes = new ArrayList<>(); @@ -84,8 +79,7 @@ public PantheonNode( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final boolean devMode, - final Function, Optional> genesisConfig) - final WebSocketConfiguration webSocketConfiguration, + final GenesisConfigProvider genesisConfigProvider, final int p2pPort) throws IOException { this.homeDirectory = Files.createTempDirectory("acctest"); @@ -95,9 +89,7 @@ public PantheonNode( this.miningParameters = miningParameters; this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; - this.jsonRpcEnabled = jsonRpcConfiguration.isEnabled(); - this.wsRpcEnabled = webSocketConfiguration.isEnabled(); - this.genesisConfig = genesisConfig; + this.genesisConfigProvider = genesisConfigProvider; this.devMode = devMode; LOG.info("Created PantheonNode {}", this.toString()); } @@ -162,7 +154,7 @@ public Web3j web3j() { } if (web3j == null) { - return web3j(web3jService()); + return web3j(new HttpService(jsonRpcBaseUrl().get())); } return web3j; @@ -224,14 +216,6 @@ private Web3jService web3jService() { return new HttpService(jsonRpcBaseUrl().get()); } - public int getPeerCount() { - try { - return web3j().netPeerCount().send().getQuantity().intValueExact(); - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - @Override public void start(final PantheonNodeRunner runner) { runner.startNode(this); @@ -259,6 +243,7 @@ private void loadPortsFile() { } } + @Override public Address getAddress() { return Util.publicKeyToAddress(keyPair.getPublicKey()); } @@ -353,16 +338,19 @@ public void close() { } } - public Function, Optional> getGenesisConfig() { - return genesisConfig; + @Override + public GenesisConfigProvider genesisConfigProvider() { + return genesisConfigProvider; } - public void setEthNetworkConfig(final Optional ethNetworkConfig) { - this.ethNetworkConfig = ethNetworkConfig; + @Override + public Optional ethNetworkConfig() { + return ethNetworkConfig; } - public Optional getEthNetworkConfig() { - return ethNetworkConfig; + @Override + public void ethNetworkConfig(final Optional ethNetworkConfig) { + this.ethNetworkConfig = ethNetworkConfig; } @Override diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java index e2d09e633f..e455f41fb2 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java @@ -12,6 +12,12 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static tech.pegasys.pantheon.consensus.clique.jsonrpc.CliqueRpcApis.CLIQUE; + +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; @@ -20,7 +26,15 @@ import java.io.IOException; import java.net.ServerSocket; -import java.util.Arrays; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import com.google.common.io.Resources; public class PantheonNodeFactory { @@ -32,6 +46,8 @@ private PantheonNode create(final PantheonFactoryConfiguration config) throws IO config.getMiningParameters(), config.getJsonRpcConfiguration(), config.getWebSocketConfiguration(), + config.isDevMode(), + config.getGenesisConfigProvider(), serverSocket.getLocalPort()); serverSocket.close(); @@ -62,15 +78,74 @@ public PantheonNode createArchiveNodeWithRpcDisabled(final String name) throws I public PantheonNode createArchiveNodeWithRpcApis( final String name, final RpcApi... enabledRpcApis) throws IOException { final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); - jsonRpcConfig.setRpcApis(Arrays.asList(enabledRpcApis)); + jsonRpcConfig.setRpcApis(asList(enabledRpcApis)); final WebSocketConfiguration webSocketConfig = createWebSocketConfig(); - webSocketConfig.setRpcApis(Arrays.asList(enabledRpcApis)); + webSocketConfig.setRpcApis(asList(enabledRpcApis)); return create( new PantheonFactoryConfiguration( name, createMiningParameters(false), jsonRpcConfig, webSocketConfig)); } + public PantheonNode createCliqueMinerNode(final String name) throws IOException { + return create( + new PantheonFactoryConfiguration( + name, + createMiningParameters(true), + jsonRpcConfigWithClique(), + createWebSocketConfig(), + false, + this::createCliqueGenesisConfig)); + } + + public PantheonNode createCliqueMinerNodeWithValidators( + final String name, final String... validators) throws IOException { + return create( + new PantheonFactoryConfiguration( + name, + createMiningParameters(true), + jsonRpcConfigWithClique(), + createWebSocketConfig(), + false, + nodes -> createCliqueGenesisConfigForValidators(asList(validators), nodes))); + } + + private Optional createCliqueGenesisConfig(final Collection validators) { + String genesisTemplate = cliqueGenesisTemplateConfig(); + String cliqueExtraData = encodeCliqueExtraData(validators); + String genesis = genesisTemplate.replaceAll("%cliqueExtraData%", cliqueExtraData); + return Optional.of(genesis); + } + + private Optional createCliqueGenesisConfigForValidators( + final Collection validators, final Collection pantheonNodes) { + List collect = + pantheonNodes.stream().filter(n -> validators.contains(n.getName())).collect(toList()); + return createCliqueGenesisConfig(collect); + } + + private String cliqueGenesisTemplateConfig() { + try { + URI uri = Resources.getResource("clique/clique.json").toURI(); + return Resources.toString(uri.toURL(), Charset.defaultCharset()); + } catch (URISyntaxException | IOException e) { + throw new IllegalStateException("Unable to get test clique genesis config"); + } + } + + private String encodeCliqueExtraData(final Collection nodes) { + final List
addresses = nodes.stream().map(RunnableNode::getAddress).collect(toList()); + return CliqueExtraData.createGenesisExtraDataString(addresses); + } + + private JsonRpcConfiguration jsonRpcConfigWithClique() { + final JsonRpcConfiguration jsonRpcConfig = createJsonRpcConfig(); + final List 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(); } @@ -95,16 +170,36 @@ static class PantheonFactoryConfiguration { 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, + false, + 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() { @@ -122,5 +217,13 @@ public JsonRpcConfiguration getJsonRpcConfiguration() { public WebSocketConfiguration getWebSocketConfiguration() { return webSocketConfiguration; } + + public boolean isDevMode() { + return devMode; + } + + public GenesisConfigProvider getGenesisConfigProvider() { + return genesisConfigProvider; + } } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index 37ca9f4b32..4ce358f584 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -85,8 +85,8 @@ public void startNode(final PantheonNode node) { params.add(apiList(node.webSocketConfiguration().getRpcApis())); } - if (node.getEthNetworkConfig().isPresent()) { - EthNetworkConfig ethNetworkConfig = node.getEthNetworkConfig().get(); + if (node.ethNetworkConfig().isPresent()) { + EthNetworkConfig ethNetworkConfig = node.ethNetworkConfig().get(); Path genesisFile = createGenesisFile(node, ethNetworkConfig); params.add("--genesis"); params.add(genesisFile.toString()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/RunnableNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/RunnableNode.java index 5cbc239ca3..0b0cf8f701 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/RunnableNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/RunnableNode.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.node; +import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; public interface RunnableNode extends Node { @@ -27,4 +28,6 @@ public interface RunnableNode extends Node { void awaitPeerDiscovery(final Condition condition); String getName(); + + Address getAddress(); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index e4578ef9df..5531431674 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -51,7 +51,7 @@ public void startNode(final PantheonNode node) { final PantheonControllerBuilder builder = new PantheonControllerBuilder(); final EthNetworkConfig ethNetworkConfig = - node.getEthNetworkConfig() + node.ethNetworkConfig() .orElse(new EthNetworkConfig.Builder(mainnet()).setNetworkId(NETWORK_ID).build()); PantheonController pantheonController; try { @@ -62,7 +62,7 @@ public void startNode(final PantheonNode node) { ethNetworkConfig, false, node.getMiningParameters(), - true, + node.isDevMode(), KeyPairUtil.getDefaultKeyFile(node.homeDirectory())); } catch (final IOException e) { throw new RuntimeException("Error building PantheonController", e); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetPeerCountTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetPeerCountTransaction.java index 01902ba581..e52e2f4f1e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetPeerCountTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/net/NetPeerCountTransaction.java @@ -14,12 +14,12 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; import java.math.BigInteger; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.NetPeerCount; public class NetPeerCountTransaction implements Transaction { @@ -27,7 +27,7 @@ public class NetPeerCountTransaction implements Transaction { NetPeerCountTransaction() {} @Override - public BigInteger execute(final Web3j node) { + public BigInteger execute(final PantheonWeb3j node) { try { final NetPeerCount result = node.netPeerCount().send(); assertThat(result).isNotNull(); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java index 35a3b7d83d..28f908a8f7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java @@ -1,3 +1,15 @@ +/* + * 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.waitcondition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java index 6ff511a80f..ca981ca567 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -1,18 +1,32 @@ +/* + * 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.waitcondition; -import java.math.BigInteger; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; +import java.math.BigInteger; + public class WaitConditions { - private EthTransactions eth; + private final EthTransactions eth; public WaitConditions(final EthTransactions eth) { this.eth = eth; } - public WaitCondition chainHeadHasProgressed(final PantheonNode node, final int blocksAheadOfLatest) { + public WaitCondition chainHeadHasProgressed( + final PantheonNode node, final int blocksAheadOfLatest) { final BigInteger futureBlock = node.execute(eth.blockNumber()).add(BigInteger.valueOf(blocksAheadOfLatest)); return new ExpectBlockNumber(eth, futureBlock)::verify; From 853c403d2a61fadb41b647821434160ee89cf00c Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 21 Nov 2018 11:33:08 +1000 Subject: [PATCH 27/41] [NC-1524] improve clique test stability by adding wait conditions --- .../CliqueDiscardRpcAcceptanceTest.java | 4 +- .../clique/CliqueGetSignersRpcTest.java | 9 ++--- .../clique/CliqueMiningAcceptanceTest.java | 2 +- .../CliqueProposalRpcAcceptanceTest.java | 1 + .../CliqueProposeRpcAcceptanceTest.java | 10 ++++- .../acceptance/dsl/AcceptanceTestBase.java | 2 +- .../tests/acceptance/dsl/WaitUtils.java | 7 ++++ .../acceptance/dsl/blockchain/Blockchain.java | 7 ---- .../condition/clique/CliqueConditions.java | 15 +++++-- .../tests/acceptance/dsl/node/Cluster.java | 7 ++++ .../tests/acceptance/dsl/node/Node.java | 3 ++ .../acceptance/dsl/node/PantheonNode.java | 3 +- .../dsl/transaction/eth/EthTransactions.java | 7 +++- .../dsl/waitcondition/WaitCondition.java | 2 +- .../dsl/waitcondition/WaitConditions.java | 12 +++++- .../WaitUntilSignersChanged.java | 40 +++++++++++++++++++ 16 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index 562162ea33..c78d130d23 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -33,13 +33,13 @@ public void shouldDiscardVotes() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeRemove(minerNode2)); + minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.execute(cliqueTransactions.discard(minerNode2)); minerNode1.execute(cliqueTransactions.discard(minerNode3)); - minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.verify(clique.noProposals()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index 636d7cd903..8100c39a62 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -17,8 +17,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; -import java.io.IOException; - import org.junit.Before; import org.junit.Test; @@ -39,7 +37,7 @@ public void setUp() throws Exception { } @Test - public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { + public void shouldBeAbleToGetValidatorsForBlockNumber() { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); @@ -49,12 +47,11 @@ public void shouldBeAbleToGetValidatorsForBlockNumber() throws IOException { } @Test - public void shouldBeAbleToGetValidatorsForBlockHash() throws IOException { + public void shouldBeAbleToGetValidatorsForBlockHash() { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); - // TODO add support for latest block hash - // cluster.verify(clique.validatorsAtBlockHashEqual(latestBlockHash, allNodes)); + cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 3, allNodes)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 46174e2cae..eeed68f29e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -25,7 +25,7 @@ public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { @Test public void shouldMineTransactionsOnSingleNode() throws IOException { - final PantheonNode minerNode = pantheon.createMinerNode("miner1"); + final PantheonNode minerNode = pantheon.createCliqueMinerNode("miner1"); cluster.start(minerNode); final Account sender = accounts.createAccount("account1"); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index d01c2705c1..ae01b55d49 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -36,6 +36,7 @@ public void shouldReturnProposals() throws IOException { minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); minerNode2.execute(cliqueTransactions.proposeRemove(minerNode3)); + minerNode1.verify( clique.proposalsEqual().addProposal(minerNode3).removeProposal(minerNode2).build()); minerNode2.verify(clique.proposalsEqual().removeProposal(minerNode3).build()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index b2ea4b137a..56675559bf 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -15,6 +15,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; +import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition; import java.io.IOException; @@ -34,8 +35,10 @@ public void shouldAddValidators() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); + final WaitCondition cliqueValidatorsChanged = wait.cliqueValidatorsChanged(minerNode1); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); + cluster.waitUntil(cliqueValidatorsChanged); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -51,8 +54,10 @@ public void shouldRemoveValidators() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); + final WaitCondition cliqueValidatorsChanged = wait.cliqueValidatorsChanged(minerNode1); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); minerNode2.execute(cliqueTransactions.proposeRemove(minerNode3)); + cluster.waitUntil(cliqueValidatorsChanged); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -69,6 +74,7 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -81,6 +87,7 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -96,12 +103,11 @@ public void shouldIncludeVoteInBlockHeader() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); - minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); + minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode2)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); 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 b03a9a1f33..12e8b79d9c 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 @@ -55,7 +55,7 @@ protected AcceptanceTestBase() { transactions = new Transactions(accounts); web3 = new Web3(new Web3Transactions()); pantheon = new PantheonNodeFactory(); - wait = new WaitConditions(ethTransactions); + wait = new WaitConditions(ethTransactions, cliqueTransactions); } @After diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/WaitUtils.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/WaitUtils.java index 88320fb49f..235553adee 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/WaitUtils.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/WaitUtils.java @@ -21,4 +21,11 @@ public class WaitUtils { public static void waitFor(final ThrowingRunnable condition) { Awaitility.await().ignoreExceptions().atMost(30, TimeUnit.SECONDS).untilAsserted(condition); } + + public static void waitFor(final int timeout, final ThrowingRunnable condition) { + Awaitility.await() + .ignoreExceptions() + .atMost(timeout, TimeUnit.SECONDS) + .untilAsserted(condition); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java index 13f1ffd308..d54b3ff52b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java @@ -14,14 +14,11 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBeneficiary; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectMinimumBlockNumber; 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.transaction.eth.EthTransactions; -import java.math.BigInteger; - public class Blockchain { private final EthTransactions eth; @@ -37,8 +34,4 @@ public Condition blockNumberMustBeLatest(final Node node) { public Condition beneficiaryEquals(final PantheonNode node) { return new ExpectBeneficiary(eth, node); } - - public Condition blockNumberEquals(final BigInteger blockNumber) { - return new ExpectBlockNumber(eth, blockNumber); - } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java index e8823322ff..35cc00658b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -12,14 +12,17 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; +import static tech.pegasys.pantheon.ethereum.core.Hash.fromHexString; + import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; +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.transaction.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; +import java.math.BigInteger; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -27,6 +30,7 @@ import java.util.stream.Collectors; import com.google.common.collect.ImmutableMap; +import org.web3j.protocol.core.DefaultBlockParameter; public class CliqueConditions { private final EthTransactions eth; @@ -46,10 +50,13 @@ public Condition validatorsAtBlockEqual( return new ExpectValidatorsAtBlock(clique, blockNumber, validatorAddresses(validators)); } - public Condition validatorsAtBlockHashEqual( - final String blockHash, final PantheonNode... validators) { + public Condition validatorsAtBlockHashFromBlockNumberEqual( + final Node node, final long blockNumber, final PantheonNode... validators) { + final DefaultBlockParameter blockParameter = + DefaultBlockParameter.valueOf(BigInteger.valueOf(blockNumber)); + final String blockHash = node.execute(eth.block(blockParameter)).getHash(); return new ExpectValidatorsAtBlockHash( - clique, Hash.fromHexString(blockHash), validatorAddresses(validators)); + clique, fromHexString(blockHash), validatorAddresses(validators)); } public ProposalsConfig proposalsEqual() { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java index d0e037cd6c..26e3db8a62 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Cluster.java @@ -17,6 +17,7 @@ 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.waitcondition.WaitCondition; import java.util.ArrayList; import java.util.Arrays; @@ -98,4 +99,10 @@ public void verify(final Condition expected) { expected.verify(node); } } + + public void waitUntil(final WaitCondition condition) { + for (final Node node : nodes.values()) { + node.waitUntil(condition); + } + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java index d16e475153..414cac9328 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/Node.java @@ -14,9 +14,12 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; +import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition; public interface Node { T execute(Transaction transaction); void verify(final Condition expected); + + void waitUntil(final WaitCondition condition); } 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 a30bbe5946..aedf64f571 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 @@ -13,7 +13,6 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.node; import static org.apache.logging.log4j.LogManager.getLogger; -import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.controller.KeyPairUtil; @@ -364,6 +363,6 @@ public void verify(final Condition expected) { } public void waitUntil(final WaitCondition expected) { - waitFor(() -> expected.verify(this)); + expected.waitUntil(this); } } 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 dc29f5dbe8..d0f502f2fd 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 @@ -14,6 +14,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; +import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; public class EthTransactions { @@ -27,7 +28,11 @@ public EthBlockNumberTransaction blockNumber() { } public EthGetBlockTransaction block() { - return new EthGetBlockTransaction(DefaultBlockParameterName.LATEST, false); + return block(DefaultBlockParameterName.LATEST); + } + + public EthGetBlockTransaction block(final DefaultBlockParameter blockParameter) { + return new EthGetBlockTransaction(blockParameter, false); } public EthGetBalanceTransaction getBalance(final Account account) { diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java index 28f908a8f7..33ed8b322c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitCondition.java @@ -16,5 +16,5 @@ @FunctionalInterface public interface WaitCondition { - void verify(Node node); + void waitUntil(Node node); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java index ca981ca567..a222b2f44c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -12,17 +12,23 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; + import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNumber; +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.transaction.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.math.BigInteger; public class WaitConditions { private final EthTransactions eth; + private CliqueTransactions clique; - public WaitConditions(final EthTransactions eth) { + public WaitConditions(final EthTransactions eth, final CliqueTransactions clique) { this.eth = eth; + this.clique = clique; } public WaitCondition chainHeadHasProgressed( @@ -31,4 +37,8 @@ public WaitCondition chainHeadHasProgressed( node.execute(eth.blockNumber()).add(BigInteger.valueOf(blocksAheadOfLatest)); return new ExpectBlockNumber(eth, futureBlock)::verify; } + + public WaitCondition cliqueValidatorsChanged(final Node node) { + return new WaitUntilSignersChanged(node.execute(clique.getSigners(LATEST)), clique); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java new file mode 100644 index 0000000000..f4a13694a1 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java @@ -0,0 +1,40 @@ +/* + * 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.waitcondition; + +import static org.assertj.core.api.Assertions.assertThat; +import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions; + +import java.util.List; + +public class WaitUntilSignersChanged implements WaitCondition { + private final CliqueTransactions clique; + private final List
initialSigners; + + public WaitUntilSignersChanged( + final List
initialSigners, final CliqueTransactions clique) { + this.initialSigners = initialSigners; + this.clique = clique; + } + + @Override + public void waitUntil(final Node node) { + waitFor( + 60, () -> assertThat(node.execute(clique.getSigners(LATEST))).isNotEqualTo(initialSigners)); + } +} From ab015417d3ee535b323512ce4eece06d7a3e9815 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 21 Nov 2018 11:52:14 +1000 Subject: [PATCH 28/41] [NC-1524] fix merge issues --- .../pantheon/tests/acceptance/dsl/node/PantheonNode.java | 1 + .../dsl/transaction/DeploySmartContractTransaction.java | 2 +- .../transaction/eth/EthGetTransactionReceiptTransaction.java | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) 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 f49e5b27cb..89b7e02942 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 @@ -44,6 +44,7 @@ import com.google.common.io.RecursiveDeleteOption; import org.apache.logging.log4j.Logger; import org.web3j.protocol.Web3j; +import org.web3j.protocol.Web3jService; import org.web3j.protocol.http.HttpService; import org.web3j.protocol.websocket.WebSocketService; import org.web3j.utils.Async; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/DeploySmartContractTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/DeploySmartContractTransaction.java index c033fff97a..55ef493902 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/DeploySmartContractTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/DeploySmartContractTransaction.java @@ -35,7 +35,7 @@ public DeploySmartContractTransaction(final Class clazz) { } @Override - public T execute(final Web3j node) { + public T execute(final PantheonWeb3j node) { try { final Method method = clazz.getMethod( diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptTransaction.java index 085f02ba93..2784ce1991 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthGetTransactionReceiptTransaction.java @@ -14,12 +14,12 @@ import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import java.io.IOException; import java.util.Optional; -import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; import org.web3j.protocol.core.methods.response.TransactionReceipt; @@ -33,7 +33,7 @@ public class EthGetTransactionReceiptTransaction } @Override - public Optional execute(final Web3j node) { + public Optional execute(final PantheonWeb3j node) { try { final EthGetTransactionReceipt result = node.ethGetTransactionReceipt(input).send(); assertThat(result.hasError()).isFalse(); From cd3451f0f01d56c6efcc04ec18f409ded2b132d7 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 21 Nov 2018 12:11:41 +1000 Subject: [PATCH 29/41] [NC-1524] spotless warnings --- .../pantheon/tests/acceptance/dsl/node/PantheonNode.java | 1 + .../tests/acceptance/dsl/waitcondition/WaitConditions.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) 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 89b7e02942..517f16619b 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 @@ -347,6 +347,7 @@ public void verify(final Condition expected) { expected.verify(this); } + @Override public void waitUntil(final WaitCondition expected) { expected.waitUntil(this); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java index a222b2f44c..26236eca79 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -24,7 +24,7 @@ public class WaitConditions { private final EthTransactions eth; - private CliqueTransactions clique; + private final CliqueTransactions clique; public WaitConditions(final EthTransactions eth, final CliqueTransactions clique) { this.eth = eth; From 5273625bfa4855949bbb467a1780075b2b543917 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 22 Nov 2018 15:03:44 +1000 Subject: [PATCH 30/41] [NC-1524] code review changes --- .../tests/acceptance/clique/CliqueGetSignersRpcTest.java | 2 +- .../pantheon/tests/acceptance/dsl/AcceptanceTestBase.java | 2 +- .../dsl/condition/blockchain/ExpectBeneficiary.java | 5 ++--- .../dsl/condition/blockchain/ExpectBlockNumber.java | 5 ++--- .../acceptance/dsl/condition/clique/CliqueConditions.java | 2 +- .../acceptance/dsl/condition/clique/ExpectProposals.java | 2 +- .../acceptance/dsl/condition/clique/ExpectValidators.java | 4 ++-- .../dsl/condition/clique/ExpectValidatorsAtBlock.java | 2 +- .../dsl/condition/clique/ExpectValidatorsAtBlockHash.java | 2 +- .../dsl/transaction/{ => clique}/CliqueTransactions.java | 4 ++-- .../tests/acceptance/dsl/waitcondition/WaitConditions.java | 4 ++-- .../dsl/waitcondition/WaitUntilSignersChanged.java | 4 ++-- 12 files changed, 18 insertions(+), 20 deletions(-) rename acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/{ => clique}/CliqueTransactions.java (93%) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index 8100c39a62..e0973136c3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -12,7 +12,7 @@ */ package tech.pegasys.pantheon.tests.acceptance.clique; -import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; 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 12e8b79d9c..e1bb27dbaf 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 @@ -20,7 +20,7 @@ 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.transaction.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.NetTransactions; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java index ae0dc16727..15a125f126 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBeneficiary.java @@ -21,9 +21,8 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; public class ExpectBeneficiary implements Condition { - - private EthTransactions eth; - private String beneficiary; + private final EthTransactions eth; + private final String beneficiary; public ExpectBeneficiary(final EthTransactions eth, final PantheonNode node) { this.eth = eth; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java index c8db8ac140..0d0769e709 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNumber.java @@ -22,9 +22,8 @@ import java.math.BigInteger; public class ExpectBlockNumber implements Condition { - - private EthTransactions eth; - private BigInteger blockNumber; + private final EthTransactions eth; + private final BigInteger blockNumber; public ExpectBlockNumber(final EthTransactions eth, final BigInteger blockNumber) { this.eth = eth; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java index 35cc00658b..279ac49eb3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -19,7 +19,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; 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.transaction.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.math.BigInteger; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java index d4a0996c9c..e3e8b5f8f3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java @@ -18,7 +18,7 @@ import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; import java.util.Map; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java index 367db8a26e..bc4439910f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java @@ -14,12 +14,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; -import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST; import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; public class ExpectValidators implements Condition { private final CliqueTransactions clique; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java index 8857f036f6..f55720f383 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java @@ -18,7 +18,7 @@ import tech.pegasys.pantheon.ethereum.core.Address; 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.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; public class ExpectValidatorsAtBlock implements Condition { private final CliqueTransactions clique; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java index 7a97641386..a2b361de75 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java @@ -19,7 +19,7 @@ import tech.pegasys.pantheon.ethereum.core.Hash; 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.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; public class ExpectValidatorsAtBlockHash implements Condition { private final CliqueTransactions clique; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java similarity index 93% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java index 73e4d86e70..439d964143 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/CliqueTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java @@ -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.transaction; +package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -31,7 +31,7 @@ public CliquePropose proposeAdd(final PantheonNode node) { return propose(node.getAddress().toString(), true); } - public CliquePropose propose(final String address, final boolean auth) { + private CliquePropose propose(final String address, final boolean auth) { return new CliquePropose(address, auth); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java index 26236eca79..110474562e 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -12,12 +12,12 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition; -import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNumber; 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.transaction.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.math.BigInteger; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java index f4a13694a1..d158233fde 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java @@ -14,11 +14,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; -import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions.LATEST; +import static tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions.LATEST; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.CliqueTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueTransactions; import java.util.List; From b0cd99fca7835fc015a493c6c5a9777db5dbfc0b Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Thu, 22 Nov 2018 15:10:19 +1000 Subject: [PATCH 31/41] [NC-1524] code review changes --- .../clique/CliqueDiscardRpcAcceptanceTest.java | 12 ++++++------ .../clique/CliqueGetSignersRpcTest.java | 8 ++++---- .../clique/CliqueProposalRpcAcceptanceTest.java | 6 +++--- .../clique/CliqueProposeRpcAcceptanceTest.java | 16 ++++++++-------- .../acceptance/dsl/AcceptanceTestBase.java | 2 +- .../dsl/condition/clique/ExpectProposals.java | 2 +- .../dsl/condition/clique/ExpectValidators.java | 4 +++- .../clique/ExpectValidatorsAtBlock.java | 2 +- .../clique/ExpectValidatorsAtBlockHash.java | 2 +- .../transaction/clique/CliqueTransactions.java | 17 ++++++----------- .../dsl/waitcondition/WaitConditions.java | 2 +- .../waitcondition/WaitUntilSignersChanged.java | 4 +++- 12 files changed, 38 insertions(+), 39 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index c78d130d23..a912e93720 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -32,12 +32,12 @@ public void shouldDiscardVotes() throws IOException { pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); - minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); - minerNode2.execute(cliqueTransactions.proposeRemove(minerNode2)); - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode1.execute(cliqueTransactions.discard(minerNode2)); - minerNode1.execute(cliqueTransactions.discard(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode2)); + minerNode2.execute(cliqueTransactions.createProposeRemove(minerNode2)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createDiscard(minerNode2)); + minerNode1.execute(cliqueTransactions.createDiscard(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index e0973136c3..b06713d02c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -38,8 +38,8 @@ public void setUp() throws Exception { @Test public void shouldBeAbleToGetValidatorsForBlockNumber() { - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); @@ -48,8 +48,8 @@ public void shouldBeAbleToGetValidatorsForBlockNumber() { @Test public void shouldBeAbleToGetValidatorsForBlockHash() { - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 3, allNodes)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index ae01b55d49..ae2a027347 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -33,9 +33,9 @@ public void shouldReturnProposals() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.noProposals()); - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); - minerNode2.execute(cliqueTransactions.proposeRemove(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode2)); + minerNode2.execute(cliqueTransactions.createProposeRemove(minerNode3)); minerNode1.verify( clique.proposalsEqual().addProposal(minerNode3).removeProposal(minerNode2).build()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 56675559bf..c3ec428d31 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -36,8 +36,8 @@ public void shouldAddValidators() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); final WaitCondition cliqueValidatorsChanged = wait.cliqueValidatorsChanged(minerNode1); - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); cluster.waitUntil(cliqueValidatorsChanged); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -55,8 +55,8 @@ public void shouldRemoveValidators() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); final WaitCondition cliqueValidatorsChanged = wait.cliqueValidatorsChanged(minerNode1); - minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); - minerNode2.execute(cliqueTransactions.proposeRemove(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode3)); + minerNode2.execute(cliqueTransactions.createProposeRemove(minerNode3)); cluster.waitUntil(cliqueValidatorsChanged); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -73,7 +73,7 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -86,7 +86,7 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - minerNode1.execute(cliqueTransactions.proposeRemove(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -102,12 +102,12 @@ public void shouldIncludeVoteInBlockHeader() throws IOException { pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); - minerNode1.execute(cliqueTransactions.proposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); - minerNode1.execute(cliqueTransactions.proposeRemove(minerNode2)); + minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode2)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode2)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); 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 e1bb27dbaf..68c50f461e 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 @@ -20,8 +20,8 @@ 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.transaction.clique.CliqueTransactions; 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; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.net.NetTransactions; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.web3.Web3Transactions; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java index e3e8b5f8f3..d9ef87ab43 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectProposals.java @@ -33,6 +33,6 @@ public ExpectProposals(final CliqueTransactions clique, final Map assertThat(node.execute(clique.proposals())).isEqualTo(proposers)); + waitFor(() -> assertThat(node.execute(clique.createProposals())).isEqualTo(proposers)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java index bc4439910f..22fd223430 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidators.java @@ -32,6 +32,8 @@ public ExpectValidators(final CliqueTransactions clique, final Address... valida @Override public void verify(final Node node) { - waitFor(() -> assertThat(node.execute(clique.getSigners(LATEST))).containsExactly(validators)); + waitFor( + () -> + assertThat(node.execute(clique.createGetSigners(LATEST))).containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java index f55720f383..ec281fb1fa 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlock.java @@ -36,7 +36,7 @@ public ExpectValidatorsAtBlock( public void verify(final Node node) { waitFor( () -> - assertThat(node.execute(clique.getSigners(blockParameter))) + assertThat(node.execute(clique.createGetSigners(blockParameter))) .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java index a2b361de75..ef95fb0131 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/ExpectValidatorsAtBlockHash.java @@ -37,7 +37,7 @@ public ExpectValidatorsAtBlockHash( public void verify(final Node node) { waitFor( () -> - assertThat(node.execute(clique.getSignersAtHash(blockHash))) + assertThat(node.execute(clique.createGetSignersAtHash(blockHash))) .containsExactly(validators)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java index 439d964143..bffaf80204 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java @@ -14,20 +14,15 @@ import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueDiscard; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueGetSigners; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueGetSignersAtHash; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliqueProposals; -import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.clique.CliquePropose; public class CliqueTransactions { public static final String LATEST = "latest"; - public CliquePropose proposeRemove(final PantheonNode node) { + public CliquePropose createProposeRemove(final PantheonNode node) { return propose(node.getAddress().toString(), false); } - public CliquePropose proposeAdd(final PantheonNode node) { + public CliquePropose createProposeAdd(final PantheonNode node) { return propose(node.getAddress().toString(), true); } @@ -35,19 +30,19 @@ private CliquePropose propose(final String address, final boolean auth) { return new CliquePropose(address, auth); } - public CliqueProposals proposals() { + public CliqueProposals createProposals() { return new CliqueProposals(); } - public CliqueGetSigners getSigners(final String blockNumber) { + public CliqueGetSigners createGetSigners(final String blockNumber) { return new CliqueGetSigners(blockNumber); } - public CliqueGetSignersAtHash getSignersAtHash(final Hash blockHash) { + public CliqueGetSignersAtHash createGetSignersAtHash(final Hash blockHash) { return new CliqueGetSignersAtHash(blockHash); } - public CliqueDiscard discard(final PantheonNode node) { + public CliqueDiscard createDiscard(final PantheonNode node) { return new CliqueDiscard(node.getAddress().toString()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java index 110474562e..a5e1a27c25 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -39,6 +39,6 @@ public WaitCondition chainHeadHasProgressed( } public WaitCondition cliqueValidatorsChanged(final Node node) { - return new WaitUntilSignersChanged(node.execute(clique.getSigners(LATEST)), clique); + return new WaitUntilSignersChanged(node.execute(clique.createGetSigners(LATEST)), clique); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java index d158233fde..40c5ad6003 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitUntilSignersChanged.java @@ -35,6 +35,8 @@ public WaitUntilSignersChanged( @Override public void waitUntil(final Node node) { waitFor( - 60, () -> assertThat(node.execute(clique.getSigners(LATEST))).isNotEqualTo(initialSigners)); + 60, + () -> + assertThat(node.execute(clique.createGetSigners(LATEST))).isNotEqualTo(initialSigners)); } } From 9f814f1c3f00393d59ecd29746f9642afded1125 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 23 Nov 2018 09:25:12 +1000 Subject: [PATCH 32/41] [NC-1524] fix broken tests after merge from master --- .../acceptance/dsl/node/PantheonNode.java | 52 ++++--------------- .../dsl/node/PantheonNodeFactory.java | 2 +- 2 files changed, 12 insertions(+), 42 deletions(-) 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 219aa5cf49..16f8bc295d 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 @@ -23,7 +23,6 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; -import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eth; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.PantheonWeb3j; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction; import tech.pegasys.pantheon.tests.acceptance.dsl.waitcondition.WaitCondition; @@ -49,8 +48,6 @@ import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; import org.java_websocket.exceptions.WebsocketNotConnectedException; -import org.web3j.protocol.Web3j; -import org.web3j.protocol.Web3jService; import org.web3j.protocol.http.HttpService; import org.web3j.protocol.websocket.WebSocketClient; import org.web3j.protocol.websocket.WebSocketListener; @@ -75,8 +72,6 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto private final boolean devMode; private List bootnodes = new ArrayList<>(); - private Eth eth; - private Web3j web3j; private PantheonWeb3j pantheonWeb3j; private Optional ethNetworkConfig = Optional.empty(); @@ -154,19 +149,19 @@ public String hostName() { return LOCALHOST; } - private Web3j web3j() { + private PantheonWeb3j pantheonWeb3j() { - if (web3j == null) { + if (pantheonWeb3j == null) { if (!jsonRpcBaseUrl().isPresent()) { - return Web3j.build( + return new PantheonWeb3j( new HttpService("http://" + LOCALHOST + ":8545"), 2000, Async.defaultExecutorService()); } - return Web3j.build( + return new PantheonWeb3j( new HttpService(jsonRpcBaseUrl().get()), 2000, Async.defaultExecutorService()); } - return web3j; + return pantheonWeb3j; } /** All future JSON-RPC calls are made via a web sockets connection. */ @@ -183,11 +178,11 @@ public void useWebSocketsForJsonRpc() { throw new RuntimeException("Error connection to WebSocket endpoint", e); } - if (web3j != null) { - web3j.shutdown(); + if (pantheonWeb3j != null) { + pantheonWeb3j.shutdown(); } - web3j = Web3j.build(webSocketService, 2000, Async.defaultExecutorService()); + pantheonWeb3j = new PantheonWeb3j(webSocketService, 2000, Async.defaultExecutorService()); } private void checkIfWebSocketEndpointIsAvailable(final String url) { @@ -224,31 +219,6 @@ public void onClose() { } } - private PantheonWeb3j pantheonWeb3j() { - if (pantheonWeb3j == null) { - return pantheonWeb3j(web3jService()); - } - - return pantheonWeb3j; - } - - private PantheonWeb3j pantheonWeb3j(final Web3jService web3jService) { - if (pantheonWeb3j == null) { - pantheonWeb3j = new PantheonWeb3j(web3jService, 2000, Async.defaultExecutorService()); - } - - return pantheonWeb3j; - } - - private Web3jService web3jService() { - if (!jsonRpcBaseUrl().isPresent()) { - throw new IllegalStateException( - "Can't create a web3j instance for a node with RPC disabled."); - } - - return new HttpService(jsonRpcBaseUrl().get()); - } - @Override public void start(final PantheonNodeRunner runner) { runner.startNode(this); @@ -355,9 +325,9 @@ public String toString() { @Override public void stop() { - if (web3j != null) { - web3j.shutdown(); - web3j = null; + if (pantheonWeb3j != null) { + pantheonWeb3j.shutdown(); + pantheonWeb3j = null; } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java index e455f41fb2..8842e54749 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java @@ -183,7 +183,7 @@ public PantheonFactoryConfiguration( miningParameters, jsonRpcConfiguration, webSocketConfiguration, - false, + true, ignore -> Optional.empty()); } From 219830b352a2be0b1868246a098047592f1fe5f6 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Fri, 23 Nov 2018 14:30:53 +1000 Subject: [PATCH 33/41] [NC-1524] additional validator checks in getSigners test --- .../acceptance/clique/CliqueGetSignersRpcTest.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index b06713d02c..a0c7b7c821 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -25,6 +25,7 @@ public class CliqueGetSignersRpcTest extends AcceptanceTestBase { private PantheonNode minerNode2; private PantheonNode minerNode3; private PantheonNode[] allNodes; + private PantheonNode[] initialNodes; @Before public void setUp() throws Exception { @@ -32,26 +33,35 @@ public void setUp() throws Exception { minerNode1 = pantheon.createCliqueMinerNodeWithValidators("miner1", validators); minerNode2 = pantheon.createCliqueMinerNodeWithValidators("miner2", validators); minerNode3 = pantheon.createCliqueMinerNodeWithValidators("miner3", validators); + initialNodes = new PantheonNode[] {minerNode1, minerNode2}; allNodes = new PantheonNode[] {minerNode1, minerNode2, minerNode3}; cluster.start(allNodes); } @Test public void shouldBeAbleToGetValidatorsForBlockNumber() { + cluster.verify(clique.validatorsAtBlockEqual("0x0", initialNodes)); minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); + cluster.verify(clique.validatorsAtBlockEqual("0x1", initialNodes)); + + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); cluster.verify(clique.validatorsAtBlockEqual(LATEST, allNodes)); } @Test public void shouldBeAbleToGetValidatorsForBlockHash() { + cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 0, initialNodes)); minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); + cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 1, initialNodes)); + + minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 3, allNodes)); } } From 9d35daf1d073d572b153c1eb5e6f1c20723167ee Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 26 Nov 2018 11:34:31 +1000 Subject: [PATCH 34/41] [NC-1524] added no block created expectation --- .../clique/CliqueMiningAcceptanceTest.java | 11 +---- .../acceptance/dsl/blockchain/Blockchain.java | 5 +++ .../blockchain/ExpectBlockNotCreated.java | 45 +++++++++++++++++++ .../eth/EthBlockNumberTransaction.java | 1 + 4 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index eeed68f29e..5a395761a3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -14,7 +14,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; import java.io.IOException; @@ -62,8 +61,7 @@ public void shouldMineTransactionsOnMultipleNodes() throws IOException { } @Test - public void shouldStallMiningWhenInsufficientValidators() - throws IOException, InterruptedException { + public void shouldStallMiningWhenInsufficientValidators() throws IOException { final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); @@ -71,11 +69,6 @@ public void shouldStallMiningWhenInsufficientValidators() cluster.stopNode(minerNode2); cluster.stopNode(minerNode3); - - final Condition lastBlockNumber = blockchain.blockNumberMustBeLatest(minerNode1); - Thread.sleep(15_000); - minerNode1.verify(lastBlockNumber); - Thread.sleep(15_000); - minerNode1.verify(lastBlockNumber); + minerNode1.verify(blockchain.blockNotCreated()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java index d54b3ff52b..e3bf8c7686 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java @@ -14,6 +14,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBeneficiary; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectMinimumBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -34,4 +35,8 @@ public Condition blockNumberMustBeLatest(final Node node) { public Condition beneficiaryEquals(final PantheonNode node) { return new ExpectBeneficiary(eth, node); } + + public Condition blockNotCreated() { + return new ExpectBlockNotCreated(eth); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java new file mode 100644 index 0000000000..3c9a6d8b74 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java @@ -0,0 +1,45 @@ +/* + * 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.blockchain; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Java6Assertions.assertThat; + +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.EthTransactions; + +import java.math.BigInteger; +import java.util.concurrent.TimeUnit; + +import org.awaitility.Awaitility; +import org.awaitility.Duration; + +public class ExpectBlockNotCreated implements Condition { + private static final Duration WAIT_TIME = new Duration(20, SECONDS); + private final EthTransactions eth; + + public ExpectBlockNotCreated(final EthTransactions eth) { + this.eth = eth; + } + + @Override + public void verify(final Node node) { + final BigInteger lastBlock = node.execute(eth.blockNumber()); + Awaitility.await() + .ignoreExceptions() + .pollInterval(WAIT_TIME) + .atMost(30, TimeUnit.SECONDS) + .untilAsserted(() -> assertThat(node.execute(eth.blockNumber())).isEqualTo(lastBlock)); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java index fe7a1a87ce..4a36135464 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java @@ -27,6 +27,7 @@ public class EthBlockNumberTransaction implements Transaction { @Override public BigInteger execute(final PantheonWeb3j node) { try { + System.out.println("getting block number"); final org.web3j.protocol.core.methods.response.EthBlockNumber result = node.ethBlockNumber().send(); assertThat(result).isNotNull(); From 2afe0013cdbb3c71074ed95b4e6d6487a3db18f5 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 26 Nov 2018 11:45:45 +1000 Subject: [PATCH 35/41] [NC-1524] rename clique proposal methods --- .../clique/CliqueDiscardRpcAcceptanceTest.java | 12 ++++++------ .../clique/CliqueGetSignersRpcTest.java | 8 ++++---- .../clique/CliqueProposalRpcAcceptanceTest.java | 6 +++--- .../clique/CliqueProposeRpcAcceptanceTest.java | 16 ++++++++-------- .../transaction/clique/CliqueTransactions.java | 6 +++--- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index a912e93720..05214b5e8a 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -32,12 +32,12 @@ public void shouldDiscardVotes() throws IOException { pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); - minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode2)); - minerNode2.execute(cliqueTransactions.createProposeRemove(minerNode2)); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode1.execute(cliqueTransactions.createDiscard(minerNode2)); - minerNode1.execute(cliqueTransactions.createDiscard(minerNode3)); + minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode2)); + minerNode2.execute(cliqueTransactions.createRemoveProposal(minerNode2)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode1.execute(cliqueTransactions.createDiscardProposal(minerNode2)); + minerNode1.execute(cliqueTransactions.createDiscardProposal(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 2)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index a0c7b7c821..3d8aac9efb 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -41,8 +41,8 @@ public void setUp() throws Exception { @Test public void shouldBeAbleToGetValidatorsForBlockNumber() { cluster.verify(clique.validatorsAtBlockEqual("0x0", initialNodes)); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsAtBlockEqual("0x1", initialNodes)); @@ -55,8 +55,8 @@ public void shouldBeAbleToGetValidatorsForBlockNumber() { @Test public void shouldBeAbleToGetValidatorsForBlockHash() { cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 0, initialNodes)); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsAtBlockHashFromBlockNumberEqual(minerNode1, 1, initialNodes)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index ae2a027347..c3c055c197 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -33,9 +33,9 @@ public void shouldReturnProposals() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.noProposals()); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode2)); - minerNode2.execute(cliqueTransactions.createProposeRemove(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode2)); + minerNode2.execute(cliqueTransactions.createRemoveProposal(minerNode3)); minerNode1.verify( clique.proposalsEqual().addProposal(minerNode3).removeProposal(minerNode2).build()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index c3ec428d31..238f92e3ab 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -36,8 +36,8 @@ public void shouldAddValidators() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); final WaitCondition cliqueValidatorsChanged = wait.cliqueValidatorsChanged(minerNode1); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); - minerNode2.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); cluster.waitUntil(cliqueValidatorsChanged); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -55,8 +55,8 @@ public void shouldRemoveValidators() throws IOException { cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); final WaitCondition cliqueValidatorsChanged = wait.cliqueValidatorsChanged(minerNode1); - minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode3)); - minerNode2.execute(cliqueTransactions.createProposeRemove(minerNode3)); + minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode3)); + minerNode2.execute(cliqueTransactions.createRemoveProposal(minerNode3)); cluster.waitUntil(cliqueValidatorsChanged); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -73,7 +73,7 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); } @@ -86,7 +86,7 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); - minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode3)); + minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); } @@ -102,12 +102,12 @@ public void shouldIncludeVoteInBlockHeader() throws IOException { pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); - minerNode1.execute(cliqueTransactions.createProposeAdd(minerNode3)); + minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode3)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.AUTH)); - minerNode1.execute(cliqueTransactions.createProposeRemove(minerNode2)); + minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode2)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); minerNode1.verify(blockchain.beneficiaryEquals(minerNode2)); minerNode1.verify(clique.nonceVoteEquals(CLIQUE_NONCE_VOTE.DROP)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java index bffaf80204..f9a500b098 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/clique/CliqueTransactions.java @@ -18,11 +18,11 @@ public class CliqueTransactions { public static final String LATEST = "latest"; - public CliquePropose createProposeRemove(final PantheonNode node) { + public CliquePropose createRemoveProposal(final PantheonNode node) { return propose(node.getAddress().toString(), false); } - public CliquePropose createProposeAdd(final PantheonNode node) { + public CliquePropose createAddProposal(final PantheonNode node) { return propose(node.getAddress().toString(), true); } @@ -42,7 +42,7 @@ public CliqueGetSignersAtHash createGetSignersAtHash(final Hash blockHash) { return new CliqueGetSignersAtHash(blockHash); } - public CliqueDiscard createDiscard(final PantheonNode node) { + public CliqueDiscard createDiscardProposal(final PantheonNode node) { return new CliqueDiscard(node.getAddress().toString()); } } From 819d5c508a3a2afd12eb76e7a80d198b84452ec6 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 26 Nov 2018 12:22:10 +1000 Subject: [PATCH 36/41] [NC-1524] wait for peers to disconnect in miner instability test --- .../tests/acceptance/clique/CliqueMiningAcceptanceTest.java | 1 + .../dsl/transaction/eth/EthBlockNumberTransaction.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 5a395761a3..8d872ca714 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -69,6 +69,7 @@ public void shouldStallMiningWhenInsufficientValidators() throws IOException { cluster.stopNode(minerNode2); cluster.stopNode(minerNode3); + minerNode1.verify(net.awaitPeerCount(0)); minerNode1.verify(blockchain.blockNotCreated()); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java index 4a36135464..fe7a1a87ce 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eth/EthBlockNumberTransaction.java @@ -27,7 +27,6 @@ public class EthBlockNumberTransaction implements Transaction { @Override public BigInteger execute(final PantheonWeb3j node) { try { - System.out.println("getting block number"); final org.web3j.protocol.core.methods.response.EthBlockNumber result = node.ethBlockNumber().send(); assertThat(result).isNotNull(); From cde87bdf8b927fb1e7e078c1fd3b63bbc431c0a7 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 26 Nov 2018 14:18:33 +1000 Subject: [PATCH 37/41] [NC-1524] add initial wait in no block created expectation --- .../blockchain/ExpectBlockNotCreated.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java index 3c9a6d8b74..1244257183 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java @@ -12,7 +12,6 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain; -import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Java6Assertions.assertThat; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; @@ -20,13 +19,10 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions; import java.math.BigInteger; -import java.util.concurrent.TimeUnit; - -import org.awaitility.Awaitility; -import org.awaitility.Duration; public class ExpectBlockNotCreated implements Condition { - private static final Duration WAIT_TIME = new Duration(20, SECONDS); + private static final int INITIAL_WAIT = 5_000; + private static final int WAIT = 15_000; private final EthTransactions eth; public ExpectBlockNotCreated(final EthTransactions eth) { @@ -35,11 +31,13 @@ public ExpectBlockNotCreated(final EthTransactions eth) { @Override public void verify(final Node node) { - final BigInteger lastBlock = node.execute(eth.blockNumber()); - Awaitility.await() - .ignoreExceptions() - .pollInterval(WAIT_TIME) - .atMost(30, TimeUnit.SECONDS) - .untilAsserted(() -> assertThat(node.execute(eth.blockNumber())).isEqualTo(lastBlock)); + try { + Thread.sleep(INITIAL_WAIT); + final BigInteger lastBlock = node.execute(eth.blockNumber()); + Thread.sleep(WAIT); + assertThat(node.execute(eth.blockNumber())).isEqualTo(lastBlock); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } } } From e78b39442d1a3ce06b7e8047d42afe9d059a5eb1 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Tue, 27 Nov 2018 11:37:10 +1000 Subject: [PATCH 38/41] [NC-1524] fail no new block condition immediately if there is a new block --- acceptance-tests/build.gradle | 1 + .../clique/CliqueMiningAcceptanceTest.java | 2 +- .../acceptance/dsl/blockchain/Blockchain.java | 3 -- .../blockchain/ExpectBlockNotCreated.java | 49 ++++++++++++++++--- .../condition/clique/CliqueConditions.java | 18 +++++++ 5 files changed, 61 insertions(+), 12 deletions(-) diff --git a/acceptance-tests/build.gradle b/acceptance-tests/build.gradle index 8077d2bb58..187e791d4f 100644 --- a/acceptance-tests/build.gradle +++ b/acceptance-tests/build.gradle @@ -22,6 +22,7 @@ dependencies { testImplementation project(':ethereum:blockcreation') testImplementation project(':ethereum:jsonrpc') testImplementation project(':pantheon') + testImplementation project(':config') testImplementation project(':util') testImplementation project(':consensus:clique') diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 8d872ca714..2286de9039 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -70,6 +70,6 @@ public void shouldStallMiningWhenInsufficientValidators() throws IOException { cluster.stopNode(minerNode2); cluster.stopNode(minerNode3); minerNode1.verify(net.awaitPeerCount(0)); - minerNode1.verify(blockchain.blockNotCreated()); + minerNode1.verify(clique.noNewBlockCreated(minerNode1)); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java index e3bf8c7686..401f7c9190 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java @@ -36,7 +36,4 @@ public Condition beneficiaryEquals(final PantheonNode node) { return new ExpectBeneficiary(eth, node); } - public Condition blockNotCreated() { - return new ExpectBlockNotCreated(eth); - } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java index 1244257183..8ba76c3427 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/blockchain/ExpectBlockNotCreated.java @@ -12,30 +12,63 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static junit.framework.TestCase.fail; 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.EthTransactions; import java.math.BigInteger; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.awaitility.Awaitility; public class ExpectBlockNotCreated implements Condition { - private static final int INITIAL_WAIT = 5_000; - private static final int WAIT = 15_000; private final EthTransactions eth; + private final int initialWait; + private final int blockPeriodWait; - public ExpectBlockNotCreated(final EthTransactions eth) { + public ExpectBlockNotCreated( + final EthTransactions eth, final int initialWait, final int blockPeriodWait) { this.eth = eth; + this.initialWait = initialWait; + this.blockPeriodWait = blockPeriodWait; } @Override public void verify(final Node node) { + final AtomicInteger tries = new AtomicInteger(); + final int triesRequired = blockPeriodWait / 1000; + final BigInteger initialBlock = initialBlock(node); + Awaitility.await() + .pollInterval(1, TimeUnit.SECONDS) + .atMost(30, TimeUnit.SECONDS) + .until(() -> isNewBlock(node, tries, triesRequired, initialBlock)); + } + + private Boolean isNewBlock( + final Node node, + final AtomicInteger tries, + final int triesRequired, + final BigInteger lastBlock) { + final BigInteger currentBlock = node.execute(eth.blockNumber()); + final int currentTries = tries.getAndIncrement(); + if (!currentBlock.equals(lastBlock)) { + final String failMsg = + String.format( + "New block created. Expected block=%s got block=%s", lastBlock, currentBlock); + fail(failMsg); + } + // Only consider that the block is really the same after a period of time or number tries as a + // block could be currently be in the process of being mined + return currentTries > triesRequired; + } + + private BigInteger initialBlock(final Node node) { try { - Thread.sleep(INITIAL_WAIT); - final BigInteger lastBlock = node.execute(eth.blockNumber()); - Thread.sleep(WAIT); - assertThat(node.execute(eth.blockNumber())).isEqualTo(lastBlock); + Thread.sleep(initialWait); + return node.execute(eth.blockNumber()); } catch (InterruptedException e) { throw new IllegalStateException(e); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java index 279ac49eb3..16dcc46287 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -12,10 +12,14 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique; +import static java.util.Collections.emptyList; import static tech.pegasys.pantheon.ethereum.core.Hash.fromHexString; +import tech.pegasys.pantheon.config.CliqueConfigOptions; +import tech.pegasys.pantheon.config.GenesisConfigFile; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; +import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.clique.ExpectNonceVote.CLIQUE_NONCE_VOTE; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -71,6 +75,20 @@ public Condition nonceVoteEquals(final CLIQUE_NONCE_VOTE clique_nonce_vote) { return new ExpectNonceVote(eth, clique_nonce_vote); } + public Condition noNewBlockCreated(final PantheonNode node) { + final int blockPeriodSeconds = cliqueBlockPeriod(node); + final int blockPeriodWait = blockPeriodSeconds * 1000; + return new ExpectBlockNotCreated(eth, blockPeriodWait, blockPeriodWait); + } + + private int cliqueBlockPeriod(final PantheonNode node) { + final String config = node.genesisConfigProvider().createGenesisConfig(emptyList()).get(); + final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(config); + final CliqueConfigOptions cliqueConfigOptions = genesisConfigFile.getConfigOptions() + .getCliqueConfigOptions(); + return cliqueConfigOptions.getBlockPeriodSeconds(); + } + private Address[] validatorAddresses(final PantheonNode[] validators) { return Arrays.stream(validators).map(PantheonNode::getAddress).sorted().toArray(Address[]::new); } From 3863b533574e712380062e749ef878d702c45ba0 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Tue, 27 Nov 2018 12:07:15 +1000 Subject: [PATCH 39/41] [NC-1524] spotless fixes --- .../pantheon/tests/acceptance/dsl/blockchain/Blockchain.java | 2 -- .../acceptance/dsl/condition/clique/CliqueConditions.java | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java index 401f7c9190..d54b3ff52b 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/blockchain/Blockchain.java @@ -14,7 +14,6 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBeneficiary; -import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectBlockNotCreated; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.blockchain.ExpectMinimumBlockNumber; import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; @@ -35,5 +34,4 @@ public Condition blockNumberMustBeLatest(final Node node) { public Condition beneficiaryEquals(final PantheonNode node) { return new ExpectBeneficiary(eth, node); } - } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java index 16dcc46287..2379ac9015 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/condition/clique/CliqueConditions.java @@ -84,8 +84,8 @@ public Condition noNewBlockCreated(final PantheonNode node) { private int cliqueBlockPeriod(final PantheonNode node) { final String config = node.genesisConfigProvider().createGenesisConfig(emptyList()).get(); final GenesisConfigFile genesisConfigFile = GenesisConfigFile.fromConfig(config); - final CliqueConfigOptions cliqueConfigOptions = genesisConfigFile.getConfigOptions() - .getCliqueConfigOptions(); + final CliqueConfigOptions cliqueConfigOptions = + genesisConfigFile.getConfigOptions().getCliqueConfigOptions(); return cliqueConfigOptions.getBlockPeriodSeconds(); } From 69e93b96799edc775a7f46f45196322adda5a029 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 28 Nov 2018 11:05:12 +1000 Subject: [PATCH 40/41] [NC-1524] drop miner from createCliqueMinerNode methods as all nodes are potential miners --- .../CliqueDiscardRpcAcceptanceTest.java | 6 ++-- .../clique/CliqueGetSignersRpcTest.java | 6 ++-- .../clique/CliqueMiningAcceptanceTest.java | 14 ++++----- .../CliqueProposalRpcAcceptanceTest.java | 6 ++-- .../CliqueProposeRpcAcceptanceTest.java | 30 +++++++++---------- .../dsl/node/PantheonNodeFactory.java | 4 +-- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java index 05214b5e8a..09da7e7e04 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueDiscardRpcAcceptanceTest.java @@ -25,11 +25,11 @@ public class CliqueDiscardRpcAcceptanceTest extends AcceptanceTestBase { public void shouldDiscardVotes() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); + pantheon.createCliqueNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); + pantheon.createCliqueNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + pantheon.createCliqueNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); minerNode1.execute(cliqueTransactions.createRemoveProposal(minerNode2)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index 3d8aac9efb..fc0fbf4988 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -30,9 +30,9 @@ public class CliqueGetSignersRpcTest extends AcceptanceTestBase { @Before public void setUp() throws Exception { final String[] validators = {"miner1", "miner2"}; - minerNode1 = pantheon.createCliqueMinerNodeWithValidators("miner1", validators); - minerNode2 = pantheon.createCliqueMinerNodeWithValidators("miner2", validators); - minerNode3 = pantheon.createCliqueMinerNodeWithValidators("miner3", validators); + minerNode1 = pantheon.createCliqueNodeWithValidators("miner1", validators); + minerNode2 = pantheon.createCliqueNodeWithValidators("miner2", validators); + minerNode3 = pantheon.createCliqueNodeWithValidators("miner3", validators); initialNodes = new PantheonNode[] {minerNode1, minerNode2}; allNodes = new PantheonNode[] {minerNode1, minerNode2, minerNode3}; cluster.start(allNodes); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java index 2286de9039..55417c6ca2 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueMiningAcceptanceTest.java @@ -24,7 +24,7 @@ public class CliqueMiningAcceptanceTest extends AcceptanceTestBase { @Test public void shouldMineTransactionsOnSingleNode() throws IOException { - final PantheonNode minerNode = pantheon.createCliqueMinerNode("miner1"); + final PantheonNode minerNode = pantheon.createCliqueNode("miner1"); cluster.start(minerNode); final Account sender = accounts.createAccount("account1"); @@ -42,9 +42,9 @@ public void shouldMineTransactionsOnSingleNode() throws IOException { @Test public void shouldMineTransactionsOnMultipleNodes() throws IOException { - final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); - final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); - final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); + final PantheonNode minerNode1 = pantheon.createCliqueNode("miner1"); + final PantheonNode minerNode2 = pantheon.createCliqueNode("miner2"); + final PantheonNode minerNode3 = pantheon.createCliqueNode("miner3"); cluster.start(minerNode1, minerNode2, minerNode3); final Account sender = accounts.createAccount("account1"); @@ -62,9 +62,9 @@ public void shouldMineTransactionsOnMultipleNodes() throws IOException { @Test public void shouldStallMiningWhenInsufficientValidators() throws IOException { - final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); - final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); - final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); + final PantheonNode minerNode1 = pantheon.createCliqueNode("miner1"); + final PantheonNode minerNode2 = pantheon.createCliqueNode("miner2"); + final PantheonNode minerNode3 = pantheon.createCliqueNode("miner3"); cluster.start(minerNode1, minerNode2, minerNode3); cluster.stopNode(minerNode2); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java index c3c055c197..ee414c56ea 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposalRpcAcceptanceTest.java @@ -25,11 +25,11 @@ public class CliqueProposalRpcAcceptanceTest extends AcceptanceTestBase { public void shouldReturnProposals() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); + pantheon.createCliqueNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); + pantheon.createCliqueNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + pantheon.createCliqueNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.noProposals()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java index 238f92e3ab..938cdb1e60 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueProposeRpcAcceptanceTest.java @@ -27,11 +27,11 @@ public class CliqueProposeRpcAcceptanceTest extends AcceptanceTestBase { public void shouldAddValidators() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); + pantheon.createCliqueNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); + pantheon.createCliqueNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + pantheon.createCliqueNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); @@ -46,11 +46,11 @@ public void shouldAddValidators() throws IOException { public void shouldRemoveValidators() throws IOException { final String[] initialValidators = {"miner1", "miner2", "miner3"}; final PantheonNode minerNode1 = - pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); + pantheon.createCliqueNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); + pantheon.createCliqueNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + pantheon.createCliqueNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); @@ -65,11 +65,11 @@ public void shouldRemoveValidators() throws IOException { public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); + pantheon.createCliqueNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); + pantheon.createCliqueNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + pantheon.createCliqueNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2)); @@ -80,9 +80,9 @@ public void shouldNotAddValidatorWhenInsufficientVotes() throws IOException { @Test public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { - final PantheonNode minerNode1 = pantheon.createCliqueMinerNode("miner1"); - final PantheonNode minerNode2 = pantheon.createCliqueMinerNode("miner2"); - final PantheonNode minerNode3 = pantheon.createCliqueMinerNode("miner3"); + final PantheonNode minerNode1 = pantheon.createCliqueNode("miner1"); + final PantheonNode minerNode2 = pantheon.createCliqueNode("miner2"); + final PantheonNode minerNode3 = pantheon.createCliqueNode("miner3"); cluster.start(minerNode1, minerNode2, minerNode3); cluster.verify(clique.validatorsEqual(minerNode1, minerNode2, minerNode3)); @@ -95,11 +95,11 @@ public void shouldNotRemoveValidatorWhenInsufficientVotes() throws IOException { public void shouldIncludeVoteInBlockHeader() throws IOException { final String[] initialValidators = {"miner1", "miner2"}; final PantheonNode minerNode1 = - pantheon.createCliqueMinerNodeWithValidators("miner1", initialValidators); + pantheon.createCliqueNodeWithValidators("miner1", initialValidators); final PantheonNode minerNode2 = - pantheon.createCliqueMinerNodeWithValidators("miner2", initialValidators); + pantheon.createCliqueNodeWithValidators("miner2", initialValidators); final PantheonNode minerNode3 = - pantheon.createCliqueMinerNodeWithValidators("miner3", initialValidators); + pantheon.createCliqueNodeWithValidators("miner3", initialValidators); cluster.start(minerNode1, minerNode2, minerNode3); minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java index 8842e54749..041bf67584 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java @@ -87,7 +87,7 @@ public PantheonNode createArchiveNodeWithRpcApis( name, createMiningParameters(false), jsonRpcConfig, webSocketConfig)); } - public PantheonNode createCliqueMinerNode(final String name) throws IOException { + public PantheonNode createCliqueNode(final String name) throws IOException { return create( new PantheonFactoryConfiguration( name, @@ -98,7 +98,7 @@ public PantheonNode createCliqueMinerNode(final String name) throws IOException this::createCliqueGenesisConfig)); } - public PantheonNode createCliqueMinerNodeWithValidators( + public PantheonNode createCliqueNodeWithValidators( final String name, final String... validators) throws IOException { return create( new PantheonFactoryConfiguration( From bd5ec674fe7f3c2e2730863da04d167ddd1fb8ed Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 28 Nov 2018 15:13:05 +1000 Subject: [PATCH 41/41] [NC-1524] add wait to ensure chain is at expected block --- .../tests/acceptance/clique/CliqueGetSignersRpcTest.java | 5 +++-- .../tests/acceptance/dsl/node/PantheonNodeFactory.java | 4 ++-- .../tests/acceptance/dsl/waitcondition/WaitConditions.java | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java index fc0fbf4988..7defc03259 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/clique/CliqueGetSignersRpcTest.java @@ -41,11 +41,12 @@ public void setUp() throws Exception { @Test public void shouldBeAbleToGetValidatorsForBlockNumber() { cluster.verify(clique.validatorsAtBlockEqual("0x0", initialNodes)); + cluster.waitUntil(wait.chainHeadIsAt(1)); minerNode1.execute(cliqueTransactions.createAddProposal(minerNode3)); minerNode2.execute(cliqueTransactions.createAddProposal(minerNode3)); - minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); - cluster.verify(clique.validatorsAtBlockEqual("0x1", initialNodes)); + cluster.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); + cluster.verify(clique.validatorsAtBlockEqual("0x2", initialNodes)); minerNode1.waitUntil(wait.chainHeadHasProgressed(minerNode1, 1)); cluster.verify(clique.validatorsAtBlockEqual("0x3", allNodes)); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java index 041bf67584..f08eb88510 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNodeFactory.java @@ -98,8 +98,8 @@ public PantheonNode createCliqueNode(final String name) throws IOException { this::createCliqueGenesisConfig)); } - public PantheonNode createCliqueNodeWithValidators( - final String name, final String... validators) throws IOException { + public PantheonNode createCliqueNodeWithValidators(final String name, final String... validators) + throws IOException { return create( new PantheonFactoryConfiguration( name, diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java index a5e1a27c25..3f5b86f55f 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/waitcondition/WaitConditions.java @@ -41,4 +41,8 @@ public WaitCondition chainHeadHasProgressed( public WaitCondition cliqueValidatorsChanged(final Node node) { return new WaitUntilSignersChanged(node.execute(clique.createGetSigners(LATEST)), clique); } + + public WaitCondition chainHeadIsAt(final long blockNumber) { + return new ExpectBlockNumber(eth, BigInteger.valueOf(blockNumber))::verify; + } }