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 all 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