[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>
pull/2/head
Puneetha Karamsetty 6 years ago committed by Lucas Saldanha
parent 4e77b38e80
commit 7599f04114
  1. 1
      acceptance-tests/build.gradle
  2. 13
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java
  3. 35
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectNoPrivateContractDeployedReceipt.java
  4. 36
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectNoValidPrivateContractValuesReturned.java
  5. 8
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateTransactionVerifier.java
  6. 4
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java
  7. 156
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/PrivacyClusterAcceptanceTest.java
  8. 76
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/PrivateAcceptanceTestBase.java
  9. 1
      acceptance-tests/src/test/resources/key2
  10. 6
      enclave/src/main/java/tech/pegasys/pantheon/enclave/types/ReceiveResponse.java
  11. 3
      ethereum/core/src/integration-test/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java
  12. 7
      ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java
  13. 4
      ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java
  14. 5
      ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionProcessor.java
  15. 6
      ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java
  16. 20
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceipt.java
  17. 2
      ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceiptTest.java
  18. 1
      testutil/src/main/resources/orion_key_2.key
  19. 1
      testutil/src/main/resources/orion_key_2.pub

@ -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);

@ -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);

@ -0,0 +1 @@
{"data":{"bytes":"QmBfzDOxF99iInkXAPBAZpQQfelvPmHqbcO8tNHYtJM="},"type":"unlocked"}

@ -0,0 +1 @@
k2zXEin4Ip/qBGlRkJejnGWdP9cjkK+DAvKNW31L2C8=
Loading…
Cancel
Save