mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-08 20:47:59 -05:00
Tessera Orion-mode privacy ATs (#2166)
* Refactored privacy ATs to use both Orion and Tessera. Signed-off-by: Mark Terry <mark.terry@consensys.net>
This commit is contained in:
@@ -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());
|
||||
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, orion.getDefaultPublicKey(), to);
|
||||
return true;
|
||||
} catch (final EnclaveClientException
|
||||
| EnclaveIOException
|
||||
| EnclaveServerException e) {
|
||||
LOG.warn("Waiting for enclave connectivity");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
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 OrionTestHarness getOrion() {
|
||||
return orion;
|
||||
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).hasMessageContaining(JsonRpcError.CREATE_GROUP_INCLUDE_SELF.getMessage());
|
||||
assertThat(throwable.getMessage())
|
||||
.has(matchOrionOrTesseraMessage(orionMessage, tesseraMessage));
|
||||
}
|
||||
|
||||
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 PrivacyAcceptanceTestBase {
|
||||
public class PrivGetPrivateTransactionAcceptanceTest extends ParameterizedEnclaveTestBase {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user