Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PRIV-31] Add private cluster acceptance tests #1211

Merged
merged 4 commits into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions acceptance-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies {
testImplementation project(':pantheon')
testImplementation project(':testutil')
testImplementation project(':util')
testImplementation project(':enclave')
testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts')

testImplementation 'com.google.guava:guava'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ public PantheonNode createPrivateTransactionEnabledMinerNode(
.build());
}

public PantheonNode createPrivateTransactionEnabledNode(
final String name, final PrivacyParameters privacyParameters, final String keyFilePath)
throws IOException {
return create(
new PantheonFactoryConfigurationBuilder()
.setName(name)
.jsonRpcEnabled()
.setKeyFilePath(keyFilePath)
.enablePrivateTransactions(privacyParameters)
.webSocketEnabled()
.build());
}

public PantheonNode createArchiveNode(final String name) throws IOException {
return create(
new PantheonFactoryConfigurationBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.tests.acceptance.dsl.privacy;

import static org.junit.Assert.assertNull;

import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eea;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ResponseTypes;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions;

public class ExpectNoPrivateContractDeployedReceipt extends GetValidPrivateTransactionReceipt {

public ExpectNoPrivateContractDeployedReceipt(final Eea eea, final Transactions transactions) {
super(eea, transactions);
}

public void verify(
final PantheonNode node, final String transactionHash, final String publicKey) {
ResponseTypes.PrivateTransactionReceipt privateTxReceipt =
getPrivateTransactionReceipt(node, transactionHash, publicKey);

assertNull(privateTxReceipt.getContractAddress());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.tests.acceptance.dsl.privacy;

import static org.junit.Assert.assertEquals;

import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eea;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ResponseTypes;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions;

public class ExpectNoValidPrivateContractValuesReturned extends GetValidPrivateTransactionReceipt {

public ExpectNoValidPrivateContractValuesReturned(
final Eea eea, final Transactions transactions) {
super(eea, transactions);
}

public void verify(
final PantheonNode node, final String transactionHash, final String publicKey) {
ResponseTypes.PrivateTransactionReceipt privateTxReceipt =
getPrivateTransactionReceipt(node, transactionHash, publicKey);

assertEquals("0x", privateTxReceipt.getOutput());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,19 @@ public ExpectValidPrivateContractDeployedReceipt validPrivateContractDeployed(
return new ExpectValidPrivateContractDeployedReceipt(contractAddress, eea, transactions);
}

public ExpectNoPrivateContractDeployedReceipt noPrivateContractDeployed() {
return new ExpectNoPrivateContractDeployedReceipt(eea, transactions);
}

public ExpectValidPrivateContractEventsEmitted validEventReturned(final String eventValue) {
return new ExpectValidPrivateContractEventsEmitted(eventValue, eea, transactions);
}

public ExpectValidPrivateContractValuesReturned validOutputReturned(final String returnValue) {
return new ExpectValidPrivateContractValuesReturned(returnValue, eea, transactions);
}

public ExpectNoValidPrivateContractValuesReturned noValidOutputReturned() {
return new ExpectNoValidPrivateContractValuesReturned(eea, transactions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

public class DeployPrivateSmartContractAcceptanceTest extends PrivateAcceptanceTestBase {

// Contract address is generated from sender address and transaction nonce
// Contract address is generated from sender address and transaction nonce and privacy group id
protected static final Address CONTRACT_ADDRESS =
Address.fromHexString("0x0bac79b78b9866ef11c989ad21a7fcf15f7a18d7");
Address.fromHexString("0x99a3e1c0368cb56aeea8fc8cf5068175d0de7ac1");
protected static final String PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";

private PantheonNode minerNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.tests.web3j.privacy;

import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor;

import tech.pegasys.orion.testutil.OrionTestHarness;
import tech.pegasys.pantheon.enclave.Enclave;
import tech.pegasys.pantheon.enclave.types.SendRequest;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class PrivacyClusterAcceptanceTest extends PrivateAcceptanceTestBase {
// Contract address is generated from sender address and transaction nonce and privacy group id
protected static final Address CONTRACT_ADDRESS =
Address.fromHexString("0x2f351161a80d74047316899342eedc606b13f9f8");

protected static final String PUBLIC_KEY_1 = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
protected static final String PUBLIC_KEY_2 = "Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=";
protected static final String PUBLIC_KEY_3 = "k2zXEin4Ip/qBGlRkJejnGWdP9cjkK+DAvKNW31L2C8=";
private PantheonNode node1;
private PantheonNode node2;
private PantheonNode node3;
private static OrionTestHarness enclave1;
private static OrionTestHarness enclave2;
private static OrionTestHarness enclave3;

@Before
public void setUp() throws Exception {
enclave1 = createEnclave("orion_key_0.pub", "orion_key_0.key");
enclave2 = createEnclave("orion_key_1.pub", "orion_key_1.key", enclave1.nodeUrl());
enclave3 = createEnclave("orion_key_2.pub", "orion_key_2.key", enclave2.nodeUrl());
node1 =
pantheon.createPrivateTransactionEnabledMinerNode(
"node1", getPrivacyParams(enclave1), "key");
node2 =
pantheon.createPrivateTransactionEnabledMinerNode(
"node2", getPrivacyParams(enclave2), "key1");
node3 =
pantheon.createPrivateTransactionEnabledNode("node3", getPrivacyParams(enclave3), "key2");

cluster.start(node1, node2, node3);

// Wait for enclave 1 and enclave 2 to connect
Enclave orion1 = new Enclave(enclave1.clientUrl());
SendRequest sendRequest1 =
new SendRequest(
"SGVsbG8sIFdvcmxkIQ==", enclave1.getPublicKeys().get(0), enclave2.getPublicKeys());
waitFor(() -> orion1.send(sendRequest1));

// Wait for enclave 2 and enclave 3 to connect
Enclave orion2 = new Enclave(enclave2.clientUrl());
SendRequest sendRequest2 =
new SendRequest(
"SGVsbG8sIFdvcmxkIQ==", enclave2.getPublicKeys().get(0), enclave3.getPublicKeys());
waitFor(() -> orion2.send(sendRequest2));
}

@Test
public void node2CanSeeContract() {

final String transactionHash =
node1.execute(transactions.deployPrivateSmartContract(getDeployEventEmitterCluster()));

privateTransactionVerifier
.validPrivateContractDeployed(CONTRACT_ADDRESS.toString())
.verify(node2, transactionHash, PUBLIC_KEY_2);
}

@Test
public void node2CanExecuteContract() {
String transactionHash =
node1.execute(transactions.deployPrivateSmartContract(getDeployEventEmitterCluster()));

privateTransactionVerifier
.validPrivateContractDeployed(CONTRACT_ADDRESS.toString())
.verify(node2, transactionHash, PUBLIC_KEY_2);

transactionHash =
node2.execute(transactions.createPrivateRawTransaction(getExecuteStoreFuncCluster(0)));

privateTransactionVerifier
.validEventReturned("1000")
.verify(node1, transactionHash, PUBLIC_KEY_1);
}

@Test
public void node2CanSeePrivateTransactionReceipt() {
String transactionHash =
node1.execute(transactions.deployPrivateSmartContract(getDeployEventEmitterCluster()));

privateTransactionVerifier
.validPrivateContractDeployed(CONTRACT_ADDRESS.toString())
.verify(node2, transactionHash, PUBLIC_KEY_2);

transactionHash =
node2.execute(transactions.createPrivateRawTransaction(getExecuteStoreFuncCluster(0)));

privateTransactionVerifier
.validEventReturned("1000")
.verify(node1, transactionHash, PUBLIC_KEY_1);

transactionHash =
node2.execute(transactions.createPrivateRawTransaction(getExecuteGetFuncCluster(1)));

privateTransactionVerifier
.validOutputReturned("1000")
.verify(node2, transactionHash, PUBLIC_KEY_2);

privateTransactionVerifier
.validOutputReturned("1000")
.verify(node1, transactionHash, PUBLIC_KEY_1);
}

@Test
public void node3CannotSeeContract() {
final String transactionHash =
node1.execute(transactions.deployPrivateSmartContract(getDeployEventEmitterCluster()));

privateTransactionVerifier
.noPrivateContractDeployed()
.verify(node3, transactionHash, PUBLIC_KEY_3);
}

@Test
public void node3CannotExecuteContract() {
node1.execute(transactions.deployPrivateSmartContract(getDeployEventEmitterCluster()));

final String transactionHash =
node3.execute(transactions.createPrivateRawTransaction(getExecuteGetFuncClusterNode3()));

privateTransactionVerifier.noValidOutputReturned().verify(node3, transactionHash, PUBLIC_KEY_3);
}

@After
public void tearDown() {
enclave1.getOrion().stop();
enclave2.getOrion().stop();
enclave3.getOrion().stop();
cluster.stop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import java.io.IOException;
import java.math.BigInteger;
import java.util.List;

import com.google.common.collect.Lists;
import org.junit.ClassRule;
Expand Down Expand Up @@ -69,7 +70,7 @@ String getDeployEventEmitter() {
}

String getExecuteStoreFunc() {
Address to = Address.fromHexString("0x0bac79b78b9866ef11c989ad21a7fcf15f7a18d7");
Address to = Address.fromHexString("0x99a3e1c0368cb56aeea8fc8cf5068175d0de7ac1");
Address from = Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73");
BytesValue privateFrom =
BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8));
Expand All @@ -84,7 +85,7 @@ String getExecuteStoreFunc() {
}

String getExecuteGetFunc() {
Address to = Address.fromHexString("0x0bac79b78b9866ef11c989ad21a7fcf15f7a18d7");
Address to = Address.fromHexString("0x99a3e1c0368cb56aeea8fc8cf5068175d0de7ac1");
Address from = Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73");
BytesValue privateFrom =
BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8));
Expand All @@ -98,6 +99,77 @@ String getExecuteGetFunc() {
return RLP.encode(pTx::writeTo).toString();
}

String getDeployEventEmitterCluster() {
Address from = Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73");
BytesValue privateFrom =
BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8));
List<BytesValue> privateFor =
Lists.newArrayList(
BytesValue.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=".getBytes(UTF_8)));
SECP256K1.KeyPair keypair =
SECP256K1.KeyPair.create(
SECP256K1.PrivateKey.create(
new BigInteger(
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16)));
PrivateTransaction pTx =
privateTx.createContractTransaction(0, from, privateFrom, privateFor, keypair);
return RLP.encode(pTx::writeTo).toString();
}

String getExecuteStoreFuncCluster(final long nonce) {
Address to = Address.fromHexString("0x2f351161a80d74047316899342eedc606b13f9f8");
Address from = Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57");
BytesValue privateFrom =
BytesValue.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=".getBytes(UTF_8));
List<BytesValue> privateFor =
Lists.newArrayList(
BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)));
SECP256K1.KeyPair keypair =
SECP256K1.KeyPair.create(
SECP256K1.PrivateKey.create(
new BigInteger(
"c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 16)));
PrivateTransaction pTx =
privateTx.storeFunctionTransaction(nonce, to, from, privateFrom, privateFor, keypair);
return RLP.encode(pTx::writeTo).toString();
}

String getExecuteGetFuncCluster(final long nonce) {
Address to = Address.fromHexString("0x2f351161a80d74047316899342eedc606b13f9f8");
Address from = Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57");
BytesValue privateFrom =
BytesValue.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=".getBytes(UTF_8));
List<BytesValue> privateFor =
Lists.newArrayList(
BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)));
SECP256K1.KeyPair keypair =
SECP256K1.KeyPair.create(
SECP256K1.PrivateKey.create(
new BigInteger(
"c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 16)));
PrivateTransaction pTx =
privateTx.getFunctionTransaction(nonce, to, from, privateFrom, privateFor, keypair);
return RLP.encode(pTx::writeTo).toString();
}

String getExecuteGetFuncClusterNode3() {
Address to = Address.fromHexString("0x2f351161a80d74047316899342eedc606b13f9f8");
Address from = Address.fromHexString("0xf17f52151EbEF6C7334FAD080c5704D77216b732");
BytesValue privateFrom =
BytesValue.wrap("k2zXEin4Ip/qBGlRkJejnGWdP9cjkK+DAvKNW31L2C8=".getBytes(UTF_8));
List<BytesValue> privateFor =
Lists.newArrayList(
BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)));
SECP256K1.KeyPair keypair =
SECP256K1.KeyPair.create(
SECP256K1.PrivateKey.create(
new BigInteger(
"ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 16)));
PrivateTransaction pTx =
privateTx.getFunctionTransaction(0, to, from, privateFrom, privateFor, keypair);
return RLP.encode(pTx::writeTo).toString();
}

static PrivacyParameters getPrivacyParams(final OrionTestHarness testHarness) throws IOException {
final PrivacyParameters privacyParameters = new PrivacyParameters();
privacyParameters.setEnabled(true);
Expand Down
1 change: 1 addition & 0 deletions acceptance-tests/src/test/resources/key2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f
Loading