Tessera Orion-mode privacy ATs (#2166)

* Refactored privacy ATs to use both Orion and Tessera.

Signed-off-by: Mark Terry <mark.terry@consensys.net>
pull/2359/head
mark-terry 4 years ago committed by GitHub
parent 82dcdf219c
commit 3e86423457
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      .circleci/config.yml
  2. 2
      acceptance-tests/dsl/build.gradle
  3. 16
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeConfiguration.java
  4. 103
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/privacy/PrivacyNodeFactory.java
  5. 37
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/ParameterizedEnclaveTestBase.java
  6. 44
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyCluster.java
  7. 122
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java
  8. 24
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/account/PrivacyAccountResolver.java
  9. 2
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/AddToOnChainPrivacyGroupTransaction.java
  10. 2
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/transaction/CreatePrivacyGroupTransaction.java
  11. 2
      acceptance-tests/tests/build.gradle
  12. 16
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootOffchainGroupAcceptanceTest.java
  13. 35
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/PrivDebugGetStateRootOnchainGroupAcceptanceTest.java
  14. 31
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/OnChainMultiTenancyAcceptanceTest.java
  15. 13
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java
  16. 43
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/EnclaveErrorAcceptanceTest.java
  17. 11
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/EthSignerAcceptanceTest.java
  18. 24
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/Ibft2PrivacyClusterAcceptanceTest.java
  19. 40
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/OnChainPrivacyAcceptanceTest.java
  20. 2
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/OnChainPrivacyAcceptanceTestBase.java
  21. 11
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivCallAcceptanceTest.java
  22. 12
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivGetCodeAcceptanceTest.java
  23. 11
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivGetLogsAcceptanceTest.java
  24. 22
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivGetPrivateTransactionAcceptanceTest.java
  25. 24
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivacyClusterAcceptanceTest.java
  26. 37
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivacyGroupAcceptanceTest.java
  27. 12
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivacyReceiptAcceptanceTest.java
  28. 23
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivateContractPublicStateAcceptanceTest.java
  29. 11
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/PrivateLogFilterAcceptanceTest.java
  30. 2
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  31. 19
      besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java
  32. 9
      enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java
  33. 45
      enclave/src/main/java/org/hyperledger/besu/enclave/Enclave.java
  34. 2
      enclave/src/main/java/org/hyperledger/besu/enclave/EnclaveClientException.java
  35. 1
      enclave/src/main/java/org/hyperledger/besu/enclave/VertxRequestTransmitter.java
  36. 9
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivGetPrivateTransactionIntegrationTest.java
  37. 5
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/response/JsonRpcError.java
  38. 11
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java
  39. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/DefaultPrivacyControllerTest.java
  40. 2
      testutil/build.gradle
  41. 13
      testutil/src/main/java/org/hyperledger/enclave/testutil/EnclaveConfiguration.java
  42. 8
      testutil/src/main/java/org/hyperledger/enclave/testutil/EnclaveKeyConfiguration.java
  43. 6
      testutil/src/main/java/org/hyperledger/enclave/testutil/EnclaveKeyUtils.java
  44. 42
      testutil/src/main/java/org/hyperledger/enclave/testutil/EnclaveTestHarness.java
  45. 20
      testutil/src/main/java/org/hyperledger/enclave/testutil/EnclaveType.java
  46. 50
      testutil/src/main/java/org/hyperledger/enclave/testutil/OrionTestHarness.java
  47. 11
      testutil/src/main/java/org/hyperledger/enclave/testutil/OrionTestHarnessFactory.java
  48. 284
      testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarness.java
  49. 84
      testutil/src/main/java/org/hyperledger/enclave/testutil/TesseraTestHarnessFactory.java
  50. 0
      testutil/src/main/resources/enclave_key_0.key
  51. 0
      testutil/src/main/resources/enclave_key_0.pub
  52. 0
      testutil/src/main/resources/enclave_key_1.key
  53. 0
      testutil/src/main/resources/enclave_key_1.pub
  54. 0
      testutil/src/main/resources/enclave_key_2.key
  55. 0
      testutil/src/main/resources/enclave_key_2.pub

@ -24,7 +24,7 @@ executors:
machine:
image: ubuntu-2004:202010-01
goquorum_executor:
xl_machine_executor:
machine:
image: ubuntu-2004:202101-01
resource_class: xlarge
@ -175,14 +175,14 @@ jobs:
acceptanceTests:
parallelism: 6
executor: besu_executor_xl
executor: xl_machine_executor
steps:
- prepare
- attach_workspace:
at: ~/project
- run:
name: AcceptanceTests
no_output_timeout: 40m
no_output_timeout: 30m
command: |
CLASSNAMES=$(circleci tests glob "acceptance-tests/tests/src/test/java/**/*.java" \
| sed 's@.*/src/test/java/@@' \
@ -197,7 +197,7 @@ jobs:
acceptanceTestsQuorum:
parallelism: 1
executor: goquorum_executor
executor: xl_machine_executor
steps:
- prepare
- attach_workspace:

@ -45,4 +45,6 @@ dependencies {
implementation 'tech.pegasys.ethsigner.internal:ethsigner-core'
implementation 'tech.pegasys.signers.internal:signing-secp256k1-api'
implementation 'tech.pegasys.signers.internal:signing-secp256k1-impl'
implementation 'org.testcontainers:testcontainers'
}

@ -15,21 +15,21 @@
package org.hyperledger.besu.tests.acceptance.dsl.node.configuration.privacy;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.BesuNodeConfiguration;
import org.hyperledger.orion.testutil.OrionKeyConfiguration;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
public class PrivacyNodeConfiguration {
private final int privacyAddress;
private final boolean isOnchainPrivacyGroupEnabled;
private final BesuNodeConfiguration besuConfig;
private final OrionKeyConfiguration orionConfig;
private final EnclaveKeyConfiguration keyConfig;
private final boolean isMultitenancyEnabled;
PrivacyNodeConfiguration(
final int privacyAddress,
final BesuNodeConfiguration besuConfig,
final OrionKeyConfiguration orionConfig) {
this(privacyAddress, false, false, besuConfig, orionConfig);
final EnclaveKeyConfiguration keyConfig) {
this(privacyAddress, false, false, besuConfig, keyConfig);
}
PrivacyNodeConfiguration(
@ -37,11 +37,11 @@ public class PrivacyNodeConfiguration {
final boolean isOnchainPrivacyGroupEnabled,
final boolean isMultitenancyEnabled,
final BesuNodeConfiguration besuConfig,
final OrionKeyConfiguration orionConfig) {
final EnclaveKeyConfiguration keyConfig) {
this.privacyAddress = privacyAddress;
this.isOnchainPrivacyGroupEnabled = isOnchainPrivacyGroupEnabled;
this.besuConfig = besuConfig;
this.orionConfig = orionConfig;
this.keyConfig = keyConfig;
this.isMultitenancyEnabled = isMultitenancyEnabled;
}
@ -61,7 +61,7 @@ public class PrivacyNodeConfiguration {
return besuConfig;
}
public OrionKeyConfiguration getOrionKeyConfig() {
return orionConfig;
public EnclaveKeyConfiguration getKeyConfig() {
return keyConfig;
}
}

@ -20,12 +20,15 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.NodeConfigur
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationFactory;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccount;
import org.hyperledger.orion.testutil.OrionKeyConfiguration;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Optional;
import io.vertx.core.Vertx;
import org.testcontainers.containers.Network;
public class PrivacyNodeFactory {
@ -37,17 +40,30 @@ public class PrivacyNodeFactory {
this.vertx = vertx;
}
private PrivacyNode create(final PrivacyNodeConfiguration privacyNodeConfig) throws IOException {
return new PrivacyNode(privacyNodeConfig, vertx);
private PrivacyNode create(
final PrivacyNodeConfiguration privacyNodeConfig,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return new PrivacyNode(privacyNodeConfig, vertx, enclaveType, containerNetwork);
}
public PrivacyNode createPrivateTransactionEnabledMinerNode(
final String name, final PrivacyAccount privacyAccount) throws IOException {
return createPrivateTransactionEnabledMinerNode(name, privacyAccount, Address.PRIVACY);
final String name,
final PrivacyAccount privacyAccount,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return createPrivateTransactionEnabledMinerNode(
name, privacyAccount, Address.PRIVACY, enclaveType, containerNetwork);
}
public PrivacyNode createPrivateTransactionEnabledMinerNode(
final String name, final PrivacyAccount privacyAccount, final int privacyAddress)
final String name,
final PrivacyAccount privacyAccount,
final int privacyAddress,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return create(
new PrivacyNodeConfiguration(
@ -60,17 +76,28 @@ public class PrivacyNodeFactory {
.enablePrivateTransactions()
.keyFilePath(privacyAccount.getPrivateKeyPath())
.build(),
new OrionKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())));
new EnclaveKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())),
enclaveType,
containerNetwork);
}
public PrivacyNode createPrivateTransactionEnabledNode(
final String name, final PrivacyAccount privacyAccount) throws IOException {
return createPrivateTransactionEnabledNode(name, privacyAccount, Address.PRIVACY);
final String name,
final PrivacyAccount privacyAccount,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return createPrivateTransactionEnabledNode(
name, privacyAccount, Address.PRIVACY, enclaveType, containerNetwork);
}
public PrivacyNode createPrivateTransactionEnabledNode(
final String name, final PrivacyAccount privacyAccount, final int privacyAddress)
final String name,
final PrivacyAccount privacyAccount,
final int privacyAddress,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return create(
new PrivacyNodeConfiguration(
@ -82,25 +109,39 @@ public class PrivacyNodeFactory {
.enablePrivateTransactions()
.webSocketEnabled()
.build(),
new OrionKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())));
new EnclaveKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())),
enclaveType,
containerNetwork);
}
public PrivacyNode createIbft2NodePrivacyMiningEnabled(
final String name, final PrivacyAccount privacyAccount) throws IOException {
return createIbft2NodePrivacyEnabled(name, privacyAccount, Address.PRIVACY, true);
final String name,
final PrivacyAccount privacyAccount,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return createIbft2NodePrivacyEnabled(
name, privacyAccount, Address.PRIVACY, true, enclaveType, containerNetwork);
}
public PrivacyNode createIbft2NodePrivacyEnabled(
final String name, final PrivacyAccount privacyAccount) throws IOException {
return createIbft2NodePrivacyEnabled(name, privacyAccount, Address.PRIVACY, false);
final String name,
final PrivacyAccount privacyAccount,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return createIbft2NodePrivacyEnabled(
name, privacyAccount, Address.PRIVACY, false, enclaveType, containerNetwork);
}
public PrivacyNode createIbft2NodePrivacyEnabled(
final String name,
final PrivacyAccount privacyAccount,
final int privacyAddress,
final boolean minerEnabled)
final boolean minerEnabled,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return create(
new PrivacyNodeConfiguration(
@ -115,15 +156,19 @@ public class PrivacyNodeFactory {
.keyFilePath(privacyAccount.getPrivateKeyPath())
.enablePrivateTransactions()
.build(),
new OrionKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())));
new EnclaveKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())),
enclaveType,
containerNetwork);
}
public PrivacyNode createOnChainPrivacyGroupEnabledMinerNode(
final String name,
final PrivacyAccount privacyAccount,
final int privacyAddress,
final boolean multiTenancyEnabled)
final boolean multiTenancyEnabled,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException, URISyntaxException {
final BesuNodeConfigurationBuilder besuNodeConfigurationBuilder =
new BesuNodeConfigurationBuilder();
@ -144,15 +189,19 @@ public class PrivacyNodeFactory {
.enablePrivateTransactions()
.keyFilePath(privacyAccount.getPrivateKeyPath())
.build(),
new OrionKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())));
new EnclaveKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())),
enclaveType,
containerNetwork);
}
public PrivacyNode createOnChainPrivacyGroupEnabledNode(
final String name,
final PrivacyAccount privacyAccount,
final int privacyAddress,
final boolean multiTenancyEnabled)
final boolean multiTenancyEnabled,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
return create(
new PrivacyNodeConfiguration(
@ -166,7 +215,9 @@ public class PrivacyNodeFactory {
.enablePrivateTransactions()
.webSocketEnabled()
.build(),
new OrionKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())));
new EnclaveKeyConfiguration(
privacyAccount.getEnclaveKeyPaths(), privacyAccount.getEnclavePrivateKeyPaths())),
enclaveType,
containerNetwork);
}
}

