Skip to content

Commit

Permalink
Migrated to container tests.
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Terry <mark.terry@consensys.net>
  • Loading branch information
mark-terry committed Feb 25, 2021
1 parent 67e5b4e commit ac84bae
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@
*/
package org.hyperledger.besu.tests.container;

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

import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import io.reactivex.subscribers.TestSubscriber;
import okhttp3.OkHttpClient;
import org.awaitility.Awaitility;
import org.awaitility.core.ThrowingRunnable;
import org.junit.After;
Expand All @@ -35,39 +33,31 @@
import org.testcontainers.utility.MountableFile;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthBlockNumber;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.exceptions.TransactionException;
import org.web3j.protocol.http.HttpService;
import org.web3j.quorum.Quorum;
import org.web3j.quorum.enclave.Enclave;
import org.web3j.quorum.enclave.Tessera;
import org.web3j.quorum.enclave.protocol.EnclaveService;
import org.web3j.quorum.tx.QuorumTransactionManager;
import org.web3j.tx.response.PollingTransactionReceiptProcessor;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ContainerTestBase {
private final String besuVersion = "20.10.3";
private final String besuVersion = "develop";
private final String goQuorumVersion = "21.1.0";
private final String tesseraVersion = "21.1.0";

protected final int defaultWait = 10;

protected final String pubKey1 = "3XGBIf+x8IdVQOVfIsbRnHwTYOJP/Fx84G8gMmy8qDM=";
protected final String pubKey2 = "4g8pPgIUC0oZVeuIoe9ETsgL/9CkNSRYlqPQEChM1DE=";
protected final String goQuorumTesseraPubKey = "3XGBIf+x8IdVQOVfIsbRnHwTYOJP/Fx84G8gMmy8qDM=";
protected final String besuTesseraPubKey = "8JJLEAbq6o9m4Kqm++v0Y1n9Z2ryAFtZTyhnxSKWgws=";

private final Network containerNetwork = Network.SHARED;
protected Web3j besuWeb3j;
protected Quorum besuWeb3j;
protected Quorum goQuorumWeb3j;

// General config
private final String hostGenesisPath = "/genesis.json";
private final String hostKeyPath = "/keys";
private final String containerKeyPath = "/tmp/keys";
private final Integer networkId = 2020;

// Besu config
Expand All @@ -85,12 +75,13 @@ public class ContainerTestBase {
private final String containerIpcPath = ipcBindDir + ipcFilePath;

// Tessera config
private final String tesseraContainerPrivKey1Path = "/tmp/tessera/key1.key";
private final String tesseraContainerPubKey1Path = "/tmp/tessera/key1.pub";
private final String tesseraContainerPrivKey2Path = "/tmp/tessera/key2.key";
private final String tesseraContainerPubKey2Path = "/tmp/tessera/key2.pub";
private final String tesseraContainerPrivKey1Path = "/tmp/keys/key1.key";
private final String tesseraContainerPubKey1Path = "/tmp/keys/key1.pub";
private final String tesseraContainerPrivKey2Path = "/tmp/keys/key2.key";
private final String tesseraContainerPubKey2Path = "/tmp/keys/key2.pub";
private final String tesseraContainerConfigFilePath = "/tmp/tessera/tesseraConfig.json";
private final int tesseraRestPort = 9081;
protected final int tesseraRestPort = 9081;
private final int tesseraQ2TRestPort = 9003;
private final String hostTesseraResources = "/tessera";
private final String containerTesseraResources = "/tmp/tessera";
private final String tesseraP2pPort = "9001";
Expand Down Expand Up @@ -123,13 +114,14 @@ public class ContainerTestBase {
@Before
public void setUp() throws IOException, InterruptedException {
besuWeb3j =
buildWeb3J(besuContainer.getContainerIpAddress(), besuContainer.getMappedPort(besuRpcPort));
buildWeb3JQuorum(
besuContainer.getContainerIpAddress(), besuContainer.getMappedPort(besuRpcPort));
goQuorumWeb3j =
buildWeb3JQuorum(
goQuorumContainer.getContainerIpAddress(),
goQuorumContainer.getMappedPort(goQuorumRpcPort));

waitFor(10, () -> assertClientVersion(besuWeb3j, besuVersion));
waitFor(10, () -> assertClientVersion(besuWeb3j, "dev"));
waitFor(10, () -> assertClientVersion(goQuorumWeb3j, goQuorumVersion));

// Tell GoQuorum to peer to Besu
Expand Down Expand Up @@ -160,6 +152,7 @@ private GenericContainer buildBesuContainer() {
.withExposedPorts(besuRpcPort, besuP2pPort)
.withClasspathResourceMapping(hostBesuKeyPath, containerBesuKeyPath, BindMode.READ_ONLY)
.withClasspathResourceMapping(hostGenesisPath, besuContainerGenesisPath, BindMode.READ_ONLY)
.withClasspathResourceMapping(hostKeyPath, containerKeyPath, BindMode.READ_ONLY)
.withCommand(
"--genesis-file",
besuContainerGenesisPath,
Expand All @@ -171,7 +164,14 @@ private GenericContainer buildBesuContainer() {
"--rpc-http-port",
besuRpcPort.toString(),
"--rpc-http-api",
"ADMIN,ETH,WEB3");
"ADMIN,ETH,NET,WEB3,PRIV,GOQUORUM",
"--goquorum-compatibility-enabled",
"--min-gas-price",
"0",
"--privacy-public-key-file",
"/tmp/keys/key2.pub",
"--privacy-url",
"http://" + "besuTessera" + ':' + tesseraQ2TRestPort);
}

private GenericContainer buildGoQuorumTesseraContainer(
Expand All @@ -186,13 +186,15 @@ private GenericContainer buildGoQuorumTesseraContainer(
.withClasspathResourceMapping(
hostTesseraResources, containerTesseraResources, BindMode.READ_ONLY)
.withClasspathResourceMapping(ipcPath, ipcBindDir, BindMode.READ_WRITE)
.withClasspathResourceMapping(hostKeyPath, containerKeyPath, BindMode.READ_ONLY)
.withCommand(
"--configfile " + tesseraContainerConfigFilePath,
"-o serverConfigs[1].serverAddress=unix:" + containerIpcPath,
"-o serverConfigs[0].serverAddress=http://localhost:" + tesseraRestPort,
"-o serverConfigs[1].serverAddress=unix:" + containerIpcPath,
"-o serverConfigs[2].serverAddress=http://localhost:" + tesseraP2pPort,
"-o keys.keyData[0].privateKeyPath=" + privKeyPath,
"-o keys.keyData[0].publicKeyPath=" + pubKeyPath,
"-o peer[0].url=" + "http://" + "goQuorumTessera" + ":" + tesseraP2pPort,
"-o peer[1].url=" + "http://" + "besuTessera" + ":" + tesseraP2pPort)
.withExposedPorts(tesseraRestPort)
.waitingFor(Wait.forHttp("/upcheck"));
Expand All @@ -205,11 +207,15 @@ private GenericContainer buildBesuTesseraContainer(
.withNetworkAliases("besuTessera")
.withClasspathResourceMapping(
hostTesseraResources, containerTesseraResources, BindMode.READ_ONLY)
.withClasspathResourceMapping(hostKeyPath, containerKeyPath, BindMode.READ_ONLY)
.withCommand(
"--configfile " + tesseraContainerConfigFilePath,
"-o serverConfigs[0].serverAddress=http://localhost:" + tesseraRestPort,
"-o serverConfigs[1].serverAddress=http://localhost:" + tesseraQ2TRestPort,
"-o serverConfigs[2].serverAddress=http://localhost:" + tesseraP2pPort,
"-o keys.keyData[0].privateKeyPath=" + privKeyPath,
"-o keys.keyData[0].publicKeyPath=" + pubKeyPath,
"-o peer[0].url=" + "http://" + "besuTessera" + ":" + tesseraP2pPort,
"-o peer[1].url=" + "http://" + "goQuorumTessera" + ":" + tesseraP2pPort)
.withExposedPorts(tesseraRestPort)
.waitingFor(Wait.forHttp("/upcheck"));
Expand Down Expand Up @@ -247,32 +253,19 @@ private GenericContainer buildGoQuorumContainer(
goQuorumContainerDatadir + "/nodeKey");
}

private Web3j buildWeb3J(final String containerIpAddress, final Integer mappedPort) {
return Web3j.build(new HttpService("http://" + containerIpAddress + ":" + mappedPort));
}

private Quorum buildWeb3JQuorum(final String containerIpAddress, final Integer mappedPort) {
return Quorum.build(new HttpService("http://" + containerIpAddress + ":" + mappedPort));
}

private void assertClientVersion(final Web3j web3, final String clientString) {
final TestSubscriber<Web3ClientVersion> testSubscriber = new TestSubscriber<>();
web3.web3ClientVersion().flowable().subscribe(testSubscriber);
testSubscriber.assertNoErrors();
testSubscriber.assertValue(
web3ClientVersion -> web3ClientVersion.getWeb3ClientVersion().contains(clientString));

testSubscriber.dispose();
private void assertClientVersion(final Web3j web3, final String clientString) throws IOException {
final Web3ClientVersion clientVersionResult = web3.web3ClientVersion().send();
assertThat(clientVersionResult.getWeb3ClientVersion()).contains(clientString);
}

private void assertBlockHeight(final Web3j web3j, final int blockHeight) {
final TestSubscriber<EthBlockNumber> testSubscriber = new TestSubscriber<>();
web3j.ethBlockNumber().flowable().subscribe(testSubscriber);
testSubscriber.assertNoErrors();
testSubscriber.assertValue(
ethBlockNumber -> ethBlockNumber.getBlockNumber().intValueExact() >= blockHeight);

testSubscriber.dispose();
private void assertBlockHeight(final Web3j web3j, final int blockHeight) throws IOException {
final EthBlockNumber blockNumberResult = web3j.ethBlockNumber().send();
assertThat(blockNumberResult.getBlockNumber().intValueExact())
.isGreaterThanOrEqualTo(blockHeight);
}

public static void waitFor(final int timeout, final ThrowingRunnable condition) {
Expand All @@ -286,48 +279,6 @@ private String getResourcePath(final String resourceName) {
return getClass().getResource(resourceName).getPath();
}

protected String sendGoQuorumTransaction(
final Quorum goQuorumWeb3j, final RawTransaction rawTransaction)
throws IOException, CipherException {
final EnclaveService enclaveService =
new EnclaveService(
"http://" + tesseraGoQuorumContainer.getHost(),
tesseraGoQuorumContainer.getMappedPort(tesseraRestPort),
new OkHttpClient());
final Enclave enclave = new Tessera(enclaveService, goQuorumWeb3j);
final Credentials credentials = loadCredentials();
final QuorumTransactionManager qrtxm =
new QuorumTransactionManager(
goQuorumWeb3j,
credentials,
pubKey1,
Arrays.asList(pubKey2),
enclave,
30, // Retry times
2000); // Sleep

// send the signed transaction to quorum
final EthSendTransaction sentTransaction = qrtxm.signAndSend(rawTransaction);
return sentTransaction.getTransactionHash();
}

protected TransactionReceipt getGoQuorumTransactionReceipt(
final Quorum goQuorumWeb3j, final String transactionHash)
throws IOException, TransactionException {
final PollingTransactionReceiptProcessor pollingTransactionReceiptProcessor =
new PollingTransactionReceiptProcessor(goQuorumWeb3j, 1000, 10);
return pollingTransactionReceiptProcessor.waitForTransactionReceipt(transactionHash);
}

protected BigInteger getGoQuorumTransactionCount(
final Quorum goQuorumWeb3j, final Credentials credentials) throws IOException {
/* deploy contract again using a single QuorumTransactionManager methods */
return goQuorumWeb3j
.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST)
.send()
.getTransactionCount();
}

protected Credentials loadCredentials() throws IOException, CipherException {
return Credentials.create("8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,49 +27,49 @@

import okhttp3.OkHttpClient;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.exceptions.TransactionException;
import org.web3j.protocol.http.HttpService;
import org.web3j.quorum.Quorum;
import org.web3j.quorum.enclave.Enclave;
import org.web3j.quorum.enclave.Tessera;
import org.web3j.quorum.enclave.protocol.EnclaveService;
import org.web3j.quorum.tx.QuorumTransactionManager;
import org.web3j.tx.response.PollingTransactionReceiptProcessor;

public class LocalTest {
public class ContainerTests extends ContainerTestBase {

private Quorum besuWeb3j;
private Credentials credentials;
private Enclave besuEnclave;
private EnclaveService besuEnclaveService;
private Quorum goQuorumWeb3j;
private Enclave goQuorumEnclave;
private EnclaveService goQuorumEnclaveService;
private PollingTransactionReceiptProcessor besuPollingTransactionReceiptProcessor;
private PollingTransactionReceiptProcessor goQuorumPollingTransactionReceiptProcessor;

// Private key from genesis
private final Credentials credentials =
Credentials.create("8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63");

private final String goQuorumTesseraPubKey = "3XGBIf+x8IdVQOVfIsbRnHwTYOJP/Fx84G8gMmy8qDM=";
private final String besuTesseraPubKey = "8JJLEAbq6o9m4Kqm++v0Y1n9Z2ryAFtZTyhnxSKWgws=";

@Before
public void setUp() {
besuWeb3j = Quorum.build(new HttpService("http://localhost:8546"));
besuEnclaveService = new EnclaveService("http://localhost", 9082, new OkHttpClient());
public void testSetUp() throws IOException, CipherException {
besuEnclaveService =
new EnclaveService(
"http://" + tesseraBesuContainer.getHost(),
tesseraBesuContainer.getMappedPort(tesseraRestPort),
new OkHttpClient());
besuEnclave = new Tessera(besuEnclaveService, besuWeb3j);
besuPollingTransactionReceiptProcessor =
new PollingTransactionReceiptProcessor(besuWeb3j, 1000, 10);
goQuorumWeb3j = Quorum.build(new HttpService("http://localhost:8545"));
goQuorumEnclaveService = new EnclaveService("http://localhost", 9081, new OkHttpClient());
goQuorumEnclaveService =
new EnclaveService(
"http://" + tesseraGoQuorumContainer.getHost(),
tesseraGoQuorumContainer.getMappedPort(tesseraRestPort),
new OkHttpClient());
goQuorumEnclave = new Tessera(goQuorumEnclaveService, goQuorumWeb3j);
goQuorumPollingTransactionReceiptProcessor =
new PollingTransactionReceiptProcessor(goQuorumWeb3j, 1000, 10);
credentials = loadCredentials();
}

@Ignore
@Test
public void contractShouldBeDeployedToBothNodes() throws IOException, TransactionException {
// create a GoQuorum transaction manager
Expand Down
Loading

0 comments on commit ac84bae

Please sign in to comment.