mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 21:17:54 -05:00
[PRIV-31] Add private cluster acceptance tests (#1211)
* Using privacy group id for contract name * Add private cluster acceptance tests Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
This commit is contained in:
committed by
Lucas Saldanha
parent
4e77b38e80
commit
7599f04114
@@ -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'
|
||||
|
||||
@@ -87,6 +87,19 @@ public class PantheonNodeFactory {
|
||||
.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()
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,10 @@ public class PrivateTransactionVerifier {
|
||||
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);
|
||||
}
|
||||
@@ -41,4 +45,8 @@ public class PrivateTransactionVerifier {
|
||||
public ExpectValidPrivateContractValuesReturned validOutputReturned(final String returnValue) {
|
||||
return new ExpectValidPrivateContractValuesReturned(returnValue, eea, transactions);
|
||||
}
|
||||
|
||||
public ExpectNoValidPrivateContractValuesReturned noValidOutputReturned() {
|
||||
return new ExpectNoValidPrivateContractValuesReturned(eea, transactions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ import org.junit.Test;
|
||||
|
||||
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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import tech.pegasys.pantheon.util.bytes.BytesValue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.ClassRule;
|
||||
@@ -69,7 +70,7 @@ public class PrivateAcceptanceTestBase extends AcceptanceTestBase {
|
||||
}
|
||||
|
||||
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));
|
||||
@@ -84,7 +85,7 @@ public class PrivateAcceptanceTestBase extends AcceptanceTestBase {
|
||||
}
|
||||
|
||||
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));
|
||||
@@ -98,6 +99,77 @@ public class PrivateAcceptanceTestBase extends AcceptanceTestBase {
|
||||
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);
|
||||
|
||||
1
acceptance-tests/src/test/resources/key2
Normal file
1
acceptance-tests/src/test/resources/key2
Normal file
@@ -0,0 +1 @@
|
||||
ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f
|
||||
@@ -20,12 +20,12 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
public class ReceiveResponse {
|
||||
|
||||
private byte[] payload;
|
||||
private byte[] privacyGroupId;
|
||||
private String privacyGroupId;
|
||||
|
||||
@JsonCreator
|
||||
public ReceiveResponse(
|
||||
@JsonProperty(value = "payload") final byte[] payload,
|
||||
@JsonProperty(value = "privacyGroupId") final byte[] privacyGroupId) {
|
||||
@JsonProperty(value = "privacyGroupId") final String privacyGroupId) {
|
||||
this.payload = payload;
|
||||
this.privacyGroupId = privacyGroupId;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class ReceiveResponse {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public byte[] getPrivacyGroupId() {
|
||||
public String getPrivacyGroupId() {
|
||||
return privacyGroupId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,8 @@ public class PrivacyPrecompiledContractIntegrationTest {
|
||||
nullable(PrivateTransaction.class),
|
||||
nullable(Address.class),
|
||||
nullable(OperationTracer.class),
|
||||
nullable(BlockHashLookup.class)))
|
||||
nullable(BlockHashLookup.class),
|
||||
nullable(BytesValue.class)))
|
||||
.thenReturn(result);
|
||||
|
||||
return mockPrivateTransactionProcessor;
|
||||
|
||||
@@ -42,6 +42,7 @@ import tech.pegasys.pantheon.util.bytes.BytesValue;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -107,7 +108,8 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
|
||||
|
||||
WorldUpdater publicWorldState = messageFrame.getWorldState();
|
||||
|
||||
BytesValue privacyGroupId = BytesValue.wrap(receiveResponse.getPrivacyGroupId());
|
||||
BytesValue privacyGroupId =
|
||||
BytesValue.wrap(receiveResponse.getPrivacyGroupId().getBytes(Charsets.UTF_8));
|
||||
// get the last world state root hash - or create a new one
|
||||
Hash lastRootHash =
|
||||
privateStateStorage.getPrivateAccountState(privacyGroupId).orElse(EMPTY_ROOT_HASH);
|
||||
@@ -125,7 +127,8 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
|
||||
privateTransaction,
|
||||
messageFrame.getMiningBeneficiary(),
|
||||
OperationTracer.NO_TRACING,
|
||||
messageFrame.getBlockHashLookup());
|
||||
messageFrame.getBlockHashLookup(),
|
||||
privacyGroupId);
|
||||
|
||||
if (result.isInvalid() || !result.isSuccessful()) {
|
||||
throw new Exception("Unable to process the private transaction");
|
||||
|
||||
@@ -78,7 +78,9 @@ public class PrivateTransactionHandler {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// FIXME: Orion should concatenate to and from - not it pantheon
|
||||
privateFor.add(BytesValues.asString(privateTransaction.getPrivateFrom()));
|
||||
if (privateFor.isEmpty()) {
|
||||
privateFor.add(BytesValues.asString(privateTransaction.getPrivateFrom()));
|
||||
}
|
||||
|
||||
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
|
||||
privateTransaction.writeTo(bvrlp);
|
||||
|
||||
@@ -150,7 +150,8 @@ public class PrivateTransactionProcessor {
|
||||
final PrivateTransaction transaction,
|
||||
final Address miningBeneficiary,
|
||||
final OperationTracer operationTracer,
|
||||
final BlockHashLookup blockHashLookup) {
|
||||
final BlockHashLookup blockHashLookup,
|
||||
final BytesValue privacyGroupId) {
|
||||
LOG.trace("Starting private execution of {}", transaction);
|
||||
|
||||
final Address senderAddress = transaction.getSender();
|
||||
@@ -171,7 +172,7 @@ public class PrivateTransactionProcessor {
|
||||
final Deque<MessageFrame> messageFrameStack = new ArrayDeque<>();
|
||||
if (transaction.isContractCreation()) {
|
||||
final Address privateContractAddress =
|
||||
Address.privateContractAddress(senderAddress, sender.getNonce() - 1L, BytesValue.EMPTY);
|
||||
Address.privateContractAddress(senderAddress, sender.getNonce() - 1L, privacyGroupId);
|
||||
|
||||
initialFrame =
|
||||
MessageFrame.builder()
|
||||
|
||||
@@ -78,8 +78,7 @@ public class PrivacyPrecompiledContractTest {
|
||||
|
||||
private Enclave mockEnclave() throws IOException {
|
||||
Enclave mockEnclave = mock(Enclave.class);
|
||||
ReceiveResponse response =
|
||||
new ReceiveResponse(VALID_PRIVATE_TRANSACTION_RLP_BASE64, new byte[0]);
|
||||
ReceiveResponse response = new ReceiveResponse(VALID_PRIVATE_TRANSACTION_RLP_BASE64, "");
|
||||
when(mockEnclave.receive(any(ReceiveRequest.class))).thenReturn(response);
|
||||
return mockEnclave;
|
||||
}
|
||||
@@ -99,7 +98,8 @@ public class PrivacyPrecompiledContractTest {
|
||||
nullable(PrivateTransaction.class),
|
||||
nullable(Address.class),
|
||||
nullable(OperationTracer.class),
|
||||
nullable(BlockHashLookup.class)))
|
||||
nullable(BlockHashLookup.class),
|
||||
nullable(BytesValue.class)))
|
||||
.thenReturn(result);
|
||||
|
||||
return mockPrivateTransactionProcessor;
|
||||
|
||||
@@ -30,7 +30,6 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.JsonRpcMethod;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.parameters.JsonRpcParameter;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.queries.BlockchainQueries;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcError;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResponse;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
|
||||
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.results.privacy.PrivateTransactionReceiptResult;
|
||||
@@ -46,6 +45,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class EeaGetTransactionReceipt implements JsonRpcMethod {
|
||||
@@ -92,18 +92,22 @@ public class EeaGetTransactionReceipt implements JsonRpcMethod {
|
||||
final long blockNumber = blockchain.getBlockchain().getBlockHeader(blockhash).get().getNumber();
|
||||
|
||||
PrivateTransaction privateTransaction;
|
||||
String privacyGroupId;
|
||||
try {
|
||||
privateTransaction = getTransactionFromEnclave(transaction, publicKey);
|
||||
privacyGroupId = getPrivacyGroupIdFromEnclave(transaction, publicKey);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to fetch transaction from Enclave with error " + e.getMessage());
|
||||
return new JsonRpcErrorResponse(
|
||||
return new JsonRpcSuccessResponse(
|
||||
request.getId(), JsonRpcError.PRIVATE_TRANSACTION_RECEIPT_ERROR);
|
||||
}
|
||||
|
||||
final String contractAddress =
|
||||
!privateTransaction.getTo().isPresent()
|
||||
? Address.privateContractAddress(
|
||||
privateTransaction.getSender(), privateTransaction.getNonce(), BytesValue.EMPTY)
|
||||
privateTransaction.getSender(),
|
||||
privateTransaction.getNonce(),
|
||||
BytesValue.wrap(privacyGroupId.getBytes(Charsets.UTF_8)))
|
||||
.toString()
|
||||
: null;
|
||||
|
||||
@@ -147,6 +151,16 @@ public class EeaGetTransactionReceipt implements JsonRpcMethod {
|
||||
return new JsonRpcSuccessResponse(request.getId(), result);
|
||||
}
|
||||
|
||||
private String getPrivacyGroupIdFromEnclave(final Transaction transaction, final String publicKey)
|
||||
throws IOException {
|
||||
LOG.trace("Fetching transaction information from Enclave");
|
||||
final ReceiveRequest enclaveRequest =
|
||||
new ReceiveRequest(new String(transaction.getPayload().extractArray(), UTF_8), publicKey);
|
||||
ReceiveResponse enclaveResponse = enclave.receive(enclaveRequest);
|
||||
LOG.trace("Received transaction information from Enclave");
|
||||
return enclaveResponse.getPrivacyGroupId();
|
||||
}
|
||||
|
||||
private PrivateTransaction getTransactionFromEnclave(
|
||||
final Transaction transaction, final String publicKey) throws IOException {
|
||||
LOG.trace("Fetching transaction information from Enclave");
|
||||
|
||||
@@ -168,7 +168,7 @@ public class EeaGetTransactionReceiptTest {
|
||||
.thenReturn(
|
||||
new ReceiveResponse(
|
||||
Base64.getEncoder().encodeToString(bvrlp.encoded().extractArray()).getBytes(UTF_8),
|
||||
new byte[0]));
|
||||
""));
|
||||
|
||||
when(blockchain.getChainHeadBlock()).thenReturn(chainBlock);
|
||||
when(chainBlock.getHash()).thenReturn(mockTransactionHash);
|
||||
|
||||
1
testutil/src/main/resources/orion_key_2.key
Normal file
1
testutil/src/main/resources/orion_key_2.key
Normal file
@@ -0,0 +1 @@
|
||||
{"data":{"bytes":"QmBfzDOxF99iInkXAPBAZpQQfelvPmHqbcO8tNHYtJM="},"type":"unlocked"}
|
||||
1
testutil/src/main/resources/orion_key_2.pub
Normal file
1
testutil/src/main/resources/orion_key_2.pub
Normal file
@@ -0,0 +1 @@
|
||||
k2zXEin4Ip/qBGlRkJejnGWdP9cjkK+DAvKNW31L2C8=
|
||||
Reference in New Issue
Block a user