@ -0,0 +1,37 @@
/*
* Copyright 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.tests.acceptance.dsl.privacy;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.util.Arrays;
import java.util.Collection;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public abstract class ParameterizedEnclaveTestBase extends PrivacyAcceptanceTestBase {
protected final EnclaveType enclaveType;
protected ParameterizedEnclaveTestBase(final EnclaveType enclaveType) {
this.enclaveType = enclaveType;
}
@Parameterized.Parameters(name = "{0}")
public static Collection<EnclaveType> enclaveTypes() {
return Arrays.asList(EnclaveType.values());
}
}

@ -15,11 +15,15 @@
package org.hyperledger.besu.tests.acceptance.dsl.privacy;
import static java.util.Collections.emptyList;
import static java.util.function.Predicate.not;
import org.hyperledger.besu.tests.acceptance.dsl.condition.net.NetConditions;
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNodeRunner;
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
import org.hyperledger.enclave.testutil.EnclaveType;
import org.hyperledger.enclave.testutil.TesseraTestHarness;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -61,7 +65,7 @@ public class PrivacyCluster {
throw new IllegalArgumentException("Can't start a cluster with no nodes");
}
this.nodes = nodes;
this.runnableNodes = nodes.stream().map(n -> n.getBesu()).collect(Collectors.toList());
this.runnableNodes = nodes.stream().map(PrivacyNode::getBesu).collect(Collectors.toList());
final Optional<PrivacyNode> bootNode = selectAndStartBootnode(nodes);
@ -80,18 +84,23 @@ public class PrivacyCluster {
node.awaitPeerDiscovery(net.awaitPeerCount(nodes.size() - 1));
}
verifyAllOrionNetworkConnections();
verifyAllEnclaveNetworkConnections();
}
public List<PrivacyNode> getNodes() {
return nodes;
}
/** Verify that each Orion node has connected to every other Orion */
public void verifyAllOrionNetworkConnections() {
for (int i = 0; i < nodes.size() - 1; i++) {
nodes.get(i).testOrionConnection(nodes.subList(i + 1, nodes.size()));
}
/** Verify that each Enclave has connected to every other Enclave */
public void verifyAllEnclaveNetworkConnections() {
nodes.forEach(
privacyNode -> {
final List<PrivacyNode> otherNodes =
nodes.stream()
.filter(not(privacyNode::equals))
.collect(Collectors.toUnmodifiableList());
privacyNode.testEnclaveConnection(otherNodes);
});
}
public void stop() {
@ -101,7 +110,7 @@ public class PrivacyCluster {
}
public void stopNode(final PrivacyNode node) {
node.getOrion().stop();
node.getEnclave().stop();
besuNodeRunner.stopNode(node.getBesu());
}
@ -145,7 +154,24 @@ public class PrivacyCluster {
.ifPresent(node.getConfiguration()::setGenesisConfig);
if (!isBootNode) {
node.addOtherEnclaveNode(bootNode.getOrion().nodeUrl());
if (bootNode.getEnclave().getEnclaveType() == EnclaveType.TESSERA) {
final URI otherNode = bootNode.getEnclave().nodeUrl();
try {
// Substitute IP with hostname for test container network
final URI otherNodeHostname =
new URI(
otherNode.getScheme()
+ "://"
+ bootNode.getName()
+ ":"
+ TesseraTestHarness.p2pPort);
node.addOtherEnclaveNode(otherNodeHostname);
} catch (Exception ex) {
throw new RuntimeException("Invalid node URI");
}
} else {
node.addOtherEnclaveNode(bootNode.getEnclave().nodeUrl());
}
}
LOG.info(

@ -41,8 +41,10 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.NodeConfigur
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.privacy.PrivacyNodeConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.condition.PrivateCondition;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
import org.hyperledger.orion.testutil.OrionTestHarness;
import org.hyperledger.orion.testutil.OrionTestHarnessFactory;
import org.hyperledger.enclave.testutil.EnclaveTestHarness;
import org.hyperledger.enclave.testutil.EnclaveType;
import org.hyperledger.enclave.testutil.OrionTestHarnessFactory;
import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory;
import java.io.IOException;
import java.net.URI;
@ -51,12 +53,14 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import io.vertx.core.Vertx;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.awaitility.Awaitility;
import org.testcontainers.containers.Network;
public class PrivacyNode implements AutoCloseable {
@ -66,19 +70,25 @@ public class PrivacyNode implements AutoCloseable {
private static final int MAX_BACKGROUND_COMPACTIONS = 4;
private static final int BACKGROUND_THREAD_COUNT = 4;
private final OrionTestHarness orion;
private final EnclaveTestHarness enclave;
private final BesuNode besu;
private final Vertx vertx;
private final boolean isOnchainPrivacyEnabled;
private final boolean isMultitenancyEnabled;
public PrivacyNode(final PrivacyNodeConfiguration privacyConfiguration, final Vertx vertx)
public PrivacyNode(
final PrivacyNodeConfiguration privacyConfiguration,
final Vertx vertx,
final EnclaveType enclaveType,
final Optional<Network> containerNetwork)
throws IOException {
final Path orionDir = Files.createTempDirectory("acctest-orion");
this.orion = OrionTestHarnessFactory.create(orionDir, privacyConfiguration.getOrionKeyConfig());
final Path enclaveDir = Files.createTempDirectory("acctest-orion");
final BesuNodeConfiguration config = privacyConfiguration.getBesuConfig();
this.enclave =
selectEnclave(enclaveType, enclaveDir, config, privacyConfiguration, containerNetwork);
this.vertx = vertx;
final BesuNodeConfiguration besuConfig = privacyConfiguration.getBesuConfig();
final BesuNodeConfiguration besuConfig = config;
isOnchainPrivacyEnabled = privacyConfiguration.isOnchainPrivacyGroupEnabled();
isMultitenancyEnabled = privacyConfiguration.isMultitenancyEnabled();
@ -111,39 +121,44 @@ public class PrivacyNode implements AutoCloseable {
List.of());
}
public void testOrionConnection(final List<PrivacyNode> otherNodes) {
LOG.info(
String.format(
"Testing Enclave connectivity between %s (%s) and %s (%s)",
besu.getName(),
orion.nodeUrl(),
Arrays.toString(otherNodes.stream().map(node -> node.besu.getName()).toArray()),
Arrays.toString(otherNodes.stream().map(node -> node.orion.nodeUrl()).toArray())));
final EnclaveFactory factory = new EnclaveFactory(vertx);
final Enclave enclaveClient = factory.createVertxEnclave(orion.clientUrl());
final String payload = "SGVsbG8sIFdvcmxkIQ==";
final List<String> to =
otherNodes.stream()
.map(node -> node.orion.getDefaultPublicKey())
.collect(Collectors.toList());
Awaitility.await()
.until(
() -> {
try {
enclaveClient.send(payload, orion.getDefaultPublicKey(), to);
return true;
} catch (final EnclaveClientException
| EnclaveIOException
| EnclaveServerException e) {
LOG.warn("Waiting for enclave connectivity");
return false;
}
});
}
public OrionTestHarness getOrion() {
return orion;
public void testEnclaveConnection(final List<PrivacyNode> otherNodes) {
if (!otherNodes.isEmpty()) {
LOG.debug(
String.format(
"Testing Enclave connectivity between %s (%s) and %s (%s)",
besu.getName(),
enclave.nodeUrl(),
Arrays.toString(otherNodes.stream().map(node -> node.besu.getName()).toArray()),
Arrays.toString(otherNodes.stream().map(node -> node.enclave.nodeUrl()).toArray())));
final EnclaveFactory factory = new EnclaveFactory(vertx);
final Enclave enclaveClient = factory.createVertxEnclave(enclave.clientUrl());
final String payload = "SGVsbG8sIFdvcmxkIQ==";
final List<String> to =
otherNodes.stream()
.map(node -> node.enclave.getDefaultPublicKey())
.collect(Collectors.toList());
Awaitility.await()
.until(
() -> {
try {
enclaveClient.send(payload, enclave.getDefaultPublicKey(), to);
return true;
} catch (final EnclaveClientException
| EnclaveIOException
| EnclaveServerException e) {
LOG.warn(
"Waiting for enclave connectivity between {} and {}: " + e.getMessage(),
enclave.getDefaultPublicKey(),
to.get(0));
return false;
}
});
}
}
public EnclaveTestHarness getEnclave() {
return enclave;
}
public BesuNode getBesu() {
@ -152,17 +167,17 @@ public class PrivacyNode implements AutoCloseable {
public void stop() {
besu.stop();
orion.stop();
enclave.stop();
}
@Override
public void close() {
besu.close();
orion.close();
enclave.close();
}
public void start(final BesuNodeRunner runner) {
orion.start();
enclave.start();
final PrivacyParameters privacyParameters;
@ -173,8 +188,8 @@ public class PrivacyNode implements AutoCloseable {
privacyParameters =
new PrivacyParameters.Builder()
.setEnabled(true)
.setEnclaveUrl(orion.clientUrl())
.setEnclavePublicKeyUsingFile(orion.getConfig().publicKeys().get(0).toFile())
.setEnclaveUrl(enclave.clientUrl())
.setEnclavePublicKeyUsingFile(enclave.getPublicKeyPaths().get(0).toFile())
.setStorageProvider(createKeyValueStorageProvider(dataDir, dbDir))
.setPrivateKeyPath(KeyPairUtil.getDefaultKeyFile(besu.homeDirectory()).toPath())
.setEnclaveFactory(new EnclaveFactory(vertx))
@ -217,7 +232,7 @@ public class PrivacyNode implements AutoCloseable {
}
public String getEnclaveKey() {
return orion.getDefaultPublicKey();
return enclave.getDefaultPublicKey();
}
public String getTransactionSigningKey() {
@ -225,7 +240,7 @@ public class PrivacyNode implements AutoCloseable {
}
public void addOtherEnclaveNode(final URI otherNode) {
orion.addOtherNode(otherNode);
enclave.addOtherNode(otherNode);
}
public NodeConfiguration getConfiguration() {
@ -250,4 +265,17 @@ public class PrivacyNode implements AutoCloseable {
.withMetricsSystem(new NoOpMetricsSystem())
.build();
}
private EnclaveTestHarness selectEnclave(
final EnclaveType enclaveType,
final Path tempDir,
final BesuNodeConfiguration config,
final PrivacyNodeConfiguration privacyConfiguration,
final Optional<Network> containerNetwork) {
return enclaveType == EnclaveType.TESSERA
? TesseraTestHarnessFactory.create(
config.getName(), tempDir, privacyConfiguration.getKeyConfig(), containerNetwork)
: OrionTestHarnessFactory.create(
config.getName(), tempDir, privacyConfiguration.getKeyConfig());
}
}

@ -22,33 +22,33 @@ public class PrivacyAccountResolver {
public static final PrivacyAccount ALICE =
PrivacyAccount.create(
resolveResource("key"),
resolveResource("orion_key_0.pub"),
resolveResource("orion_key_0.key"));
resolveResource("enclave_key_0.pub"),
resolveResource("enclave_key_0.key"));
public static final PrivacyAccount BOB =
PrivacyAccount.create(
resolveResource("key1"),
resolveResource("orion_key_1.pub"),
resolveResource("orion_key_1.key"));
resolveResource("enclave_key_1.pub"),
resolveResource("enclave_key_1.key"));
public static final PrivacyAccount CHARLIE =
PrivacyAccount.create(
resolveResource("key2"),
resolveResource("orion_key_2.pub"),
resolveResource("orion_key_2.key"));
resolveResource("enclave_key_2.pub"),
resolveResource("enclave_key_2.key"));
public static final PrivacyAccount MULTI_TENANCY =
PrivacyAccount.create(
resolveResource("key"),
new URL[] {
resolveResource("orion_key_0.pub"),
resolveResource("orion_key_1.pub"),
resolveResource("orion_key_2.pub")
resolveResource("enclave_key_0.pub"),
resolveResource("enclave_key_1.pub"),
resolveResource("enclave_key_2.pub")
},
new URL[] {
resolveResource("orion_key_0.key"),
resolveResource("orion_key_1.key"),
resolveResource("orion_key_2.key")
resolveResource("enclave_key_0.key"),
resolveResource("enclave_key_1.key"),
resolveResource("enclave_key_2.key")
});
private static URL resolveResource(final String resource) {

@ -42,7 +42,7 @@ public class AddToOnChainPrivacyGroupTransaction implements Transaction<String>
this.signer = signer;
this.addresses =
Arrays.stream(nodes)
.map(n -> n.getOrion().getDefaultPublicKey())
.map(n -> n.getEnclave().getDefaultPublicKey())
.collect(Collectors.toList());
}

@ -38,7 +38,7 @@ public class CreatePrivacyGroupTransaction implements Transaction<String> {
this.description = description;
this.addresses =
Arrays.stream(nodes)
.map(n -> Base64String.wrap(n.getOrion().getDefaultPublicKey()))
.map(n -> Base64String.wrap(n.getEnclave().getDefaultPublicKey()))
.collect(Collectors.toList());
}

@ -54,6 +54,8 @@ dependencies {
testImplementation 'org.awaitility:awaitility'
testImplementation 'org.web3j:abi'
testImplementation 'org.web3j:besu'
testImplementation 'org.testcontainers:testcontainers'
}
test.enabled = false

@ -17,31 +17,39 @@ package org.hyperledger.besu.tests.acceptance.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.Before;
import org.junit.Test;
import org.testcontainers.containers.Network;
public class PrivDebugGetStateRootOffchainGroupAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivDebugGetStateRootOffchainGroupAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivDebugGetStateRootOffchainGroupAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode aliceNode;
private PrivacyNode bobNode;
@Before
public void setUp() throws IOException, URISyntaxException {
final Network containerNetwork = Network.newNetwork();
aliceNode =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"alice-node", PrivacyAccountResolver.ALICE);
"alice-node", PrivacyAccountResolver.ALICE, enclaveType, Optional.of(containerNetwork));
bobNode =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"bob-node", PrivacyAccountResolver.BOB);
"bob-node", PrivacyAccountResolver.BOB, enclaveType, Optional.of(containerNetwork));
privacyCluster.start(aliceNode, bobNode);
}

@ -22,28 +22,59 @@ import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.account.PrivacyAccountResolver;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory;
import org.hyperledger.besu.tests.web3j.privacy.OnChainPrivacyAcceptanceTestBase;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.testcontainers.containers.Network;
@RunWith(Parameterized.class)
public class PrivDebugGetStateRootOnchainGroupAcceptanceTest
extends OnChainPrivacyAcceptanceTestBase {
private final EnclaveType enclaveType;
public PrivDebugGetStateRootOnchainGroupAcceptanceTest(final EnclaveType enclaveType) {
this.enclaveType = enclaveType;
}
@Parameterized.Parameters(name = "{0}")
public static Collection<EnclaveType> enclaveTypes() {
return Arrays.asList(EnclaveType.values());
}
private PrivacyNode aliceNode;
private PrivacyNode bobNode;
@Before
public void setUp() throws IOException, URISyntaxException {
final Network containerNetwork = Network.newNetwork();
aliceNode =
privacyBesu.createOnChainPrivacyGroupEnabledMinerNode(
"alice-node", PrivacyAccountResolver.ALICE, Address.PRIVACY, false);
"alice-node",
PrivacyAccountResolver.ALICE,
Address.PRIVACY,
false,
enclaveType,
Optional.of(containerNetwork));
bobNode =
privacyBesu.createOnChainPrivacyGroupEnabledNode(
"bob-node", PrivacyAccountResolver.BOB, Address.PRIVACY, false);
"bob-node",
PrivacyAccountResolver.BOB,
Address.PRIVACY,
false,
enclaveType,
Optional.of(containerNetwork));
privacyCluster.start(aliceNode, bobNode);
}

@ -28,22 +28,40 @@ import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.PermissioningT
import org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy.PrivacyRequestFactory;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.besu.tests.web3j.privacy.OnChainPrivacyAcceptanceTestBase;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthCall;
import org.web3j.utils.Base64String;
@RunWith(Parameterized.class)
public class OnChainMultiTenancyAcceptanceTest extends OnChainPrivacyAcceptanceTestBase {
private final EnclaveType enclaveType;
public OnChainMultiTenancyAcceptanceTest(final EnclaveType enclaveType) {
this.enclaveType = enclaveType;
}
@Parameterized.Parameters(name = "{0}")
public static Collection<EnclaveType> enclaveTypes() {
return Arrays.asList(EnclaveType.values());
}
private static final String eventEmitterDeployed =
"0x6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029";
@ -58,7 +76,12 @@ public class OnChainMultiTenancyAcceptanceTest extends OnChainPrivacyAcceptanceT
public void setUp() throws Exception {
alice =
privacyBesu.createOnChainPrivacyGroupEnabledMinerNode(
"node1", PrivacyAccountResolver.MULTI_TENANCY, Address.PRIVACY, true);
"node1",
PrivacyAccountResolver.MULTI_TENANCY,
Address.PRIVACY,
true,
enclaveType,
Optional.empty());
final BesuNode aliceBesu = alice.getBesu();
privacyCluster.startNodes(alice);
final String alice1Token =
@ -70,9 +93,9 @@ public class OnChainMultiTenancyAcceptanceTest extends OnChainPrivacyAcceptanceT
aliceBesu.execute(permissioningTransactions.createSuccessfulLogin("user3", "Password3"));
privacyCluster.awaitPeerCount(alice);
final String alice1EnclaveKey = alice.getOrion().getPublicKeys().get(0);
final String alice2EnclaveKey = alice.getOrion().getPublicKeys().get(1);
final String alice3EnclaveKey = alice.getOrion().getPublicKeys().get(2);
final String alice1EnclaveKey = alice.getEnclave().getPublicKeys().get(0);
final String alice2EnclaveKey = alice.getEnclave().getPublicKeys().get(1);
final String alice3EnclaveKey = alice.getEnclave().getPublicKeys().get(2);
aliceMultiTenancyPrivacyNode = new MultiTenancyPrivacyNode(alice);
aliceMultiTenancyPrivacyNode

@ -14,14 +14,21 @@
*/
package org.hyperledger.besu.tests.web3j.privacy;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
public class DeployPrivateSmartContractAcceptanceTest extends PrivacyAcceptanceTestBase {
public class DeployPrivateSmartContractAcceptanceTest extends ParameterizedEnclaveTestBase {
public DeployPrivateSmartContractAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private static final long POW_CHAIN_ID = 1337;
@ -31,7 +38,7 @@ public class DeployPrivateSmartContractAcceptanceTest extends PrivacyAcceptanceT
public void setUp() throws Exception {
minerNode =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"miner-node", privacyAccountResolver.resolve(0));
"miner-node", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(minerNode);
}

@ -18,20 +18,27 @@ import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Base64;
import java.util.Optional;
import org.apache.tuweni.crypto.sodium.Box;
import org.assertj.core.api.Condition;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.testcontainers.containers.Network;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
public class EnclaveErrorAcceptanceTest extends ParameterizedEnclaveTestBase {
public EnclaveErrorAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private static final long IBFT2_CHAIN_ID = 4;
@ -41,8 +48,14 @@ public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
@Before
public void setUp() throws Exception {
alice = privacyBesu.createIbft2NodePrivacyEnabled("node1", privacyAccountResolver.resolve(0));
bob = privacyBesu.createIbft2NodePrivacyEnabled("node2", privacyAccountResolver.resolve(1));
final Network containerNetwork = Network.newNetwork();
alice =
privacyBesu.createIbft2NodePrivacyEnabled(
"node1", privacyAccountResolver.resolve(0), enclaveType, Optional.of(containerNetwork));
bob =
privacyBesu.createIbft2NodePrivacyEnabled(
"node2", privacyAccountResolver.resolve(1), enclaveType, Optional.of(containerNetwork));
privacyCluster.start(alice, bob);
wrongPublicKey =
@ -80,7 +93,11 @@ public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
alice.getEnclaveKey(),
wrongPublicKey)));
assertThat(throwable).hasMessageContaining(JsonRpcError.NODE_MISSING_PEER_URL.getMessage());
final String orionMessage = JsonRpcError.NODE_MISSING_PEER_URL.getMessage();
final String tesseraMessage = JsonRpcError.TESSERA_NODE_MISSING_PEER_URL.getMessage();
assertThat(throwable.getMessage())
.has(matchOrionOrTesseraMessage(orionMessage, tesseraMessage));
}
@Test
@ -116,7 +133,7 @@ public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
privateTransactionVerifier.validPrivateTransactionReceipt(
transactionHash, receiptBeforeEnclaveLosesConnection));
alice.getOrion().stop();
alice.getEnclave().stop();
alice.verify(
privateTransactionVerifier.internalErrorPrivateTransactionReceipt(transactionHash));
@ -141,7 +158,7 @@ public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
.validPrivateContractDeployed(contractAddress, alice.getAddress().toString())
.verify(eventEmitter);
bob.getOrion().stop();
bob.getEnclave().stop();
final Throwable throwable =
catchThrowable(
@ -162,7 +179,17 @@ public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
public void createPrivacyGroupReturnsCorrectError() {
final Throwable throwable =
catchThrowable(() -> alice.execute(privacyTransactions.createPrivacyGroup(null, null)));
final String orionMessage = JsonRpcError.CREATE_GROUP_INCLUDE_SELF.getMessage();
final String tesseraMessage = JsonRpcError.TESSERA_CREATE_GROUP_INCLUDE_SELF.getMessage();
assertThat(throwable.getMessage())
.has(matchOrionOrTesseraMessage(orionMessage, tesseraMessage));
}
assertThat(throwable).hasMessageContaining(JsonRpcError.CREATE_GROUP_INCLUDE_SELF.getMessage());
private Condition<String> matchOrionOrTesseraMessage(
final String orionMessage, final String tesseraMessage) {
return new Condition<>(
message -> message.contains(orionMessage) || message.contains(tesseraMessage),
"Message did not match either Orion or Tessera expected output");
}
}

@ -17,13 +17,15 @@ package org.hyperledger.besu.tests.web3j.privacy;
import org.hyperledger.besu.tests.acceptance.dsl.ethsigner.EthSignerClient;
import org.hyperledger.besu.tests.acceptance.dsl.ethsigner.testutil.EthSignerTestHarness;
import org.hyperledger.besu.tests.acceptance.dsl.ethsigner.testutil.EthSignerTestHarnessFactory;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Collections;
import java.util.Optional;
import org.junit.Before;
import org.junit.Ignore;
@ -32,7 +34,10 @@ import org.web3j.protocol.besu.response.privacy.PrivacyGroup;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.utils.Base64String;
public class EthSignerAcceptanceTest extends PrivacyAcceptanceTestBase {
public class EthSignerAcceptanceTest extends ParameterizedEnclaveTestBase {
public EthSignerAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode minerNode;
private EthSignerTestHarness ethSigner;
@ -43,7 +48,7 @@ public class EthSignerAcceptanceTest extends PrivacyAcceptanceTestBase {
public void setUp() throws Exception {
minerNode =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"miner-node", privacyAccountResolver.resolve(0));
"miner-node", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(minerNode);
ethSigner =

@ -14,17 +14,23 @@
*/
package org.hyperledger.besu.tests.web3j.privacy;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.testcontainers.containers.Network;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
public class Ibft2PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase {
public class Ibft2PrivacyClusterAcceptanceTest extends ParameterizedEnclaveTestBase {
public Ibft2PrivacyClusterAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private static final long IBFT2_CHAIN_ID = 4;
@ -34,9 +40,17 @@ public class Ibft2PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase
@Before
public void setUp() throws Exception {
alice = privacyBesu.createIbft2NodePrivacyEnabled("node1", privacyAccountResolver.resolve(0));
bob = privacyBesu.createIbft2NodePrivacyEnabled("node2", privacyAccountResolver.resolve(1));
charlie = privacyBesu.createIbft2NodePrivacyEnabled("node3", privacyAccountResolver.resolve(2));
final Network containerNetwork = Network.newNetwork();
alice =
privacyBesu.createIbft2NodePrivacyEnabled(
"node1", privacyAccountResolver.resolve(0), enclaveType, Optional.of(containerNetwork));
bob =
privacyBesu.createIbft2NodePrivacyEnabled(
"node2", privacyAccountResolver.resolve(1), enclaveType, Optional.of(containerNetwork));
charlie =
privacyBesu.createIbft2NodePrivacyEnabled(
"node3", privacyAccountResolver.resolve(2), enclaveType, Optional.of(containerNetwork));
privacyCluster.start(alice, bob, charlie);
}

@ -22,9 +22,11 @@ import org.hyperledger.besu.tests.acceptance.dsl.condition.eth.EthConditions;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerTransactions;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -32,6 +34,9 @@ import java.util.Optional;
import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.testcontainers.containers.Network;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthCall;
@ -39,8 +44,20 @@ import org.web3j.protocol.core.methods.response.Log;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
@RunWith(Parameterized.class)
public class OnChainPrivacyAcceptanceTest extends OnChainPrivacyAcceptanceTestBase {
private final EnclaveType enclaveType;
public OnChainPrivacyAcceptanceTest(final EnclaveType enclaveType) {
this.enclaveType = enclaveType;
}
@Parameterized.Parameters(name = "{0}")
public static Collection<EnclaveType> enclaveTypes() {
return Arrays.asList(EnclaveType.values());
}
protected static final long POW_CHAIN_ID = 1337;
private PrivacyNode alice;
@ -57,15 +74,32 @@ public class OnChainPrivacyAcceptanceTest extends OnChainPrivacyAcceptanceTestBa
@Before
public void setUp() throws Exception {
final Network containerNetwork = Network.newNetwork();
alice =
privacyBesu.createOnChainPrivacyGroupEnabledMinerNode(
"node1", privacyAccountResolver.resolve(0), Address.PRIVACY, false);
"node1",
privacyAccountResolver.resolve(0),
Address.PRIVACY,
false,
enclaveType,
Optional.of(containerNetwork));
bob =
privacyBesu.createOnChainPrivacyGroupEnabledNode(
"node2", privacyAccountResolver.resolve(1), Address.PRIVACY, false);
"node2",
privacyAccountResolver.resolve(1),
Address.PRIVACY,
false,
enclaveType,
Optional.of(containerNetwork));
charlie =
privacyBesu.createOnChainPrivacyGroupEnabledNode(
"node3", privacyAccountResolver.resolve(2), Address.PRIVACY, false);
"node3",
privacyAccountResolver.resolve(2),
Address.PRIVACY,
false,
enclaveType,
Optional.of(containerNetwork));
privacyCluster.start(alice, bob, charlie);
}

@ -41,7 +41,7 @@ public class OnChainPrivacyAcceptanceTestBase extends PrivacyAcceptanceTestBase
protected String createOnChainPrivacyGroup(final PrivacyNode... members) {
final List<String> addresses =
Arrays.asList(members).stream().map(m -> m.getEnclaveKey()).collect(Collectors.toList());
Arrays.stream(members).map(PrivacyNode::getEnclaveKey).collect(Collectors.toList());
return createOnChainPrivacyGroup(members[0].getEnclaveKey(), addresses, members);
}

@ -17,15 +17,17 @@ package org.hyperledger.besu.tests.web3j.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
@ -43,7 +45,10 @@ import org.web3j.protocol.exceptions.ClientConnectionException;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Contract;
public class PrivCallAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivCallAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivCallAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private static final long POW_CHAIN_ID = 1337;
private static final int VALUE = 1024;
@ -54,7 +59,7 @@ public class PrivCallAcceptanceTest extends PrivacyAcceptanceTestBase {
public void setUp() throws Exception {
minerNode =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"miner-node", privacyAccountResolver.resolve(0));
"miner-node", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(minerNode);
}

@ -17,9 +17,12 @@ package org.hyperledger.besu.tests.web3j.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
@ -27,7 +30,10 @@ import org.junit.Test;
import org.web3j.protocol.besu.response.privacy.PrivacyGroup;
import org.web3j.utils.Base64String;
public class PrivGetCodeAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivGetCodeAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivGetCodeAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode alice;
@ -35,7 +41,7 @@ public class PrivGetCodeAcceptanceTest extends PrivacyAcceptanceTestBase {
public void setUp() throws Exception {
alice =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"alice", privacyAccountResolver.resolve(0));
"alice", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(alice);
}

@ -16,13 +16,15 @@ package org.hyperledger.besu.tests.web3j.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.List;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
@ -30,7 +32,10 @@ import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthLog.LogResult;
@SuppressWarnings("rawtypes")
public class PrivGetLogsAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivGetLogsAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivGetLogsAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
/*
This value is derived from the contract event signature
@ -44,7 +49,7 @@ public class PrivGetLogsAcceptanceTest extends PrivacyAcceptanceTestBase {
public void setUp() throws Exception {
node =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"miner-node", privacyAccountResolver.resolve(0));
"miner-node", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(node);
}

@ -19,23 +19,37 @@ import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.privacy.Restriction;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.CreatePrivacyGroupTransaction;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.Test;
import org.testcontainers.containers.Network;
public class PrivGetPrivateTransactionAcceptanceTest extends ParameterizedEnclaveTestBase {
public class PrivGetPrivateTransactionAcceptanceTest extends PrivacyAcceptanceTestBase {
public PrivGetPrivateTransactionAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode alice;
private PrivacyNode bob;
@Before
public void setUp() throws Exception {
alice = privacyBesu.createIbft2NodePrivacyEnabled("node1", privacyAccountResolver.resolve(0));
bob = privacyBesu.createIbft2NodePrivacyEnabled("node2", privacyAccountResolver.resolve(1));
final Network containerNetwork = Network.newNetwork();
alice =
privacyBesu.createIbft2NodePrivacyEnabled(
"node1", privacyAccountResolver.resolve(0), enclaveType, Optional.of(containerNetwork));
bob =
privacyBesu.createIbft2NodePrivacyEnabled(
"node2", privacyAccountResolver.resolve(1), enclaveType, Optional.of(containerNetwork));
privacyCluster.start(alice, bob);
}

@ -20,19 +20,22 @@ import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;
import io.vertx.core.Vertx;
import org.apache.tuweni.bytes.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.testcontainers.containers.Network;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
@ -43,7 +46,11 @@ import org.web3j.utils.Base64String;
import org.web3j.utils.Numeric;
import org.web3j.utils.Restriction;
public class PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivacyClusterAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivacyClusterAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private static final long POW_CHAIN_ID = 1337;
@ -58,13 +65,16 @@ public class PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase {
@Before
public void setUp() throws Exception {
final Network containerNetwork = Network.newNetwork();
alice =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"node1", privacyAccountResolver.resolve(0));
"node1", privacyAccountResolver.resolve(0), enclaveType, Optional.of(containerNetwork));
bob =
privacyBesu.createPrivateTransactionEnabledNode("node2", privacyAccountResolver.resolve(1));
privacyBesu.createPrivateTransactionEnabledNode(
"node2", privacyAccountResolver.resolve(1), enclaveType, Optional.of(containerNetwork));
charlie =
privacyBesu.createPrivateTransactionEnabledNode("node3", privacyAccountResolver.resolve(2));
privacyBesu.createPrivateTransactionEnabledNode(
"node3", privacyAccountResolver.resolve(2), enclaveType, Optional.of(containerNetwork));
privacyCluster.start(alice, bob, charlie);
}
@ -156,12 +166,12 @@ public class PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase {
final String transactionKey =
alice.execute(privacyTransactions.privDistributeTransaction(signedPrivateTransaction));
final Enclave aliceEnclave = enclaveFactory.createVertxEnclave(alice.getOrion().clientUrl());
final Enclave aliceEnclave = enclaveFactory.createVertxEnclave(alice.getEnclave().clientUrl());
final ReceiveResponse aliceRR =
aliceEnclave.receive(
Bytes.fromHexString(transactionKey).toBase64String(), alice.getEnclaveKey());
final Enclave bobEnclave = enclaveFactory.createVertxEnclave(bob.getOrion().clientUrl());
final Enclave bobEnclave = enclaveFactory.createVertxEnclave(bob.getEnclave().clientUrl());
final ReceiveResponse bobRR =
bobEnclave.receive(
Bytes.fromHexString(transactionKey).toBase64String(), bob.getEnclaveKey());

@ -16,19 +16,30 @@ package org.hyperledger.besu.tests.web3j.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Optional;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.junit.Before;
import org.junit.Test;
import org.testcontainers.containers.Network;
import org.web3j.protocol.besu.response.privacy.PrivacyGroup;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.utils.Base64String;
public class PrivacyGroupAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivacyGroupAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivacyGroupAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode alice;
private PrivacyNode bob;
@ -36,18 +47,28 @@ public class PrivacyGroupAcceptanceTest extends PrivacyAcceptanceTestBase {
@Before
public void setUp() throws Exception {
final Network containerNetwork = Network.newNetwork();
alice =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"node1", privacyAccountResolver.resolve(0));
"node1", privacyAccountResolver.resolve(0), enclaveType, Optional.of(containerNetwork));
bob =
privacyBesu.createPrivateTransactionEnabledNode("node2", privacyAccountResolver.resolve(1));
privacyBesu.createPrivateTransactionEnabledNode(
"node2", privacyAccountResolver.resolve(1), enclaveType, Optional.of(containerNetwork));
charlie =
privacyBesu.createPrivateTransactionEnabledNode("node3", privacyAccountResolver.resolve(2));
privacyBesu.createPrivateTransactionEnabledNode(
"node3", privacyAccountResolver.resolve(2), enclaveType, Optional.of(containerNetwork));
privacyCluster.start(alice, bob, charlie);
}
@Test
public void nodeCanCreatePrivacyGroup() {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
final LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(Level.DEBUG);
ctx.updateLoggers();
final String privacyGroupId =
alice.execute(
privacyTransactions.createPrivacyGroup(
@ -112,7 +133,7 @@ public class PrivacyGroupAcceptanceTest extends PrivacyAcceptanceTestBase {
@Test
public void nodeCanCreatePrivacyGroupWithoutOptionalParams() {
final String privacyGroupId =
alice.execute(privacyTransactions.createPrivacyGroup(null, null, alice, bob));
alice.execute(privacyTransactions.createPrivacyGroup(null, null, alice));
assertThat(privacyGroupId).isNotNull();
@ -122,11 +143,9 @@ public class PrivacyGroupAcceptanceTest extends PrivacyAcceptanceTestBase {
PrivacyGroup.Type.PANTHEON,
"",
"",
Base64String.wrapList(alice.getEnclaveKey(), bob.getEnclaveKey()));
Base64String.wrapList(alice.getEnclaveKey()));
alice.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected));
bob.verify(privateTransactionVerifier.validPrivacyGroupCreated(expected));
}
@Test

@ -21,10 +21,11 @@ import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.privacy.Restriction;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.CreatePrivacyGroupTransaction;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.miner.MinerTransactions;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.util.Optional;
@ -32,14 +33,19 @@ import org.apache.tuweni.bytes.Bytes;
import org.junit.Before;
import org.junit.Test;
public class PrivacyReceiptAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivacyReceiptAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivacyReceiptAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode alice;
final MinerTransactions minerTransactions = new MinerTransactions();
@Before
public void setUp() throws Exception {
alice =
privacyBesu.createIbft2NodePrivacyMiningEnabled("node1", privacyAccountResolver.resolve(0));
privacyBesu.createIbft2NodePrivacyMiningEnabled(
"node1", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(alice);
}

@ -16,20 +16,27 @@ package org.hyperledger.besu.tests.web3j.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.CrossContractReader;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import org.testcontainers.containers.Network;
import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.exceptions.ContractCallException;
public class PrivateContractPublicStateAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivateContractPublicStateAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivateContractPublicStateAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private static final long POW_CHAIN_ID = 1337;
private PrivacyNode minerNode;
@ -37,12 +44,20 @@ public class PrivateContractPublicStateAcceptanceTest extends PrivacyAcceptanceT
@Before
public void setUp() throws Exception {
final Network containerNetwork = Network.newNetwork();
minerNode =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"miner-node", privacyAccountResolver.resolve(0));
"miner-node",
privacyAccountResolver.resolve(0),
enclaveType,
Optional.of(containerNetwork));
transactionNode =
privacyBesu.createPrivateTransactionEnabledNode(
"transaction-node", privacyAccountResolver.resolve(1));
"transaction-node",
privacyAccountResolver.resolve(1),
enclaveType,
Optional.of(containerNetwork));
privacyCluster.start(minerNode, transactionNode);
}

@ -16,14 +16,16 @@ package org.hyperledger.besu.tests.web3j.privacy;
import static org.assertj.core.api.Assertions.assertThat;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.ParameterizedEnclaveTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.util.LogFilterJsonParameter;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.enclave.testutil.EnclaveType;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
@ -31,7 +33,10 @@ import org.web3j.protocol.besu.response.privacy.PrivateTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthLog.LogResult;
@SuppressWarnings("rawtypes")
public class PrivateLogFilterAcceptanceTest extends PrivacyAcceptanceTestBase {
public class PrivateLogFilterAcceptanceTest extends ParameterizedEnclaveTestBase {
public PrivateLogFilterAcceptanceTest(final EnclaveType enclaveType) {
super(enclaveType);
}
private PrivacyNode node;
@ -39,7 +44,7 @@ public class PrivateLogFilterAcceptanceTest extends PrivacyAcceptanceTestBase {
public void setUp() throws Exception {
node =
privacyBesu.createPrivateTransactionEnabledMinerNode(
"miner-node", privacyAccountResolver.resolve(0));
"miner-node", privacyAccountResolver.resolve(0), enclaveType, Optional.empty());
privacyCluster.start(node);
}

@ -1337,7 +1337,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
configParsingHandler,
exceptionHandler,
String.format("%s=%s", CONFIG_FILE_OPTION_NAME, file.getAbsolutePath()));
} catch (LauncherException e) {
} catch (final LauncherException e) {
logger.warn("Unable to run the launcher {}", e.getMessage());
}
} else {

@ -60,9 +60,9 @@ import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.data.TransactionType;
import org.hyperledger.besu.testutil.TestClock;
import org.hyperledger.orion.testutil.OrionKeyConfiguration;
import org.hyperledger.orion.testutil.OrionTestHarness;
import org.hyperledger.orion.testutil.OrionTestHarnessFactory;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
import org.hyperledger.enclave.testutil.EnclaveTestHarness;
import org.hyperledger.enclave.testutil.OrionTestHarnessFactory;
import java.io.IOException;
import java.math.BigInteger;
@ -78,6 +78,7 @@ import com.google.common.base.Suppliers;
import io.vertx.core.Vertx;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -85,6 +86,7 @@ import org.junit.rules.TemporaryFolder;
@SuppressWarnings("rawtypes")
public class PrivacyReorgTest {
@Rule public final TemporaryFolder folder = new TemporaryFolder();
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
@ -133,18 +135,18 @@ public class PrivacyReorgTest {
private final BlockDataGenerator gen = new BlockDataGenerator();
private BesuController besuController;
private OrionTestHarness enclave;
private EnclaveTestHarness enclave;
private PrivateStateRootResolver privateStateRootResolver;
private PrivacyParameters privacyParameters;
private DefaultPrivacyController privacyController;
@Before
public void setUp() throws IOException {
// Start Enclave
enclave =
OrionTestHarnessFactory.create(
"orion",
folder.newFolder().toPath(),
new OrionKeyConfiguration("enclavePublicKey", "enclavePrivateKey"));
new EnclaveKeyConfiguration("enclavePublicKey", "enclavePrivateKey"));
enclave.start();
// Create Storage
@ -184,6 +186,11 @@ public class PrivacyReorgTest {
.build();
}
@After
public void tearDown() {
enclave.stop();
}
@Test
public void privacyGroupHeadIsTracked() {
// Setup an initial blockchain with one private transaction

@ -21,9 +21,9 @@ import static org.assertj.core.api.Assertions.catchThrowable;
import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.enclave.types.SendResponse;
import org.hyperledger.orion.testutil.OrionKeyConfiguration;
import org.hyperledger.orion.testutil.OrionTestHarness;
import org.hyperledger.orion.testutil.OrionTestHarnessFactory;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
import org.hyperledger.enclave.testutil.OrionTestHarness;
import org.hyperledger.enclave.testutil.OrionTestHarnessFactory;
import java.net.URI;
import java.net.URISyntaxException;
@ -59,8 +59,9 @@ public class EnclaveTest {
testHarness =
OrionTestHarnessFactory.create(
"enclave",
folder.newFolder().toPath(),
new OrionKeyConfiguration("orion_key_0.pub", "orion_key_0.key"));
new EnclaveKeyConfiguration("enclave_key_0.pub", "enclave_key_0.key"));
testHarness.start();

@ -168,12 +168,53 @@ public class Enclave {
final int statusCode, final byte[] body, final Class<T> responseType) {
try {
return objectMapper.readValue(body, responseType);
} catch (IOException e) {
} catch (final IOException e) {
final String utf8EncodedBody = new String(body, StandardCharsets.UTF_8);
throw new EnclaveClientException(statusCode, utf8EncodedBody);
// Check if it's a Tessera error message
try {
return objectMapper.readValue(
processTesseraError(utf8EncodedBody, responseType), responseType);
} catch (final IOException ex) {
throw new EnclaveClientException(statusCode, utf8EncodedBody);
}
}
}
private <T> byte[] processTesseraError(final String errorMsg, final Class<T> responseType) {
if (responseType == SendResponse.class) {
final String base64Key =
errorMsg.substring(errorMsg.substring(0, errorMsg.indexOf('=')).lastIndexOf(' '));
return jsonByteArrayFromString("key", base64Key);
} else if (responseType == ErrorResponse.class) {
// Remove dynamic values
return jsonByteArrayFromString("error", removeBase64(errorMsg));
} else {
throw new RuntimeException("Unhandled response type.");
}
}
private String removeBase64(final String input) {
if (input.contains("=")) {
final String startInclBase64 = input.substring(0, input.indexOf('='));
final String startTrimmed = startInclBase64.substring(0, startInclBase64.lastIndexOf(" "));
final String end = input.substring(input.indexOf("="));
if (end.length() > 1) {
// Base64 in middle
return startTrimmed + end.substring(1);
} else {
// Base64 at end
return startTrimmed;
}
} else {
return input;
}
}
private byte[] jsonByteArrayFromString(final String key, final String value) {
String format = String.format("{\"%s\":\"%s\"}", key, value);
return format.getBytes(StandardCharsets.UTF_8);
}
private boolean clientError(final int statusCode) {
return statusCode >= 400 && statusCode < 500;
}

@ -14,7 +14,7 @@
*/
package org.hyperledger.besu.enclave;
public class EnclaveClientException extends IllegalArgumentException {
public class EnclaveClientException extends RuntimeException {
private int statusCode;
public EnclaveClientException(final int statusCode, final String message) {

@ -87,6 +87,7 @@ public class VertxRequestTransmitter implements RequestTransmitter {
request.putHeader(HttpHeaderNames.ACCEPT, APPLICATION_JSON);
}
contentType.ifPresent(ct -> request.putHeader(HttpHeaders.CONTENT_TYPE, ct));
if (content.isPresent()) {
request.end(content.get());
} else {

@ -47,9 +47,9 @@ import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.privacy.Restriction;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.orion.testutil.OrionKeyConfiguration;
import org.hyperledger.orion.testutil.OrionTestHarness;
import org.hyperledger.orion.testutil.OrionTestHarnessFactory;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
import org.hyperledger.enclave.testutil.OrionTestHarness;
import org.hyperledger.enclave.testutil.OrionTestHarnessFactory;
import java.math.BigInteger;
import java.util.ArrayList;
@ -126,8 +126,9 @@ public class PrivGetPrivateTransactionIntegrationTest {
testHarness =
OrionTestHarnessFactory.create(
"enclave",
folder.newFolder().toPath(),
new OrionKeyConfiguration("orion_key_0.pub", "orion_key_0.key"));
new EnclaveKeyConfiguration("enclave_key_0.pub", "enclave_key_0.key"));
testHarness.start();

@ -177,6 +177,11 @@ public enum JsonRpcError {
ENCLAVE_PAYLOAD_NOT_FOUND(-50200, "EnclavePayloadNotFound"),
CREATE_GROUP_INCLUDE_SELF(-50200, "CreatePrivacyGroupShouldIncludeSelf"),
// Tessera error codes
TESSERA_NODE_MISSING_PEER_URL(-50200, "Recipient not found for key:"),
TESSERA_CREATE_GROUP_INCLUDE_SELF(
-50200, "The list of members in a privacy group should include self"),
/** Storing privacy group issue */
ENCLAVE_UNABLE_STORE_PRIVACY_GROUP(-50200, "PrivacyGroupNotStored"),
ENCLAVE_UNABLE_DELETE_PRIVACY_GROUP(-50200, "PrivacyGroupNotDeleted"),

@ -46,9 +46,9 @@ import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.ethereum.vm.OperationTracer;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.orion.testutil.OrionKeyConfiguration;
import org.hyperledger.orion.testutil.OrionTestHarness;
import org.hyperledger.orion.testutil.OrionTestHarnessFactory;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
import org.hyperledger.enclave.testutil.OrionTestHarness;
import org.hyperledger.enclave.testutil.OrionTestHarnessFactory;
import java.util.List;
import java.util.Optional;
@ -118,8 +118,9 @@ public class PrivacyPrecompiledContractIntegrationTest {
testHarness =
OrionTestHarnessFactory.create(
"enclave",
folder.newFolder().toPath(),
new OrionKeyConfiguration("orion_key_0.pub", "orion_key_1.key"));
new EnclaveKeyConfiguration("enclave_key_0.pub", "enclave_key_1.key"));
testHarness.start();
@ -164,7 +165,7 @@ public class PrivacyPrecompiledContractIntegrationTest {
@AfterClass
public static void tearDownOnce() {
testHarness.getOrion().stop();
testHarness.stop();
vertx.close();
}

@ -53,7 +53,7 @@ import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
import org.hyperledger.besu.plugin.data.TransactionType;
import org.hyperledger.orion.testutil.OrionKeyUtils;
import org.hyperledger.enclave.testutil.EnclaveKeyUtils;
import java.math.BigInteger;
import java.util.ArrayList;
@ -162,7 +162,7 @@ public class DefaultPrivacyControllerTest {
privateWorldStateReader = mock(PrivateWorldStateReader.class);
enclavePublicKey = OrionKeyUtils.loadKey("orion_key_0.pub");
enclavePublicKey = EnclaveKeyUtils.loadKey("enclave_key_0.pub");
privateTransactionValidator = mockPrivateTransactionValidator();
enclave = mockEnclave();

@ -42,4 +42,6 @@ dependencies {
implementation 'org.assertj:assertj-core'
implementation 'org.mockito:mockito-core'
implementation 'org.web3j:core'
implementation 'org.testcontainers:testcontainers'
}

@ -12,13 +12,13 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.orion.testutil;
package org.hyperledger.enclave.testutil;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class OrionConfiguration {
public class EnclaveConfiguration {
private final Path[] publicKeys;
private final Path[] privateKeys;
@ -26,8 +26,10 @@ public class OrionConfiguration {
private final List<String> otherNodes = new ArrayList<>();
private final boolean clearKnownNodes;
private final String storage;
private final String name;
public OrionConfiguration(
public EnclaveConfiguration(
final String name,
final Path[] publicKeys,
final Path[] privateKeys,
final Path tempDir,
@ -41,6 +43,7 @@ public class OrionConfiguration {
this.otherNodes.addAll(otherNodes);
this.clearKnownNodes = clearKnownNodes;
this.storage = storage;
this.name = name;
}
public Path[] getPublicKeys() {
@ -70,4 +73,8 @@ public class OrionConfiguration {
public String getStorage() {
return storage;
}
public String getName() {
return name;
}
}

@ -12,18 +12,18 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.orion.testutil;
package org.hyperledger.enclave.testutil;
public class OrionKeyConfiguration {
public class EnclaveKeyConfiguration {
private final String[] pubKeyPaths;
private final String[] privKeyPaths;
public OrionKeyConfiguration(final String pubKeyPath, final String privKeyPath) {
public EnclaveKeyConfiguration(final String pubKeyPath, final String privKeyPath) {
this.pubKeyPaths = new String[] {pubKeyPath};
this.privKeyPaths = new String[] {privKeyPath};
}
public OrionKeyConfiguration(final String[] pubKeyPaths, final String[] privKeyPaths) {
public EnclaveKeyConfiguration(final String[] pubKeyPaths, final String[] privKeyPaths) {
this.pubKeyPaths = pubKeyPaths;
this.privKeyPaths = privKeyPaths;
}

@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.orion.testutil;
package org.hyperledger.enclave.testutil;
import java.io.BufferedReader;
import java.io.IOException;
@ -30,7 +30,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
public class OrionKeyUtils {
public class EnclaveKeyUtils {
private static final Logger LOG = LogManager.getLogger();
/**
@ -42,7 +42,7 @@ public class OrionKeyUtils {
* @throws IOException throws if key not found
*/
public static String loadKey(final String keyFileName) throws IOException {
InputStream is = OrionKeyUtils.class.getResourceAsStream("/" + keyFileName);
InputStream is = EnclaveKeyUtils.class.getResourceAsStream("/" + keyFileName);
InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8);
try (BufferedReader reader = new BufferedReader(streamReader)) {
return reader.readLine();

@ -0,0 +1,42 @@
/*
* Copyright 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.enclave.testutil;
import java.net.URI;
import java.nio.file.Path;
import java.util.List;
public interface EnclaveTestHarness {
void start();
void stop();
void close();
List<Path> getPublicKeyPaths();
String getDefaultPublicKey();
List<String> getPublicKeys();
URI clientUrl();
URI nodeUrl();
void addOtherNode(final URI otherNode);
EnclaveType getEnclaveType();
}

@ -0,0 +1,20 @@
/*
* Copyright 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.enclave.testutil;
public enum EnclaveType {
ORION,
TESSERA
}

@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.orion.testutil;
package org.hyperledger.enclave.testutil;
import static com.google.common.io.Files.readLines;
@ -32,11 +32,11 @@ import okhttp3.HttpUrl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class OrionTestHarness {
public class OrionTestHarness implements EnclaveTestHarness {
private static final Logger LOG = LogManager.getLogger();
private final Orion orion;
private final OrionConfiguration orionConfiguration;
private final EnclaveConfiguration enclaveConfiguration;
private Config config;
@ -44,25 +44,23 @@ public class OrionTestHarness {
protected static final String HOST = "127.0.0.1";
protected OrionTestHarness(final OrionConfiguration orionConfiguration) {
this.orionConfiguration = orionConfiguration;
protected OrionTestHarness(final EnclaveConfiguration enclaveConfiguration) {
this.enclaveConfiguration = enclaveConfiguration;
this.orion = new Orion();
}
public Orion getOrion() {
return orion;
}
@Override
public void start() {
if (!isRunning) {
config = buildConfig();
orion.run(config, orionConfiguration.isClearKnownNodes());
orion.run(config, enclaveConfiguration.isClearKnownNodes());
isRunning = true;
LOG.info("Orion node port: {}", orion.nodePort());
LOG.info("Orion client port: {}", orion.clientPort());
}
}
@Override
public void stop() {
if (isRunning) {
orion.stop();
@ -70,6 +68,7 @@ public class OrionTestHarness {
}
}
@Override
public void close() {
stop();
try {
@ -79,14 +78,21 @@ public class OrionTestHarness {
}
}
@Override
public List<Path> getPublicKeyPaths() {
return config.publicKeys();
}
public Config getConfig() {
return config;
}
@Override
public String getDefaultPublicKey() {
return config.publicKeys().stream().map(OrionTestHarness::readFile).findFirst().orElseThrow();
}
@Override
public List<String> getPublicKeys() {
return config.publicKeys().stream()
.map(OrionTestHarness::readFile)
@ -102,6 +108,7 @@ public class OrionTestHarness {
}
}
@Override
public URI clientUrl() {
final HttpUrl httpUrl =
new HttpUrl.Builder().scheme("http").host(HOST).port(orion.clientPort()).build();
@ -109,6 +116,7 @@ public class OrionTestHarness {
return URI.create(httpUrl.toString());
}
@Override
public URI nodeUrl() {
final HttpUrl httpUrl =
new HttpUrl.Builder().scheme("http").host(HOST).port(orion.nodePort()).build();
@ -116,8 +124,14 @@ public class OrionTestHarness {
return URI.create(httpUrl.toString());
}
@Override
public void addOtherNode(final URI otherNode) {
orionConfiguration.addOtherNode(otherNode.toString());
enclaveConfiguration.addOtherNode(otherNode.toString());
}
@Override
public EnclaveType getEnclaveType() {
return EnclaveType.ORION;
}
private Config buildConfig() {
@ -135,21 +149,23 @@ public class OrionTestHarness {
+ HOST
+ "\"\n"
+ "storage = \""
+ orionConfiguration.getStorage()
+ enclaveConfiguration.getStorage()
+ "\"\n"
+ "publickeys = ["
+ joinPathsAsTomlListEntry(orionConfiguration.getPublicKeys())
+ joinPathsAsTomlListEntry(enclaveConfiguration.getPublicKeys())
+ "]\n"
+ "privatekeys = ["
+ joinPathsAsTomlListEntry(orionConfiguration.getPrivateKeys())
+ joinPathsAsTomlListEntry(enclaveConfiguration.getPrivateKeys())
+ "]\n"
+ "workdir= \""
+ orionConfiguration.getTempDir().toString()
+ enclaveConfiguration.getTempDir().toString()
+ "\"\n";
if (orionConfiguration.getOtherNodes().size() != 0) {
if (enclaveConfiguration.getOtherNodes().size() != 0) {
confString +=
"othernodes = [" + joinStringsAsTomlListEntry(orionConfiguration.getOtherNodes()) + "]\n";
"othernodes = ["
+ joinStringsAsTomlListEntry(enclaveConfiguration.getOtherNodes())
+ "]\n";
}
// @formatter:on

@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.orion.testutil;
package org.hyperledger.enclave.testutil;
import static org.apache.tuweni.io.file.Files.copyResource;
@ -26,8 +26,9 @@ public class OrionTestHarnessFactory {
private static final String storage = "memory";
public static OrionTestHarness create(
final Path tempDir, final OrionKeyConfiguration orionConfig) {
final String name, final Path tempDir, final EnclaveKeyConfiguration orionConfig) {
return create(
name,
tempDir,
orionConfig.getPubKeyPaths(),
orionConfig.getPrivKeyPaths(),
@ -35,6 +36,7 @@ public class OrionTestHarnessFactory {
}
public static OrionTestHarness create(
final String name,
final Path tempDir,
final String[] pubKeyPaths,
final String[] privKeyPaths,
@ -62,15 +64,16 @@ public class OrionTestHarnessFactory {
})
.toArray(Path[]::new);
return create(tempDir, pubKeys, privKeys, othernodes);
return create(name, tempDir, pubKeys, privKeys, othernodes);
}
public static OrionTestHarness create(
final String name,
final Path tempDir,
final Path[] key1pubs,
final Path[] key1keys,
final List<String> othernodes) {
return new OrionTestHarness(
new OrionConfiguration(key1pubs, key1keys, tempDir, othernodes, false, storage));
new EnclaveConfiguration(name, key1pubs, key1keys, tempDir, othernodes, false, storage));
}
}

@ -0,0 +1,284 @@
/*
* Copyright 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.enclave.testutil;
import static com.google.common.io.Files.readLines;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import com.google.common.base.Charsets;
import io.vertx.core.json.JsonArray;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.assertj.core.util.Files;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.MountableFile;
public class TesseraTestHarness implements EnclaveTestHarness {
private static final Logger LOG = LogManager.getLogger();
private final EnclaveConfiguration enclaveConfiguration;
private boolean isRunning;
private URI nodeURI;
private URI q2TUri;
private URI thirdPartyUri;
private final String tesseraVersion = "latest";
private final int thirdPartyPort = 9081;
private final int q2TPort = 9082;
public static final int p2pPort = 9001;
private final String containerKeyDir = "/tmp/keys/";
@SuppressWarnings("rawtypes")
private GenericContainer tesseraContainer;
private final Optional<Network> containerNetwork;
private final String containerName;
protected TesseraTestHarness(
final EnclaveConfiguration enclaveConfiguration, final Optional<Network> containerNetwork) {
this.enclaveConfiguration = enclaveConfiguration;
this.containerNetwork = containerNetwork;
this.containerName = enclaveConfiguration.getName();
Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
}
@Override
public void start() {
if (!isRunning) {
final File tempFolder = Files.newTemporaryFolder();
LOG.info("Temporary directory: " + tempFolder.getAbsolutePath());
final String configFile = createConfigFile(enclaveConfiguration.getName());
tesseraContainer = buildTesseraContainer(configFile);
containerNetwork.ifPresent(network -> addNetwork(tesseraContainer, containerName, network));
tesseraContainer.start();
isRunning = true;
try {
final String host = "http://" + tesseraContainer.getHost();
nodeURI = new URI(host + ":" + tesseraContainer.getMappedPort(p2pPort));
LOG.info("Tessera node URI: {}", nodeURI);
q2TUri = new URI(host + ':' + tesseraContainer.getMappedPort(q2TPort));
LOG.info("Tessera client URI: {}", q2TUri);
thirdPartyUri = new URI(host + ':' + tesseraContainer.getMappedPort(thirdPartyPort));
LOG.info("Tessera thirdParty URI: {}", thirdPartyUri);
} catch (final URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void stop() {
if (isRunning) {
tesseraContainer.stop();
isRunning = false;
}
}
@Override
public void close() {
stop();
}
@Override
public List<Path> getPublicKeyPaths() {
return Arrays.asList(enclaveConfiguration.getPublicKeys());
}
@Override
public String getDefaultPublicKey() {
return readFile(enclaveConfiguration.getPublicKeys()[0]);
}
@Override
public List<String> getPublicKeys() {
return Arrays.stream(enclaveConfiguration.getPublicKeys())
.map(TesseraTestHarness::readFile)
.collect(Collectors.toList());
}
private static String readFile(final Path path) {
try {
return readLines(path.toFile(), Charsets.UTF_8).get(0);
} catch (final IOException e) {
e.printStackTrace();
return "";
}
}
@Override
public URI clientUrl() {
return q2TUri;
}
@Override
public URI nodeUrl() {
return nodeURI;
}
@Override
public void addOtherNode(final URI otherNode) {
enclaveConfiguration.addOtherNode(otherNode.toString());
}
@Override
public EnclaveType getEnclaveType() {
return EnclaveType.TESSERA;
}
private String createConfigFile(final String nodeName) {
// create a config file
// @formatter:off
String confString =
"{\n"
+ " \"mode\" : \"orion\",\n"
+ " \"encryptor\":{\n"
+ " \"type\":\"NACL\",\n"
+ " \"properties\":{\n"
+ " }\n"
+ " },\n"
+ " \"useWhiteList\": false,\n"
+ " \"jdbc\": {\n"
+ " \"username\": \"sa\",\n"
+ " \"password\": \"\",\n"
+ " \"url\": \"jdbc:h2:/tmp/db;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0\",\n"
+ " \"autoCreateTables\": true\n"
+ " },\n"
+ " \"serverConfigs\":[\n"
+ " {\n"
+ " \"app\":\"ThirdParty\",\n"
+ " \"enabled\": true,\n"
+ " \"serverAddress\": \"http://"
+ nodeName
+ ":"
+ thirdPartyPort
+ "\",\n"
+ " \"cors\" : {\n"
+ " \"allowedMethods\" : [\"GET\", \"OPTIONS\"],\n"
+ " \"allowedOrigins\" : [\"*\"]\n"
+ " },\n"
+ " \"communicationType\" : \"REST\"\n"
+ " },\n"
+ " {\n"
+ " \"app\":\"Q2T\",\n"
+ " \"enabled\": true,\n"
+ " \"serverAddress\":\"http://"
+ nodeName
+ ":"
+ q2TPort
+ "\",\n"
+ " \"communicationType\" : \"REST\"\n"
+ " },\n"
+ " {\n"
+ " \"app\":\"P2P\",\n"
+ " \"enabled\": true,\n"
+ " \"serverAddress\":\"http://"
+ nodeName
+ ":"
+ p2pPort
+ "\",\n"
+ " \"communicationType\" : \"REST\"\n"
+ " }\n"
+ " ],\n"
+ " \"keys\": {\n"
+ " \"passwords\": [],\n"
+ " \"keyData\": "
+ buildKeyConfig()
+ "\n"
+ " },\n"
+ " \"alwaysSendTo\": []";
if (enclaveConfiguration.getOtherNodes().size() != 0) {
confString +=
",\n"
+ " \"peer\": [\n"
+ " {\n"
+ " \"url\": \""
+ enclaveConfiguration.getOtherNodes().get(0)
+ "\"\n"
+ " }\n"
+ " ]";
} else {
confString += ",\n" + " \"peer\": []";
}
confString += "\n}";
final File configFile = Files.newTemporaryFile();
try {
final FileWriter fw = new FileWriter(configFile, StandardCharsets.UTF_8);
fw.write(confString);
fw.close();
} catch (final IOException e) {
throw new RuntimeException(e);
}
return configFile.getAbsolutePath();
}
private String buildKeyConfig() {
final JsonArray keyArray = new JsonArray();
final List<Path> pubKeysPaths = Arrays.asList(enclaveConfiguration.getPublicKeys());
final List<Path> privKeyPaths = Arrays.asList(enclaveConfiguration.getPrivateKeys());
for (int count = 0; count < pubKeysPaths.size(); count++) {
final HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put(
"publicKeyPath", containerKeyDir + pubKeysPaths.get(count).getFileName());
stringStringHashMap.put(
"privateKeyPath", containerKeyDir + privKeyPaths.get(count).getFileName());
keyArray.add(stringStringHashMap);
}
return keyArray.toString();
}
@SuppressWarnings("rawtypes")
private GenericContainer buildTesseraContainer(final String configFilePath) {
final String containerConfigFilePath = "/tmp/config.json";
final String keyDir = enclaveConfiguration.getTempDir().toString();
return new GenericContainer<>("quorumengineering/tessera:" + tesseraVersion)
.withCopyFileToContainer(MountableFile.forHostPath(configFilePath), containerConfigFilePath)
.withFileSystemBind(keyDir, containerKeyDir)
.withCommand("--configfile " + containerConfigFilePath)
.withExposedPorts(p2pPort, q2TPort, thirdPartyPort)
.waitingFor(Wait.forHttp("/upcheck").withMethod("GET").forStatusCode(200));
}
@SuppressWarnings("rawtypes")
private void addNetwork(
final GenericContainer container, final String containerName, final Network network) {
container.withNetwork(network).withNetworkAliases(containerName);
}
}

@ -0,0 +1,84 @@
/*
* Copyright 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.enclave.testutil;
import static org.apache.tuweni.io.file.Files.copyResource;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.jetbrains.annotations.NotNull;
import org.testcontainers.containers.Network;
public class TesseraTestHarnessFactory {
private static final String storage = "memory";
public static TesseraTestHarness create(
final String name,
final Path tempDir,
final EnclaveKeyConfiguration enclaveConfig,
final Optional<Network> containerNetwork) {
return create(
name,
tempDir,
enclaveConfig.getPubKeyPaths(),
enclaveConfig.getPrivKeyPaths(),
Collections.emptyList(),
containerNetwork);
}
public static TesseraTestHarness create(
final String name,
final Path tempDir,
final String[] pubKeyPaths,
final String[] privKeyPaths,
final List<String> othernodes,
final Optional<Network> containerNetwork) {
final Path[] pubKeys = stringArrayToPathArray(tempDir, pubKeyPaths);
final Path[] privKeys = stringArrayToPathArray(tempDir, privKeyPaths);
return create(name, tempDir, pubKeys, privKeys, othernodes, containerNetwork);
}
public static TesseraTestHarness create(
final String name,
final Path tempDir,
final Path[] key1pubs,
final Path[] key1keys,
final List<String> othernodes,
final Optional<Network> containerNetwork) {
return new TesseraTestHarness(
new EnclaveConfiguration(name, key1pubs, key1keys, tempDir, othernodes, false, storage),
containerNetwork);
}
@NotNull
private static Path[] stringArrayToPathArray(final Path tempDir, final String[] privKeyPaths) {
return Arrays.stream(privKeyPaths)
.map(
(pk) -> {
try {
return copyResource(pk, tempDir.resolve(pk));
} catch (final IOException e) {
throw new RuntimeException(e);
}
})
.toArray(Path[]::new);
}
}
Loading…
Cancel
Save