diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index 1a1df67164..e3c6b4ad01 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.tests.acceptance.dsl.node; import static java.util.Collections.unmodifiableList; +import static net.consensys.cava.io.file.Files.copyResource; import static org.apache.logging.log4j.LogManager.getLogger; import tech.pegasys.pantheon.controller.KeyPairUtil; @@ -104,6 +105,7 @@ public PantheonNode( final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, final Optional permissioningConfiguration, + final Optional keyfilePath, final boolean devMode, final GenesisConfigProvider genesisConfigProvider, final boolean p2pEnabled, @@ -112,10 +114,19 @@ public PantheonNode( throws IOException { this.bootnodeEligible = bootnodeEligible; this.homeDirectory = Files.createTempDirectory("acctest"); + keyfilePath.ifPresent( + path -> { + try { + copyResource(path, homeDirectory.resolve("key")); + } catch (IOException e) { + LOG.error("Could not find key file \"{}\" in resources", path); + } + }); this.keyPair = KeyPairUtil.loadKeyPair(homeDirectory); this.name = name; this.miningParameters = miningParameters; this.privacyParameters = privacyParameters; + this.privacyParameters.setSigningKeyPair(keyPair); this.jsonRpcConfiguration = jsonRpcConfiguration; this.webSocketConfiguration = webSocketConfiguration; this.metricsConfiguration = metricsConfiguration; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java index 30e53d39f3..abb62e6e61 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ProcessPantheonNodeRunner.java @@ -87,7 +87,7 @@ public void startNode(final PantheonNode node) { params.add("--privacy-url"); params.add(node.getPrivacyParameters().getUrl()); params.add("--privacy-public-key-file"); - params.add(node.getPrivacyParameters().getPublicKeyFile().getAbsolutePath()); + params.add(node.getPrivacyParameters().getEnclavePublicKeyFile().getAbsolutePath()); params.add("--privacy-precompiled-address"); params.add(String.valueOf(node.getPrivacyParameters().getPrivacyAddress())); } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java index f0a894a1dc..d67e6d68ef 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java @@ -20,6 +20,7 @@ import tech.pegasys.pantheon.cli.PantheonControllerBuilder; import tech.pegasys.pantheon.controller.KeyPairUtil; import tech.pegasys.pantheon.controller.PantheonController; +import tech.pegasys.pantheon.ethereum.core.PendingTransactions; import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration; import tech.pegasys.pantheon.metrics.MetricsSystem; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; @@ -69,6 +70,7 @@ public void startNode(final PantheonNode node) { .devMode(node.isDevMode()) .nodePrivateKeyFile(KeyPairUtil.getDefaultKeyFile(node.homeDirectory())) .metricsSystem(noOpMetricsSystem) + .maxPendingTransactions(PendingTransactions.MAX_PENDING_TRANSACTIONS) .build(); } catch (final IOException e) { throw new RuntimeException("Error building PantheonController", e); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java index 0bd5366bb2..32750e2907 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java @@ -31,6 +31,7 @@ class PantheonFactoryConfiguration { private final WebSocketConfiguration webSocketConfiguration; private final MetricsConfiguration metricsConfiguration; private final Optional permissioningConfiguration; + private final Optional keyFilePath; private final boolean devMode; private final GenesisConfigProvider genesisConfigProvider; private final boolean p2pEnabled; @@ -45,6 +46,7 @@ class PantheonFactoryConfiguration { final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, final Optional permissioningConfiguration, + final Optional keyFilePath, final boolean devMode, final GenesisConfigProvider genesisConfigProvider, final boolean p2pEnabled, @@ -57,6 +59,7 @@ class PantheonFactoryConfiguration { this.webSocketConfiguration = webSocketConfiguration; this.metricsConfiguration = metricsConfiguration; this.permissioningConfiguration = permissioningConfiguration; + this.keyFilePath = keyFilePath; this.devMode = devMode; this.genesisConfigProvider = genesisConfigProvider; this.p2pEnabled = p2pEnabled; @@ -92,6 +95,10 @@ public Optional getPermissioningConfiguration() { return permissioningConfiguration; } + public Optional getKeyFilePath() { + return keyFilePath; + } + public boolean isDevMode() { return devMode; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java index 2955af4126..df5710f22c 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java @@ -39,6 +39,7 @@ public class PantheonFactoryConfigurationBuilder { private WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault(); private MetricsConfiguration metricsConfiguration = MetricsConfiguration.createDefault(); private Optional permissioningConfiguration = Optional.empty(); + private Optional keyFilePath = Optional.empty(); private boolean devMode = true; private GenesisConfigProvider genesisConfigProvider = ignore -> Optional.empty(); private Boolean p2pEnabled = true; @@ -142,6 +143,11 @@ public PantheonFactoryConfigurationBuilder setPermissioningConfiguration( return this; } + public PantheonFactoryConfigurationBuilder setKeyFilePath(final String keyFilePath) { + this.keyFilePath = Optional.of(keyFilePath); + return this; + } + public PantheonFactoryConfigurationBuilder setDevMode(final boolean devMode) { this.devMode = devMode; return this; @@ -172,6 +178,7 @@ public PantheonFactoryConfiguration build() { webSocketConfiguration, metricsConfiguration, permissioningConfiguration, + keyFilePath, devMode, genesisConfigProvider, p2pEnabled, diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java index 5b6c74aaf7..f9b598e6e6 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java @@ -61,6 +61,7 @@ private PantheonNode create(final PantheonFactoryConfiguration config) throws IO config.getWebSocketConfiguration(), config.getMetricsConfiguration(), config.getPermissioningConfiguration(), + config.getKeyFilePath(), config.isDevMode(), config.getGenesisConfigProvider(), config.isP2pEnabled(), @@ -79,12 +80,14 @@ public PantheonNode createMinerNode(final String name) throws IOException { } public PantheonNode createPrivateTransactionEnabledMinerNode( - final String name, final PrivacyParameters privacyParameters) throws IOException { + final String name, final PrivacyParameters privacyParameters, final String keyFilePath) + throws IOException { return create( new PantheonFactoryConfigurationBuilder() .setName(name) .miningEnabled() .jsonRpcEnabled() + .setKeyFilePath(keyFilePath) .enablePrivateTransactions(privacyParameters) .webSocketEnabled() .build()); diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractDeployedReceipt.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractDeployedReceipt.java index ab994500f1..9f4621aee3 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractDeployedReceipt.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractDeployedReceipt.java @@ -19,8 +19,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.ResponseTypes; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; -public class ExpectValidPrivateContractDeployedReceipt - extends ExpectValidPrivateTransactionReceipt { +public class ExpectValidPrivateContractDeployedReceipt extends GetValidPrivateTransactionReceipt { private final String contractAddress; diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractEventsEmitted.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractEventsEmitted.java index bfeb1a3cf9..199f12d6c1 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractEventsEmitted.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractEventsEmitted.java @@ -23,7 +23,7 @@ import org.web3j.utils.Numeric; -public class ExpectValidPrivateContractEventsEmitted extends ExpectValidPrivateTransactionReceipt { +public class ExpectValidPrivateContractEventsEmitted extends GetValidPrivateTransactionReceipt { private final String eventValue; public ExpectValidPrivateContractEventsEmitted( @@ -33,12 +33,12 @@ public ExpectValidPrivateContractEventsEmitted( } public void verify( - final PantheonNode node, final String transactionHash, final String PUBLIC_KEY) { + final PantheonNode node, final String transactionHash, final String publicKey) { ResponseTypes.PrivateTransactionReceipt privateTxReceipt = - getPrivateTransactionReceipt(node, transactionHash, PUBLIC_KEY); + getPrivateTransactionReceipt(node, transactionHash, publicKey); String event = privateTxReceipt.getLogs().get(0).getData().substring(66, 130); assertEquals( - Numeric.decodeQuantity(Numeric.prependHexPrefix(event)), new BigInteger(eventValue)); + new BigInteger(eventValue), Numeric.decodeQuantity(Numeric.prependHexPrefix(event))); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractValuesReturned.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractValuesReturned.java index 2960c2bdc8..39e6ab84d8 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractValuesReturned.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateContractValuesReturned.java @@ -24,7 +24,7 @@ import org.web3j.utils.Numeric; -public class ExpectValidPrivateContractValuesReturned extends ExpectValidPrivateTransactionReceipt { +public class ExpectValidPrivateContractValuesReturned extends GetValidPrivateTransactionReceipt { private final String returnValue; public ExpectValidPrivateContractValuesReturned( @@ -34,11 +34,11 @@ public ExpectValidPrivateContractValuesReturned( } public void verify( - final PantheonNode node, final String transactionHash, final String PUBLIC_KEY) { + final PantheonNode node, final String transactionHash, final String publicKey) { ResponseTypes.PrivateTransactionReceipt privateTxReceipt = - getPrivateTransactionReceipt(node, transactionHash, PUBLIC_KEY); + getPrivateTransactionReceipt(node, transactionHash, publicKey); BytesValue output = BytesValue.fromHexString(privateTxReceipt.getOutput()); - assertEquals(Numeric.decodeQuantity(output.toString()), new BigInteger(returnValue)); + assertEquals(new BigInteger(returnValue), Numeric.decodeQuantity(output.toString())); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateTransactionReceipt.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateTransactionReceipt.java index 7ec00bf064..75c3c5bc83 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateTransactionReceipt.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/ExpectValidPrivateTransactionReceipt.java @@ -12,29 +12,25 @@ */ package tech.pegasys.pantheon.tests.acceptance.dsl.privacy; -import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; 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 abstract class ExpectValidPrivateTransactionReceipt { +public class ExpectValidPrivateTransactionReceipt extends GetValidPrivateTransactionReceipt { - private Eea eea; - private Transactions transactions; - - ExpectValidPrivateTransactionReceipt(final Eea eea, final Transactions transactions) { - this.eea = eea; - this.transactions = transactions; + public ExpectValidPrivateTransactionReceipt(final Eea eea, final Transactions transactions) { + super(eea, transactions); } - ResponseTypes.PrivateTransactionReceipt getPrivateTransactionReceipt( + public void verify( final PantheonNode node, final String transactionHash, final String publicKey) { - - waitFor(() -> node.verify(eea.expectSuccessfulTransactionReceipt(transactionHash, publicKey))); ResponseTypes.PrivateTransactionReceipt privateTxReceipt = - node.execute(transactions.getPrivateTransactionReceipt(transactionHash, publicKey)); - return privateTxReceipt; + getPrivateTransactionReceipt(node, transactionHash, publicKey); + assertNotNull(privateTxReceipt); + assertThat(privateTxReceipt.getFrom()).isNotBlank(); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/GetValidPrivateTransactionReceipt.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/GetValidPrivateTransactionReceipt.java new file mode 100644 index 0000000000..dbbc8f39d5 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/GetValidPrivateTransactionReceipt.java @@ -0,0 +1,40 @@ +/* + * 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 tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor; + +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 abstract class GetValidPrivateTransactionReceipt { + + private Eea eea; + private Transactions transactions; + + GetValidPrivateTransactionReceipt(final Eea eea, final Transactions transactions) { + this.eea = eea; + this.transactions = transactions; + } + + ResponseTypes.PrivateTransactionReceipt getPrivateTransactionReceipt( + final PantheonNode node, final String transactionHash, final String publicKey) { + + waitFor(() -> node.verify(eea.expectSuccessfulTransactionReceipt(transactionHash, publicKey))); + ResponseTypes.PrivateTransactionReceipt privateTxReceipt = + node.execute(transactions.getPrivateTransactionReceipt(transactionHash, publicKey)); + return privateTxReceipt; + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateContractVerifier.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateTransactionVerifier.java similarity index 68% rename from acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateContractVerifier.java rename to acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateTransactionVerifier.java index 2e4671c747..a939c790f6 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateContractVerifier.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/privacy/PrivateTransactionVerifier.java @@ -15,28 +15,30 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eea; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transactions; -public class PrivateContractVerifier { +public class PrivateTransactionVerifier { private final Transactions transactions; private final Eea eea; - public PrivateContractVerifier(final Eea eea, final Transactions transactions) { + public PrivateTransactionVerifier(final Eea eea, final Transactions transactions) { this.eea = eea; this.transactions = transactions; } - public ExpectValidPrivateContractDeployedReceipt validPrivateTransactionReceipt( + public ExpectValidPrivateTransactionReceipt validPrivateTransactionReceipt() { + return new ExpectValidPrivateTransactionReceipt(eea, transactions); + } + + public ExpectValidPrivateContractDeployedReceipt validPrivateContractDeployed( final String contractAddress) { return new ExpectValidPrivateContractDeployedReceipt(contractAddress, eea, transactions); } - public ExpectValidPrivateContractEventsEmitted validPrivateTransactionReceiptReturnsEvents( - final String eventValue) { + public ExpectValidPrivateContractEventsEmitted validEventReturned(final String eventValue) { return new ExpectValidPrivateContractEventsEmitted(eventValue, eea, transactions); } - public ExpectValidPrivateContractValuesReturned validPrivateTransactionReceiptReturnsValues( - final String returnValue) { + public ExpectValidPrivateContractValuesReturned validOutputReturned(final String returnValue) { return new ExpectValidPrivateContractValuesReturned(returnValue, eea, transactions); } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eea/PrivateTransactionFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eea/PrivateTransactionFactory.java new file mode 100644 index 0000000000..847c2c5488 --- /dev/null +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/transaction/eea/PrivateTransactionFactory.java @@ -0,0 +1,106 @@ +/* + * 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.transaction.eea; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import tech.pegasys.pantheon.crypto.SECP256K1; +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Wei; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransaction; +import tech.pegasys.pantheon.util.bytes.BytesValue; + +import java.util.List; + +public class PrivateTransactionFactory { + + private static BytesValue EVENT_EMITTER_CONSTRUCTOR = + BytesValue.fromHexString( + "0x608060405234801561001057600080fd5b5060008054600160a06" + + "0020a03191633179055610199806100326000396000f3fe6080" + + "604052600436106100565763ffffffff7c01000000000000000" + + "000000000000000000000000000000000000000006000350416" + + "633fa4f245811461005b5780636057361d1461008257806367e" + + "404ce146100ae575b600080fd5b34801561006757600080fd5b" + + "506100706100ec565b60408051918252519081900360200190f" + + "35b34801561008e57600080fd5b506100ac6004803603602081" + + "10156100a557600080fd5b50356100f2565b005b3480156100b" + + "a57600080fd5b506100c3610151565b6040805173ffffffffff" + + "ffffffffffffffffffffffffffffff909216825251908190036" + + "0200190f35b60025490565b6040805133815260208101839052" + + "81517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb1" + + "2b753f3d1aaa2d8f9f5929181900390910190a1600255600180" + + "5473ffffffffffffffffffffffffffffffffffffffff1916331" + + "79055565b60015473ffffffffffffffffffffffffffffffffff" + + "ffffff169056fea165627a7a72305820c7f729cb24e05c221f5" + + "aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029"); + + private static BytesValue SET_FUNCTION_CALL = + BytesValue.fromHexString( + "0x6057361d00000000000000000000000000000000000000000000000000000000000003e8"); + + private static BytesValue GET_FUNCTION_CALL = BytesValue.fromHexString("0x3fa4f245"); + + public PrivateTransaction createContractTransaction( + final long nonce, + final Address from, + final BytesValue privateFrom, + final List privateFor, + final SECP256K1.KeyPair keypair) { + return privateTransaction( + nonce, null, EVENT_EMITTER_CONSTRUCTOR, from, privateFrom, privateFor, keypair); + } + + public PrivateTransaction storeFunctionTransaction( + final long nonce, + final Address to, + final Address from, + final BytesValue privateFrom, + final List privateFor, + final SECP256K1.KeyPair keypair) { + return privateTransaction(nonce, to, SET_FUNCTION_CALL, from, privateFrom, privateFor, keypair); + } + + public PrivateTransaction getFunctionTransaction( + final long nonce, + final Address to, + final Address from, + final BytesValue privateFrom, + final List privateFor, + final SECP256K1.KeyPair keypair) { + return privateTransaction(nonce, to, GET_FUNCTION_CALL, from, privateFrom, privateFor, keypair); + } + + public PrivateTransaction privateTransaction( + final long nonce, + final Address to, + final BytesValue payload, + final Address from, + final BytesValue privateFrom, + final List privateFor, + final SECP256K1.KeyPair keypair) { + return PrivateTransaction.builder() + .nonce(nonce) + .gasPrice(Wei.of(1000)) + .gasLimit(3000000) + .to(to) + .value(Wei.ZERO) + .payload(payload) + .sender(from) + .chainId(2018) + .privateFrom(privateFrom) + .privateFor(privateFor) + .restriction(BytesValue.wrap("restricted".getBytes(UTF_8))) + .signAndBuild(keypair); + } +} diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java index e86d9b9470..65d1fff6b7 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java @@ -14,14 +14,10 @@ import tech.pegasys.orion.testutil.OrionTestHarness; import tech.pegasys.pantheon.ethereum.core.Address; -import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode; -import java.io.IOException; - -import org.junit.AfterClass; +import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; public class DeployPrivateSmartContractAcceptanceTest extends PrivateAcceptanceTestBase { @@ -33,59 +29,55 @@ public class DeployPrivateSmartContractAcceptanceTest extends PrivateAcceptanceT private PantheonNode minerNode; private static OrionTestHarness enclave; - private static PrivacyParameters privacyParameters; - - @BeforeClass - public static void setUpOnce() throws Exception { - enclave = createEnclave("orion_key_0.pub", "orion_key_0.key"); - privacyParameters = getPrivacyParams(enclave); - } - - @AfterClass - public static void tearDownOnce() { - enclave.getOrion().stop(); - } @Before public void setUp() throws Exception { - minerNode = pantheon.createPrivateTransactionEnabledMinerNode("miner-node", privacyParameters); + enclave = createEnclave("orion_key_0.pub", "orion_key_0.key"); + minerNode = + pantheon.createPrivateTransactionEnabledMinerNode( + "miner-node", getPrivacyParams(enclave), "key"); cluster.start(minerNode); } @Test - public void deployingMustGiveValidReceipt() throws IOException { + public void deployingMustGiveValidReceipt() { final String transactionHash = - minerNode.execute(transactions.deployPrivateSmartContract(getDeploySimpleStorage())); + minerNode.execute(transactions.deployPrivateSmartContract(getDeployEventEmitter())); - privateContractVerifier - .validPrivateTransactionReceipt(CONTRACT_ADDRESS.toString()) + privateTransactionVerifier + .validPrivateContractDeployed(CONTRACT_ADDRESS.toString()) .verify(minerNode, transactionHash, PUBLIC_KEY); } @Test - public void privateSmartContractMustEmitEvents() throws IOException { - minerNode.execute(transactions.deployPrivateSmartContract(getDeploySimpleStorage())); + public void privateSmartContractMustEmitEvents() { + minerNode.execute(transactions.deployPrivateSmartContract(getDeployEventEmitter())); final String transactionHash = minerNode.execute(transactions.createPrivateRawTransaction(getExecuteStoreFunc())); - privateContractVerifier - .validPrivateTransactionReceiptReturnsEvents("1000") + privateTransactionVerifier + .validEventReturned("1000") .verify(minerNode, transactionHash, PUBLIC_KEY); } @Test - public void privateSmartContractMustReturnValues() throws IOException { + public void privateSmartContractMustReturnValues() { - minerNode.execute(transactions.deployPrivateSmartContract(getDeploySimpleStorage())); + minerNode.execute(transactions.deployPrivateSmartContract(getDeployEventEmitter())); minerNode.execute(transactions.createPrivateRawTransaction(getExecuteStoreFunc())); final String transactionHash = minerNode.execute(transactions.createPrivateRawTransaction(getExecuteGetFunc())); - privateContractVerifier - .validPrivateTransactionReceiptReturnsValues("1000") + privateTransactionVerifier + .validOutputReturned("1000") .verify(minerNode, transactionHash, PUBLIC_KEY); } + + @After + public void tearDown() { + enclave.getOrion().stop(); + } } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/PrivateAcceptanceTestBase.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/PrivateAcceptanceTestBase.java index 376e10a121..a9d9c2d7cc 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/PrivateAcceptanceTestBase.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/web3j/privacy/PrivateAcceptanceTestBase.java @@ -12,19 +12,26 @@ */ package tech.pegasys.pantheon.tests.web3j.privacy; +import static java.nio.charset.StandardCharsets.UTF_8; + import tech.pegasys.orion.testutil.OrionTestHarness; import tech.pegasys.orion.testutil.OrionTestHarnessFactory; +import tech.pegasys.pantheon.crypto.SECP256K1; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; +import tech.pegasys.pantheon.ethereum.privacy.PrivateTransaction; +import tech.pegasys.pantheon.ethereum.rlp.RLP; import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase; import tech.pegasys.pantheon.tests.acceptance.dsl.jsonrpc.Eea; -import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivateContractVerifier; +import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivateTransactionVerifier; import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaTransactions; +import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.PrivateTransactionFactory; +import tech.pegasys.pantheon.util.bytes.BytesValue; import java.io.IOException; -import java.nio.charset.Charset; +import java.math.BigInteger; -import com.google.common.io.Resources; +import com.google.common.collect.Lists; import org.junit.ClassRule; import org.junit.rules.TemporaryFolder; @@ -32,12 +39,14 @@ public class PrivateAcceptanceTestBase extends AcceptanceTestBase { @ClassRule public static final TemporaryFolder privacy = new TemporaryFolder(); protected final Eea eea; - final PrivateContractVerifier privateContractVerifier; + protected final PrivateTransactionFactory privateTx; + protected final PrivateTransactionVerifier privateTransactionVerifier; PrivateAcceptanceTestBase() { final EeaTransactions eeaTransactions = new EeaTransactions(); eea = new Eea(eeaTransactions); - privateContractVerifier = new PrivateContractVerifier(eea, transactions); + privateTx = new PrivateTransactionFactory(); + privateTransactionVerifier = new PrivateTransactionVerifier(eea, transactions); } static OrionTestHarness createEnclave( @@ -45,16 +54,48 @@ static OrionTestHarness createEnclave( return OrionTestHarnessFactory.create(privacy.newFolder().toPath(), pubKey, privKey, othernode); } - String getDeploySimpleStorage() throws IOException { - return loadRawTransaction("privacy/single-instance/deployPrivateSmartContractRLP.txt"); + String getDeployEventEmitter() { + Address from = Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"); + BytesValue privateFrom = + BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)); + SECP256K1.KeyPair keypair = + SECP256K1.KeyPair.create( + SECP256K1.PrivateKey.create( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + PrivateTransaction pTx = + privateTx.createContractTransaction(0, from, privateFrom, Lists.newArrayList(), keypair); + return RLP.encode(pTx::writeTo).toString(); } - String getExecuteStoreFunc() throws IOException { - return loadRawTransaction("privacy/single-instance/executeStoreFuncRLP.txt"); + String getExecuteStoreFunc() { + Address to = Address.fromHexString("0x0bac79b78b9866ef11c989ad21a7fcf15f7a18d7"); + Address from = Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"); + BytesValue privateFrom = + BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)); + SECP256K1.KeyPair keypair = + SECP256K1.KeyPair.create( + SECP256K1.PrivateKey.create( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + PrivateTransaction pTx = + privateTx.storeFunctionTransaction(1, to, from, privateFrom, Lists.newArrayList(), keypair); + return RLP.encode(pTx::writeTo).toString(); } - String getExecuteGetFunc() throws IOException { - return loadRawTransaction("privacy/single-instance/executeGetFuncRLP.txt"); + String getExecuteGetFunc() { + Address to = Address.fromHexString("0x0bac79b78b9866ef11c989ad21a7fcf15f7a18d7"); + Address from = Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"); + BytesValue privateFrom = + BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)); + SECP256K1.KeyPair keypair = + SECP256K1.KeyPair.create( + SECP256K1.PrivateKey.create( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + PrivateTransaction pTx = + privateTx.getFunctionTransaction(2, to, from, privateFrom, Lists.newArrayList(), keypair); + return RLP.encode(pTx::writeTo).toString(); } static PrivacyParameters getPrivacyParams(final OrionTestHarness testHarness) throws IOException { @@ -62,12 +103,9 @@ static PrivacyParameters getPrivacyParams(final OrionTestHarness testHarness) th privacyParameters.setEnabled(true); privacyParameters.setUrl(testHarness.clientUrl()); privacyParameters.setPrivacyAddress(Address.PRIVACY); - privacyParameters.setPublicKeyUsingFile(testHarness.getConfig().publicKeys().get(0).toFile()); - privacyParameters.enablePrivateDB(privacy.newFolder("private").toPath()); + privacyParameters.setEnclavePublicKeyUsingFile( + testHarness.getConfig().publicKeys().get(0).toFile()); + privacyParameters.enablePrivateDB(privacy.newFolder().toPath()); return privacyParameters; } - - private String loadRawTransaction(final String path) throws IOException { - return Resources.toString(Resources.getResource(path), Charset.defaultCharset()); - } } diff --git a/acceptance-tests/src/test/resources/key b/acceptance-tests/src/test/resources/key new file mode 100644 index 0000000000..85329a8cbe --- /dev/null +++ b/acceptance-tests/src/test/resources/key @@ -0,0 +1 @@ +8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63 \ No newline at end of file diff --git a/acceptance-tests/src/test/resources/key1 b/acceptance-tests/src/test/resources/key1 new file mode 100644 index 0000000000..ee8bb3413d --- /dev/null +++ b/acceptance-tests/src/test/resources/key1 @@ -0,0 +1 @@ +c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 \ No newline at end of file diff --git a/acceptance-tests/src/test/resources/privacy/single-instance/deployPrivateSmartContractRLP.txt b/acceptance-tests/src/test/resources/privacy/single-instance/deployPrivateSmartContractRLP.txt deleted file mode 100644 index d2f9119add..0000000000 --- a/acceptance-tests/src/test/resources/privacy/single-instance/deployPrivateSmartContractRLP.txt +++ /dev/null @@ -1 +0,0 @@ -0xf90285808203e8832dc6c08080b901cb608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610199806100326000396000f3fe6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029820fe8a03b613ac4bcef689e202b5d6471712ace47fb629597556881101203bcf7c956b5a00f1546398f42fd5ec0c89b8e3603cfbd77b7dbf7cde5589faf3d68096e300353ac41316156744d784c4355486d425648586f5a7a7a42675062572f776a3561784470573958386c393153476f3dedac41316156744d784c4355486d425648586f5a7a7a42675062572f776a3561784470573958386c393153476f3d8c756e72657374726963746564 \ No newline at end of file diff --git a/acceptance-tests/src/test/resources/privacy/single-instance/executeGetFuncRLP.txt b/acceptance-tests/src/test/resources/privacy/single-instance/executeGetFuncRLP.txt deleted file mode 100644 index e11fbba40b..0000000000 --- a/acceptance-tests/src/test/resources/privacy/single-instance/executeGetFuncRLP.txt +++ /dev/null @@ -1 +0,0 @@ -0xf8d0028203e8832dc6c0940bac79b78b9866ef11c989ad21a7fcf15f7a18d780843fa4f245820fe7a0f3f7356dfd5be89a35f2d86ee768ac42122cdd31889ebb5c12b2af63462dd4d1a06311b6a169a08cd093161dfe40f8747e70eaaafafea61f1e9b73acba9b0fe037ac41316156744d784c4355486d425648586f5a7a7a42675062572f776a3561784470573958386c393153476f3dedac41316156744d784c4355486d425648586f5a7a7a42675062572f776a3561784470573958386c393153476f3d8c756e72657374726963746564 \ No newline at end of file diff --git a/acceptance-tests/src/test/resources/privacy/single-instance/executeStoreFuncRLP.txt b/acceptance-tests/src/test/resources/privacy/single-instance/executeStoreFuncRLP.txt deleted file mode 100644 index 0d1644747e..0000000000 --- a/acceptance-tests/src/test/resources/privacy/single-instance/executeStoreFuncRLP.txt +++ /dev/null @@ -1 +0,0 @@ -0xf8f0018203e8832dc6c0940bac79b78b9866ef11c989ad21a7fcf15f7a18d780a46057361d00000000000000000000000000000000000000000000000000000000000003e8820fe8a0ed4a9cce97d0b962462be81166872c474eb920ba8925f41cb839af61ba19e980a03f9d28583f1c1123803a3193db5598f986b90c11d2d6dd35a814a47809e78a4cac41316156744d784c4355486d425648586f5a7a7a42675062572f776a3561784470573958386c393153476f3dedac41316156744d784c4355486d425648586f5a7a7a42675062572f776a3561784470573958386c393153476f3d8c756e72657374726963746564 \ No newline at end of file diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/PrivacyParameters.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/PrivacyParameters.java index 156d461f11..4a9a29d1d6 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/PrivacyParameters.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/PrivacyParameters.java @@ -14,6 +14,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import tech.pegasys.pantheon.crypto.SECP256K1; import tech.pegasys.pantheon.ethereum.privacy.PrivateStateStorage; import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionStorage; import tech.pegasys.pantheon.ethereum.storage.StorageProvider; @@ -38,25 +39,34 @@ public class PrivacyParameters { private Integer privacyAddress; private boolean enabled; private String url; - private String publicKey; - private File publicKeyFile; + private String enclavePublicKey; + private File enclavePublicKeyFile; + private SECP256K1.KeyPair signingKeyPair; private WorldStateArchive privateWorldStateArchive; private StorageProvider privateStorageProvider; private PrivateTransactionStorage privateTransactionStorage; private PrivateStateStorage privateStateStorage; - public String getPublicKey() { - return publicKey; + public String getEnclavePublicKey() { + return enclavePublicKey; } - public File getPublicKeyFile() { - return publicKeyFile; + public File getEnclavePublicKeyFile() { + return enclavePublicKeyFile; } - public void setPublicKeyUsingFile(final File publicKeyFile) throws IOException { - this.publicKeyFile = publicKeyFile; - this.publicKey = Files.asCharSource(publicKeyFile, UTF_8).read(); + public void setEnclavePublicKeyUsingFile(final File publicKeyFile) throws IOException { + this.enclavePublicKeyFile = publicKeyFile; + this.enclavePublicKey = Files.asCharSource(publicKeyFile, UTF_8).read(); + } + + public void setSigningKeyPair(final SECP256K1.KeyPair signingKeyPair) { + this.signingKeyPair = signingKeyPair; + } + + public SECP256K1.KeyPair getSigningKeyPair() { + return signingKeyPair; } public static PrivacyParameters noPrivacy() { diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java index 866b4a89b9..632539cece 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java @@ -13,6 +13,7 @@ package tech.pegasys.pantheon.ethereum.mainnet.precompiles.privacy; import static java.nio.charset.StandardCharsets.UTF_8; +import static tech.pegasys.pantheon.crypto.Hash.keccak256; import tech.pegasys.pantheon.enclave.Enclave; import tech.pegasys.pantheon.enclave.types.ReceiveRequest; @@ -59,7 +60,7 @@ public PrivacyPrecompiledContract( final GasCalculator gasCalculator, final PrivacyParameters privacyParameters) { this( gasCalculator, - privacyParameters.getPublicKey(), + privacyParameters.getEnclavePublicKey(), new Enclave(privacyParameters.getUrl()), privacyParameters.getPrivateWorldStateArchive(), privacyParameters.getPrivateTransactionStorage(), @@ -136,8 +137,7 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram privateStateUpdater.putPrivateAccountState(privacyGroupId, disposablePrivateState.rootHash()); privateStateUpdater.commit(); - BytesValue rlpEncoded = RLP.encode(privateTransaction::writeTo); - Bytes32 txHash = tech.pegasys.pantheon.crypto.Hash.keccak256(rlpEncoded); + Bytes32 txHash = keccak256(RLP.encode(privateTransaction::writeTo)); PrivateTransactionStorage.Updater privateUpdater = privateTransactionStorage.updater(); privateUpdater.putTransactionLogs(txHash, result.getLogs()); privateUpdater.putTransactionResult(txHash, result.getOutput()); diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java index f1816b47c8..4313b358e0 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandler.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.ethereum.privacy; +import tech.pegasys.pantheon.crypto.SECP256K1; import tech.pegasys.pantheon.enclave.Enclave; import tech.pegasys.pantheon.enclave.types.SendRequest; import tech.pegasys.pantheon.enclave.types.SendResponse; @@ -23,34 +24,47 @@ import tech.pegasys.pantheon.util.bytes.BytesValues; import java.io.IOException; -import java.nio.charset.Charset; import java.util.Base64; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; +import com.google.common.base.Charsets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + public class PrivateTransactionHandler { + private static final Logger LOG = LogManager.getLogger(); + private final Enclave enclave; private final Address privacyPrecompileAddress; + private final SECP256K1.KeyPair nodeKeyPair; public PrivateTransactionHandler(final PrivacyParameters privacyParameters) { this( new Enclave(privacyParameters.getUrl()), - Address.privacyPrecompiled(privacyParameters.getPrivacyAddress())); + Address.privacyPrecompiled(privacyParameters.getPrivacyAddress()), + privacyParameters.getSigningKeyPair()); } - public PrivateTransactionHandler(final Enclave enclave, final Address privacyPrecompileAddress) { + public PrivateTransactionHandler( + final Enclave enclave, + final Address privacyPrecompileAddress, + final SECP256K1.KeyPair nodeKeyPair) { this.enclave = enclave; this.privacyPrecompileAddress = privacyPrecompileAddress; + this.nodeKeyPair = nodeKeyPair; } public Transaction handle(final PrivateTransaction privateTransaction) throws IOException { + LOG.trace("Handling private transaction"); final SendRequest sendRequest = createSendRequest(privateTransaction); final SendResponse sendResponse; try { + LOG.trace("Storing private transaction in enclave"); sendResponse = enclave.send(sendRequest); } catch (IOException e) { + LOG.error("Failed to store private transaction in enclave", e); throw e; } @@ -63,6 +77,9 @@ private SendRequest createSendRequest(final PrivateTransaction privateTransactio .map(BytesValues::asString) .collect(Collectors.toList()); + // FIXME: Orion should concatenate to and from - not it pantheon + privateFor.add(BytesValues.asString(privateTransaction.getPrivateFrom())); + final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); privateTransaction.writeTo(bvrlp); @@ -75,15 +92,14 @@ private SendRequest createSendRequest(final PrivateTransaction privateTransactio private Transaction createPrivacyMarkerTransaction( final String transactionEnclaveKey, final PrivateTransaction privateTransaction) { - return new Transaction( - privateTransaction.getNonce(), - privateTransaction.getGasPrice(), - privateTransaction.getGasLimit(), - Optional.of(privacyPrecompileAddress), - privateTransaction.getValue(), - privateTransaction.getSignature(), - BytesValue.wrap(transactionEnclaveKey.getBytes(Charset.defaultCharset())), - privateTransaction.getSender(), - privateTransaction.getChainId().getAsInt()); + return Transaction.builder() + .nonce(privateTransaction.getNonce()) + .gasPrice(privateTransaction.getGasPrice()) + .gasLimit(privateTransaction.getGasLimit()) + .to(privacyPrecompileAddress) + .value(privateTransaction.getValue()) + .payload(BytesValue.wrap(transactionEnclaveKey.getBytes(Charsets.UTF_8))) + .sender(privateTransaction.getSender()) + .signAndBuild(nodeKeyPair); } } diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandlerTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandlerTest.java index efb258268d..636f539405 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandlerTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/privacy/PrivateTransactionHandlerTest.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.when; import tech.pegasys.pantheon.crypto.SECP256K1; +import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.enclave.Enclave; import tech.pegasys.pantheon.enclave.types.SendRequest; import tech.pegasys.pantheon.enclave.types.SendResponse; @@ -29,8 +30,8 @@ import java.io.IOException; import java.math.BigInteger; -import java.util.Optional; +import com.google.common.base.Charsets; import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Test; @@ -41,54 +42,45 @@ public class PrivateTransactionHandlerTest { private static final String TRANSACTION_KEY = "My Transaction Key"; - private static final String TRANSACTION_KEY_HEX = "0x4d79205472616e73616374696f6e204b6579"; + private static final KeyPair KEY_PAIR = + KeyPair.create( + SECP256K1.PrivateKey.create( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); PrivateTransactionHandler privateTransactionHandler; PrivateTransactionHandler brokenPrivateTransactionHandler; private static final PrivateTransaction VALID_PRIVATE_TRANSACTION = - new PrivateTransaction( - 0L, - Wei.of(1), - 21000L, - Optional.of( - Address.wrap(BytesValue.fromHexString("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"))), - Wei.of( - new BigInteger( - "115792089237316195423570985008687907853269984665640564039457584007913129639935")), - SECP256K1.Signature.create( - new BigInteger( - "32886959230931919120748662916110619501838190146643992583529828535682419954515"), - new BigInteger( - "14473701025599600909210599917245952381483216609124029382871721729679842002948"), - Byte.valueOf("0")), - BytesValue.fromHexString("0x"), - Address.wrap(BytesValue.fromHexString("0x8411b12666f68ef74cace3615c9d5a377729d03f")), - 1, - BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)), - Lists.newArrayList( - BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)), - BytesValue.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=".getBytes(UTF_8))), - BytesValue.wrap("restricted".getBytes(UTF_8))); + PrivateTransaction.builder() + .nonce(0) + .gasPrice(Wei.of(1000)) + .gasLimit(3000000) + .to(Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57")) + .value(Wei.ZERO) + .payload(BytesValue.fromHexString("0x")) + .sender(Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73")) + .chainId(2018) + .privateFrom( + BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8))) + .privateFor( + Lists.newArrayList( + BytesValue.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)), + BytesValue.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=".getBytes(UTF_8)))) + .restriction(BytesValue.wrap("restricted".getBytes(UTF_8))) + .signAndBuild(KEY_PAIR); private static final Transaction PUBLIC_TRANSACTION = - new Transaction( - 0L, - Wei.of(1), - 21000L, - Optional.of(Address.DEFAULT_PRIVACY), - Wei.of( - new BigInteger( - "115792089237316195423570985008687907853269984665640564039457584007913129639935")), - SECP256K1.Signature.create( - new BigInteger( - "32886959230931919120748662916110619501838190146643992583529828535682419954515"), - new BigInteger( - "14473701025599600909210599917245952381483216609124029382871721729679842002948"), - Byte.valueOf("0")), - BytesValue.fromHexString(TRANSACTION_KEY_HEX), - Address.wrap(BytesValue.fromHexString("0x8411b12666f68ef74cace3615c9d5a377729d03f")), - 1); + Transaction.builder() + .nonce(0) + .gasPrice(Wei.of(1000)) + .gasLimit(3000000) + .to(Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57")) + .value(Wei.ZERO) + .payload(BytesValue.wrap(TRANSACTION_KEY.getBytes(Charsets.UTF_8))) + .sender(Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73")) + .chainId(2018) + .signAndBuild(KEY_PAIR); Enclave mockEnclave() throws IOException { Enclave mockEnclave = mock(Enclave.class); @@ -107,17 +99,22 @@ Enclave brokenMockEnclave() throws IOException { @Before public void setUp() throws IOException { privateTransactionHandler = - new PrivateTransactionHandler(mockEnclave(), Address.DEFAULT_PRIVACY); + new PrivateTransactionHandler(mockEnclave(), Address.DEFAULT_PRIVACY, KEY_PAIR); brokenPrivateTransactionHandler = - new PrivateTransactionHandler(brokenMockEnclave(), Address.DEFAULT_PRIVACY); + new PrivateTransactionHandler(brokenMockEnclave(), Address.DEFAULT_PRIVACY, KEY_PAIR); } @Test public void validTransactionThroughHandler() throws IOException { - final Transaction transactionRespose = + final Transaction transactionResponse = privateTransactionHandler.handle(VALID_PRIVATE_TRANSACTION); - assertThat(transactionRespose).isEqualToComparingFieldByField(PUBLIC_TRANSACTION); + assertThat(transactionResponse.contractAddress()) + .isEqualTo(PUBLIC_TRANSACTION.contractAddress()); + assertThat(transactionResponse.getPayload()).isEqualTo(PUBLIC_TRANSACTION.getPayload()); + assertThat(transactionResponse.getNonce()).isEqualTo(PUBLIC_TRANSACTION.getNonce()); + assertThat(transactionResponse.getSender()).isEqualTo(PUBLIC_TRANSACTION.getSender()); + assertThat(transactionResponse.getValue()).isEqualTo(PUBLIC_TRANSACTION.getValue()); } @Test(expected = IOException.class) diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceipt.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceipt.java index ccfa41a466..0f4b2e912f 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceipt.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceipt.java @@ -18,7 +18,9 @@ import tech.pegasys.pantheon.enclave.Enclave; import tech.pegasys.pantheon.enclave.types.ReceiveRequest; import tech.pegasys.pantheon.enclave.types.ReceiveResponse; +import tech.pegasys.pantheon.ethereum.chain.TransactionLocation; import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.BlockBody; import tech.pegasys.pantheon.ethereum.core.Hash; import tech.pegasys.pantheon.ethereum.core.Log; import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; @@ -48,11 +50,12 @@ public class EeaGetTransactionReceipt implements JsonRpcMethod { + private static final Logger LOG = getLogger(); + private final BlockchainQueries blockchain; private final Enclave enclave; private final JsonRpcParameter parameters; private final PrivacyParameters privacyParameters; - private static final Logger LOG = getLogger(); public EeaGetTransactionReceipt( final BlockchainQueries blockchain, @@ -73,22 +76,20 @@ public String getName() { @Override public JsonRpcResponse response(final JsonRpcRequest request) { LOG.trace("Executing eea_getTransactionReceipt"); - final Hash hash = parameters.required(request.getParams(), 0, Hash.class); + final Hash transactionHash = parameters.required(request.getParams(), 0, Hash.class); final String publicKey = parameters.required(request.getParams(), 1, String.class); - final Optional transactionCompleteResult = - blockchain.getBlockchain().getTransactionByHash(hash); - - PrivateTransactionReceiptResult result; - - if (!transactionCompleteResult.isPresent()) { + final Optional maybeLocation = + blockchain.getBlockchain().getTransactionLocation(transactionHash); + if (!maybeLocation.isPresent()) { return new JsonRpcSuccessResponse(request.getId(), null); } + final TransactionLocation location = maybeLocation.get(); + final BlockBody blockBody = + blockchain.getBlockchain().getBlockBody(location.getBlockHash()).get(); + final Transaction transaction = blockBody.getTransactions().get(location.getTransactionIndex()); - Transaction transaction = transactionCompleteResult.get(); - - Hash blockHash = blockchain.getBlockchain().getChainHeadBlock().getHash(); - long blockNumber = blockchain.getBlockchain().getChainHeadBlockNumber(); - int txIndex = getTransactionIndex(blockchain, transaction, blockNumber); + final Hash blockhash = location.getBlockHash(); + final long blockNumber = blockchain.getBlockchain().getBlockHeader(blockhash).get().getNumber(); PrivateTransaction privateTransaction; try { @@ -100,51 +101,52 @@ public JsonRpcResponse response(final JsonRpcRequest request) { } final String contractAddress = - Address.privateContractAddress( - privateTransaction.getSender(), privateTransaction.getNonce(), BytesValue.EMPTY) - .toString(); + !privateTransaction.getTo().isPresent() + ? Address.privateContractAddress( + privateTransaction.getSender(), privateTransaction.getNonce(), BytesValue.EMPTY) + .toString() + : null; + + LOG.trace("Calculated contractAddress: {}", contractAddress); BytesValue rlpEncoded = RLP.encode(privateTransaction::writeTo); Bytes32 txHash = tech.pegasys.pantheon.crypto.Hash.keccak256(rlpEncoded); + LOG.trace("Calculated private transaction hash: {}", txHash); + List events = privacyParameters .getPrivateTransactionStorage() .getEvents(txHash) .orElse(Collections.emptyList()); + + LOG.trace("Processed private transaction events"); + BytesValue output = privacyParameters .getPrivateTransactionStorage() .getOutput(txHash) .orElse(BytesValue.wrap(new byte[0])); - result = + LOG.trace("Processed private transaction output"); + + PrivateTransactionReceiptResult result = new PrivateTransactionReceiptResult( contractAddress, privateTransaction.getSender().toString(), privateTransaction.getTo().map(Address::toString).orElse(null), events, output, - blockHash, - hash, + blockhash, + transactionHash, blockNumber, - txIndex); + location.getTransactionIndex()); LOG.trace("Created Private Transaction from given Transaction Hash"); return new JsonRpcSuccessResponse(request.getId(), result); } - private int getTransactionIndex( - final BlockchainQueries blockchain, final Transaction transaction, final long blockNumber) { - return blockchain - .getBlockchain() - .getBlockBody(blockchain.getBlockchain().getBlockHeader(blockNumber).get().getHash()) - .get() - .getTransactions() - .indexOf(transaction); - } - private PrivateTransaction getTransactionFromEnclave( final Transaction transaction, final String publicKey) throws IOException { LOG.trace("Fetching transaction information from Enclave"); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransaction.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransaction.java index ce83e23151..2319e70204 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransaction.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransaction.java @@ -80,7 +80,7 @@ public JsonRpcResponse response(final JsonRpcRequest request) { if (!privateTransaction .getRestriction() - .equals(BytesValue.wrap("unrestricted".getBytes(UTF_8)))) { + .equals(BytesValue.wrap("restricted".getBytes(UTF_8)))) { return new JsonRpcErrorResponse( request.getId(), JsonRpcError.UNIMPLEMENTED_PRIVATE_TRANSACTION_TYPE); } @@ -106,7 +106,6 @@ private Transaction handlePrivateTransaction(final PrivateTransaction privateTra try { return privateTransactionHandler.handle(privateTransaction); } catch (final IOException e) { - LOG.debug(e); throw new InvalidJsonRpcRequestException("Unable to handle private transaction", e); } } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceiptTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceiptTest.java index 380943941d..02a695fa34 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceiptTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaGetTransactionReceiptTest.java @@ -15,6 +15,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -24,6 +25,7 @@ import tech.pegasys.pantheon.enclave.types.ReceiveRequest; import tech.pegasys.pantheon.enclave.types.ReceiveResponse; import tech.pegasys.pantheon.ethereum.chain.Blockchain; +import tech.pegasys.pantheon.ethereum.chain.TransactionLocation; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.core.Block; import tech.pegasys.pantheon.ethereum.core.BlockBody; @@ -63,6 +65,12 @@ public class EeaGetTransactionReceiptTest { private final Address sender = Address.fromHexString("0x0000000000000000000000000000000000000003"); + private static final SECP256K1.KeyPair KEY_PAIR = + SECP256K1.KeyPair.create( + SECP256K1.PrivateKey.create( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + private final PrivateTransaction privateTransaction = PrivateTransaction.builder() .nonce(0) @@ -90,23 +98,24 @@ public class EeaGetTransactionReceiptTest { Lists.newArrayList( BytesValue.wrap("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=".getBytes(UTF_8)))) .restriction(BytesValue.wrap("restricted".getBytes(UTF_8))) - .signAndBuild( - SECP256K1.KeyPair.create( - SECP256K1.PrivateKey.create( - new BigInteger( - "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", - 16)))); + .signAndBuild(KEY_PAIR); + private final Transaction transaction = - new Transaction( - privateTransaction.getNonce(), - privateTransaction.getGasPrice(), - privateTransaction.getGasLimit(), - Optional.of(Address.DEFAULT_PRIVACY), - privateTransaction.getValue(), - privateTransaction.getSignature(), - BytesValue.wrap("EnclaveKey".getBytes(UTF_8)), - privateTransaction.getSender(), - privateTransaction.getChainId().getAsInt()); + Transaction.builder() + .nonce(0) + .gasPrice(Wei.of(1000)) + .gasLimit(3000000) + .to(Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57")) + .value(Wei.ZERO) + .payload(BytesValue.wrap("EnclaveKey".getBytes(UTF_8))) + .sender(Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73")) + .chainId(2018) + .signAndBuild(KEY_PAIR); + + private final Hash mockTransactionHash = + Hash.fromHexString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + private final Hash mockBlockHash = + Hash.fromHexString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); private final JsonRpcParameter parameters = new JsonRpcParameter(); @@ -118,7 +127,6 @@ public class EeaGetTransactionReceiptTest { @Test public void createsPrivateTransactionReceipt() throws IOException { - final Hash mockHash = mock(Hash.class); final BytesValue mockBytesValue = mock(BytesValue.class); final Block chainBlock = mock(Block.class); final long mockLong = 10; @@ -136,6 +144,8 @@ public void createsPrivateTransactionReceipt() throws IOException { final List mockLogList = Arrays.asList(mockLog); final PrivateTransactionStorage privateTransactionStorage = mock(PrivateTransactionStorage.class); + final List mockListTx = Arrays.asList(mockTx, transaction); + final TransactionLocation transactionLocation = new TransactionLocation(mockBlockHash, 1); doReturn(privateTransactionStorage).when(privacyParameters).getPrivateTransactionStorage(); when(privateTransactionStorage.getEvents(any(Bytes32.class))) @@ -150,6 +160,8 @@ public void createsPrivateTransactionReceipt() throws IOException { when(blockchainQueries.getBlockchain()).thenReturn(blockchain); when(blockchain.getTransactionByHash(transaction.hash())).thenReturn(Optional.of(transaction)); + when(blockchain.getTransactionLocation(nullable(Hash.class))) + .thenReturn(Optional.of(transactionLocation)); final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); privateTransaction.writeTo(bvrlp); when(enclave.receive(any(ReceiveRequest.class))) @@ -159,15 +171,13 @@ public void createsPrivateTransactionReceipt() throws IOException { .encodeToString(bvrlp.encoded().extractArray()) .getBytes(UTF_8))); - final List mockListTx = Arrays.asList(mockTx, transaction); when(blockchain.getChainHeadBlock()).thenReturn(chainBlock); - when(chainBlock.getHash()).thenReturn(mockHash); + when(chainBlock.getHash()).thenReturn(mockTransactionHash); when(blockchainQueries.getBlockchain().getChainHeadBlockNumber()).thenReturn(mockLong); when(blockBody.getTransactions()).thenReturn(mockListTx); - when(blockchain.getBlockHeader(mockLong)).thenReturn(Optional.of(mockBlockHeader)); - when(mockBlockHeader.getHash()).thenReturn(mockHash); - when(blockchain.getBlockBody(mockHash)).thenReturn(Optional.of(blockBody)); - + when(blockchain.getBlockHeader(mockBlockHash)).thenReturn(Optional.of(mockBlockHeader)); + when(mockBlockHeader.getHash()).thenReturn(mockTransactionHash); + when(blockchain.getBlockBody(mockBlockHash)).thenReturn(Optional.of(blockBody)); final JsonRpcSuccessResponse response = (JsonRpcSuccessResponse) eeaGetTransactionReceipt.response(request); final PrivateTransactionReceiptResult result = diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java index febc6f53dd..165a3e43e1 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaSendRawTransactionTest.java @@ -49,14 +49,16 @@ public class EeaSendRawTransactionTest { private static final String VALID_PRIVATE_TRANSACTION_RLP = - "0xf8f5800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87808025a04" - + "8b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935" - + "3a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd" - + "2c804ac41316156744d784c4355486d425648586f5a7a7a42675062572f776" - + "a3561784470573958386c393153476f3df85aac41316156744d784c4355486" - + "d425648586f5a7a7a42675062572f776a3561784470573958386c393153476" - + "f3dac4b6f32625671442b6e4e6c4e594c35454537793349644f6e766966746" - + "a69697a706a52742b4854754642733d8c756e72657374726963746564"; + "0xf8f3800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87" + + "808025a048b55bfa915ac795c431978d8a6a992b628d557da5ff" + + "759b307d495a36649353a01fffd310ac743f371de3b9f7f9cb56" + + "c0b28ad43601b4ab949f53faa07bd2c804ac41316156744d784c" + + "4355486d425648586f5a7a7a42675062572f776a356178447057" + + "3958386c393153476f3df85aac41316156744d784c4355486d42" + + "5648586f5a7a7a42675062572f776a3561784470573958386c39" + + "3153476f3dac4b6f32625671442b6e4e6c4e594c354545377933" + + "49644f6e766966746a69697a706a52742b4854754642733d8a72" + + "657374726963746564"; private static final Transaction PUBLIC_TRANSACTION = new Transaction( diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index a6dc6499f9..8c23194e66 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -878,7 +878,7 @@ private PrivacyParameters privacyParameters() throws IOException { privacyParameters.setEnabled(true); privacyParameters.setUrl(privacyUrl.toString()); if (privacyPublicKeyFile() != null) { - privacyParameters.setPublicKeyUsingFile(privacyPublicKeyFile()); + privacyParameters.setEnclavePublicKeyUsingFile(privacyPublicKeyFile()); } else { throw new ParameterException( commandLine, "Please specify Enclave public key file path to enable privacy"); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java index 8919c10a53..70415ab4c6 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java @@ -93,6 +93,7 @@ public PantheonController build() throws IOException { // instantiate a controller with mainnet config if no genesis file is defined // otherwise use the indicated genesis file final KeyPair nodeKeys = loadKeyPair(nodePrivateKeyFile); + privacyParameters.setSigningKeyPair(nodeKeys); final StorageProvider storageProvider = RocksDbStorageProvider.create(homePath.resolve(DATABASE_PATH), metricsSystem); diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java index 2c0c08c178..7368252a2e 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java @@ -2010,7 +2010,7 @@ public void mustUseEnclaveUriAndOptions() throws IOException { assertThat(enclaveArg.getValue().isEnabled()).isEqualTo(true); assertThat(enclaveArg.getValue().getUrl()).isEqualTo(ENCLAVE_URI); - assertThat(enclaveArg.getValue().getPublicKey()).isEqualTo(ENCLAVE_PUBLIC_KEY); + assertThat(enclaveArg.getValue().getEnclavePublicKey()).isEqualTo(ENCLAVE_PUBLIC_KEY); assertThat(commandOutput.toString()).isEmpty(); assertThat(commandErrorOutput.toString()).isEmpty();