diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java deleted file mode 100644 index b9b657e668..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/EnclaveTest.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.enclave; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; - -import org.hyperledger.besu.enclave.types.PrivacyGroup; -import org.hyperledger.besu.enclave.types.ReceiveResponse; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.TesseraTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -import com.google.common.collect.Lists; -import io.vertx.core.Vertx; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class EnclaveTest { - - @TempDir private static Path folder; - - private static final String PAYLOAD = "a wonderful transaction"; - private static final String MOCK_KEY = "iOCzoGo5kwtZU0J41Z9xnGXHN6ZNukIa9MspvHtu3Jk="; - private Enclave enclave; - private Vertx vertx; - private EnclaveFactory factory; - - private TesseraTestHarness testHarness; - - @BeforeEach - public void setUp() throws Exception { - vertx = Vertx.vertx(); - factory = new EnclaveFactory(vertx); - - testHarness = - TesseraTestHarnessFactory.create( - "enclave", - Files.createTempDirectory(folder, "enclave"), - new EnclaveKeyConfiguration( - new String[] {"enclave_key_0.pub"}, - new String[] {"enclave_key_0.key"}, - EnclaveEncryptorType.NOOP), - Optional.empty()); - - testHarness.start(); - - enclave = factory.createVertxEnclave(testHarness.clientUrl()); - } - - @AfterEach - public void tearDown() { - testHarness.close(); - vertx.close(); - } - - @Test - public void testUpCheck() { - assertThat(enclave.upCheck()).isTrue(); - } - - @Test - public void testReceiveThrowsWhenPayloadDoesNotExist() { - final String publicKey = testHarness.getDefaultPublicKey(); - - final Throwable t = catchThrowable(() -> enclave.receive(MOCK_KEY, publicKey)); - - assertThat(t.getMessage()).isEqualTo("Message with hash was not found"); - } - - @Test - public void testSendAndReceive() { - final List publicKeys = testHarness.getPublicKeys(); - - final SendResponse sr = - enclave.send(PAYLOAD, publicKeys.get(0), Lists.newArrayList(publicKeys.get(0))); - - final ReceiveResponse rr = enclave.receive(sr.getKey(), publicKeys.get(0)); - assertThat(rr).isNotNull(); - assertThat(new String(rr.getPayload(), UTF_8)).isEqualTo(PAYLOAD); - assertThat(rr.getPrivacyGroupId()).isNotNull(); - } - - @Test - public void testSendWithPrivacyGroupAndReceive() { - final List publicKeys = testHarness.getPublicKeys(); - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), "", ""); - - final SendResponse sr = - enclave.send(PAYLOAD, publicKeys.get(0), privacyGroupResponse.getPrivacyGroupId()); - - final ReceiveResponse rr = enclave.receive(sr.getKey(), publicKeys.get(0)); - assertThat(rr).isNotNull(); - assertThat(new String(rr.getPayload(), UTF_8)).isEqualTo(PAYLOAD); - assertThat(rr.getPrivacyGroupId()).isNotNull(); - } - - @Test - public void testCreateAndDeletePrivacyGroup() { - final List publicKeys = testHarness.getPublicKeys(); - final String name = "testName"; - final String description = "testDesc"; - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), name, description); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull(); - assertThat(privacyGroupResponse.getName()).isEqualTo(name); - assertThat(privacyGroupResponse.getDescription()).isEqualTo(description); - assertThat(privacyGroupResponse.getType()).isEqualByComparingTo(PrivacyGroup.Type.PANTHEON); - - final String response = - enclave.deletePrivacyGroup(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0)); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response); - } - - @Test - public void testCreateFindDeleteFindPrivacyGroup() { - final List publicKeys = testHarness.getPublicKeys(); - final String name = "name"; - final String description = "desc"; - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), name, description); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull(); - assertThat(privacyGroupResponse.getName()).isEqualTo(name); - assertThat(privacyGroupResponse.getDescription()).isEqualTo(description); - assertThat(privacyGroupResponse.getType()).isEqualTo(PrivacyGroup.Type.PANTHEON); - - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .untilAsserted( - () -> { - final PrivacyGroup[] findPrivacyGroupResponse = enclave.findPrivacyGroup(publicKeys); - - assertThat(findPrivacyGroupResponse.length).isEqualTo(1); - assertThat(findPrivacyGroupResponse[0].getPrivacyGroupId()) - .isEqualTo(privacyGroupResponse.getPrivacyGroupId()); - }); - - final String response = - enclave.deletePrivacyGroup(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0)); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response); - - Awaitility.await() - .atMost(5, TimeUnit.SECONDS) - .untilAsserted( - () -> { - final PrivacyGroup[] findPrivacyGroupResponse = enclave.findPrivacyGroup(publicKeys); - - assertThat(findPrivacyGroupResponse.length).isEqualTo(0); - }); - } - - @Test - public void testCreateDeleteRetrievePrivacyGroup() { - final List publicKeys = testHarness.getPublicKeys(); - final String name = "name"; - final String description = "desc"; - - final PrivacyGroup privacyGroupResponse = - enclave.createPrivacyGroup(publicKeys, publicKeys.get(0), name, description); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull(); - assertThat(privacyGroupResponse.getName()).isEqualTo(name); - assertThat(privacyGroupResponse.getDescription()).isEqualTo(description); - assertThat(privacyGroupResponse.getType()).isEqualTo(PrivacyGroup.Type.PANTHEON); - - final PrivacyGroup retrievePrivacyGroup = - enclave.retrievePrivacyGroup(privacyGroupResponse.getPrivacyGroupId()); - - assertThat(retrievePrivacyGroup).usingRecursiveComparison().isEqualTo(privacyGroupResponse); - - final String response = - enclave.deletePrivacyGroup(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0)); - - assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response); - } - - @Test - public void upcheckReturnsFalseIfNoResponseReceived() throws URISyntaxException { - assertThat(factory.createVertxEnclave(new URI("http://8.8.8.8:65535")).upCheck()).isFalse(); - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java deleted file mode 100644 index ad1271e920..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsCertificateDefinition.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.enclave; - -import java.io.File; -import java.net.URL; -import java.nio.file.Path; - -import com.google.common.io.Resources; - -public class TlsCertificateDefinition { - - private final File pkcs12File; - private final String password; - - public static TlsCertificateDefinition loadFromResource( - final String resourcePath, final String password) { - try { - final URL sslCertificate = Resources.getResource(resourcePath); - final Path keystorePath = Path.of(sslCertificate.getPath()); - - return new TlsCertificateDefinition(keystorePath.toFile(), password); - } catch (final Exception e) { - throw new RuntimeException("Failed to load TLS certificates", e); - } - } - - public TlsCertificateDefinition(final File pkcs12File, final String password) { - this.pkcs12File = pkcs12File; - this.password = password; - } - - public File getPkcs12File() { - return pkcs12File; - } - - public String getPassword() { - return password; - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java deleted file mode 100644 index b594779306..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledEnclaveTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.enclave; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.hyperledger.besu.enclave.TlsHelpers.populateFingerprintFile; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.Optional; - -import io.vertx.core.Vertx; -import io.vertx.core.http.HttpServer; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class TlsEnabledEnclaveTest { - - private TlsEnabledHttpServerFactory serverFactory; - private Vertx vertx; - - final TlsCertificateDefinition httpServerCert = - TlsCertificateDefinition.loadFromResource("tls/cert1.pfx", "password"); - final TlsCertificateDefinition besuCert = - TlsCertificateDefinition.loadFromResource("tls/cert2.pfx", "password2"); - - public void shutdown() { - vertx.close(); - } - - @BeforeEach - public void setup() { - serverFactory = new TlsEnabledHttpServerFactory(); - this.vertx = Vertx.vertx(); - } - - @AfterEach - public void cleanup() { - serverFactory.shutdown(); - this.shutdown(); - } - - private Enclave createEnclave( - final int httpServerPort, final Path workDir, final boolean tlsEnabled) throws IOException { - - final Path serverFingerprintFile = workDir.resolve("server_known_clients"); - final Path besuCertPasswordFile = workDir.resolve("password_file"); - try { - populateFingerprintFile(serverFingerprintFile, httpServerCert, Optional.of(httpServerPort)); - Files.write(besuCertPasswordFile, besuCert.getPassword().getBytes(Charset.defaultCharset())); - - final EnclaveFactory factory = new EnclaveFactory(vertx); - if (tlsEnabled) { - final URI httpServerUri = new URI("https://localhost:" + httpServerPort); - return factory.createVertxEnclave( - httpServerUri, - besuCert.getPkcs12File().toPath(), - besuCertPasswordFile, - serverFingerprintFile); - } else { - return factory.createVertxEnclave(new URI("http://localhost:" + httpServerPort)); - } - } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) { - fail("unable to populate fingerprint file"); - return null; - } catch (URISyntaxException e) { - fail("unable to create URI"); - return null; - } - } - - @Test - public void nonTlsEnclaveCannotConnectToTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, true); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, false); - - assertThat(enclave.upCheck()).isEqualTo(false); - } - - @Test - public void nonTlsEnclaveCanConnectToNonTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, false); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, false); - - assertThat(enclave.upCheck()).isEqualTo(true); - } - - @Test - public void tlsEnclaveCannotConnectToNonTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up!". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, false); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, true); - - assertThat(enclave.upCheck()).isEqualTo(false); - } - - @Test - public void tlsEnclaveCanConnectToTlsServer() throws IOException { - - Path workDir = Files.createTempDirectory("test-certs"); - - // Note: the HttpServer always responds with a JsonRpcSuccess, result="I'm up". - final HttpServer httpServer = serverFactory.create(httpServerCert, besuCert, workDir, true); - - final Enclave enclave = createEnclave(httpServer.actualPort(), workDir, true); - - assertThat(enclave.upCheck()).isEqualTo(true); - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java deleted file mode 100644 index 7c67aeb7b9..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsEnabledHttpServerFactory.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.enclave; - -import static org.hyperledger.besu.enclave.TlsHelpers.populateFingerprintFile; - -import java.io.IOException; -import java.nio.file.Path; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import com.google.common.collect.Lists; -import io.netty.handler.codec.http.HttpHeaderValues; -import io.vertx.core.Vertx; -import io.vertx.core.http.ClientAuth; -import io.vertx.core.http.HttpMethod; -import io.vertx.core.http.HttpServer; -import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.http.HttpServerResponse; -import io.vertx.core.net.PfxOptions; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; -import org.apache.tuweni.net.tls.VertxTrustOptions; - -class TlsEnabledHttpServerFactory { - - private final Vertx vertx; - private final List serversCreated = Lists.newArrayList(); - - TlsEnabledHttpServerFactory() { - this.vertx = Vertx.vertx(); - } - - void shutdown() { - serversCreated.forEach(HttpServer::close); - vertx.close(); - } - - HttpServer create( - final TlsCertificateDefinition serverCert, - final TlsCertificateDefinition acceptedClientCerts, - final Path workDir, - final boolean tlsEnabled) { - try { - - final Path serverFingerprintFile = workDir.resolve("server_known_clients"); - populateFingerprintFile(serverFingerprintFile, acceptedClientCerts, Optional.empty()); - - final HttpServerOptions web3HttpServerOptions = new HttpServerOptions(); - web3HttpServerOptions.setPort(0); - if (tlsEnabled) { - web3HttpServerOptions.setSsl(true); - web3HttpServerOptions.setClientAuth(ClientAuth.REQUIRED); - web3HttpServerOptions.setTrustOptions( - VertxTrustOptions.allowlistClients(serverFingerprintFile)); - web3HttpServerOptions.setPfxKeyCertOptions( - new PfxOptions() - .setPath(serverCert.getPkcs12File().toString()) - .setPassword(serverCert.getPassword())); - } - final Router router = Router.router(vertx); - router - .route(HttpMethod.GET, "/upcheck") - .produces(HttpHeaderValues.APPLICATION_JSON.toString()) - .handler(TlsEnabledHttpServerFactory::handleRequest); - - final HttpServer mockOrionHttpServer = vertx.createHttpServer(web3HttpServerOptions); - - final CompletableFuture serverConfigured = new CompletableFuture<>(); - mockOrionHttpServer.requestHandler(router).listen(result -> serverConfigured.complete(true)); - - serverConfigured.get(); - - serversCreated.add(mockOrionHttpServer); - return mockOrionHttpServer; - } catch (final KeyStoreException - | NoSuchAlgorithmException - | CertificateException - | IOException - | ExecutionException - | InterruptedException e) { - throw new RuntimeException("Failed to construct a TLS Enabled Server", e); - } - } - - private static void handleRequest(final RoutingContext context) { - final HttpServerResponse response = context.response(); - if (!response.closed()) { - response.end("I'm up!"); - } - } -} diff --git a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java b/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java deleted file mode 100644 index 09002f8115..0000000000 --- a/enclave/src/integration-test/java/org/hyperledger/besu/enclave/TlsHelpers.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.enclave; - -import org.hyperledger.besu.crypto.MessageDigestFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.List; -import java.util.Locale; -import java.util.Optional; -import java.util.StringJoiner; - -import com.google.common.collect.Lists; - -public class TlsHelpers { - - private TlsHelpers() {} - - private static KeyStore loadP12KeyStore(final File pkcsFile, final String password) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException { - final KeyStore store = KeyStore.getInstance("pkcs12"); - try (final InputStream keystoreStream = new FileInputStream(pkcsFile)) { - store.load(keystoreStream, password.toCharArray()); - } catch (IOException e) { - throw new RuntimeException("Unable to load keystore.", e); - } - return store; - } - - public static void populateFingerprintFile( - final Path knownClientsPath, - final TlsCertificateDefinition certDef, - final Optional serverPortToAppendToHostname) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { - - final List certs = getCertsFromPkcs12(certDef); - final StringBuilder fingerprintsToAdd = new StringBuilder(); - final String portFragment = serverPortToAppendToHostname.map(port -> ":" + port).orElse(""); - for (final X509Certificate cert : certs) { - final String fingerprint = generateFingerprint(cert); - fingerprintsToAdd.append(String.format("localhost%s %s%n", portFragment, fingerprint)); - fingerprintsToAdd.append(String.format("127.0.0.1%s %s%n", portFragment, fingerprint)); - } - Files.writeString(knownClientsPath, fingerprintsToAdd.toString()); - } - - @SuppressWarnings("JdkObsolete") // java.util.Enumeration is baked into the Keystore API - public static List getCertsFromPkcs12(final TlsCertificateDefinition certDef) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException { - final List results = Lists.newArrayList(); - - final KeyStore p12 = loadP12KeyStore(certDef.getPkcs12File(), certDef.getPassword()); - final Enumeration aliases = p12.aliases(); - while (aliases.hasMoreElements()) { - results.add((X509Certificate) p12.getCertificate(aliases.nextElement())); - } - return results; - } - - private static String generateFingerprint(final X509Certificate cert) - throws NoSuchAlgorithmException, CertificateEncodingException { - final MessageDigest md = MessageDigestFactory.create(MessageDigestFactory.SHA256_ALG); - md.update(cert.getEncoded()); - final byte[] digest = md.digest(); - - final StringJoiner joiner = new StringJoiner(":"); - for (final byte b : digest) { - joiner.add(String.format("%02X", b)); - } - - return joiner.toString().toLowerCase(Locale.ROOT); - } -} diff --git a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java b/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java deleted file mode 100644 index 9bb10629f3..0000000000 --- a/ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/fork/frontier/PrivGetPrivateTransactionIntegrationTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.ethereum.api.jsonrpc.methods.fork.frontier; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture.privateMarkerTransaction; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacyIdProvider; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivateTransaction; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult; -import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.chain.TransactionLocation; -import org.hyperledger.besu.ethereum.core.BlockHeader; -import org.hyperledger.besu.ethereum.core.Transaction; -import org.hyperledger.besu.ethereum.privacy.PrivacyController; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.privacy.RestrictedDefaultPrivacyController; -import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.plugin.data.Restriction; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.TesseraTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.math.BigInteger; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Optional; - -import com.google.common.collect.Lists; -import io.vertx.core.Vertx; -import org.apache.tuweni.bytes.Bytes; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class PrivGetPrivateTransactionIntegrationTest { - - @TempDir private static Path folder; - private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="; - - private final PrivacyIdProvider privacyIdProvider = (user) -> ENCLAVE_PUBLIC_KEY; - private final PrivateStateStorage privateStateStorage = mock(PrivateStateStorage.class); - private final Blockchain blockchain = mock(Blockchain.class); - - private final Address sender = - Address.fromHexString("0x0000000000000000000000000000000000000003"); - - private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithmFactory.getInstance(); - - private final KeyPair KEY_PAIR = - signatureAlgorithm.createKeyPair( - signatureAlgorithm.createPrivateKey( - new BigInteger( - "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); - - private final PrivateTransaction privateTransaction = - PrivateTransaction.builder() - .nonce(0) - .gasPrice(Wei.of(1000)) - .gasLimit(3000000) - .to(null) - .value(Wei.ZERO) - .payload( - Bytes.fromHexString( - "0x608060405234801561001057600080fd5b5060d08061001f60003960" - + "00f3fe60806040526004361060485763ffffffff7c01000000" - + "00000000000000000000000000000000000000000000000000" - + "60003504166360fe47b18114604d5780636d4ce63c14607557" - + "5b600080fd5b348015605857600080fd5b5060736004803603" - + "6020811015606d57600080fd5b50356099565b005b34801560" - + "8057600080fd5b506087609e565b6040805191825251908190" - + "0360200190f35b600055565b6000549056fea165627a7a7230" - + "5820cb1d0935d14b589300b12fcd0ab849a7e9019c81da24d6" - + "daa4f6b2f003d1b0180029")) - .sender(sender) - .chainId(BigInteger.valueOf(2018)) - .privateFrom(Bytes.wrap(ENCLAVE_PUBLIC_KEY.getBytes(UTF_8))) - .privateFor( - Lists.newArrayList( - Bytes.wrap("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=".getBytes(UTF_8)))) - .restriction(Restriction.RESTRICTED) - .signAndBuild(KEY_PAIR); - - private Vertx vertx = Vertx.vertx(); - private TesseraTestHarness testHarness; - private Enclave enclave; - private PrivacyController privacyController; - - @BeforeEach - public void setUp() throws Exception { - vertx = Vertx.vertx(); - - testHarness = - TesseraTestHarnessFactory.create( - "enclave", - Files.createTempDirectory(folder, "enclave"), - new EnclaveKeyConfiguration( - new String[] {"enclave_key_0.pub"}, - new String[] {"enclave_key_0.key"}, - EnclaveEncryptorType.NOOP), - Optional.empty()); - - testHarness.start(); - - final EnclaveFactory factory = new EnclaveFactory(vertx); - enclave = factory.createVertxEnclave(testHarness.clientUrl()); - - privacyController = - new RestrictedDefaultPrivacyController( - blockchain, privateStateStorage, enclave, null, null, null, null, null); - } - - @AfterEach - public void tearDown() { - testHarness.close(); - vertx.close(); - } - - @Test - public void returnsStoredPrivateTransaction() { - final PrivGetPrivateTransaction privGetPrivateTransaction = - new PrivGetPrivateTransaction(privacyController, privacyIdProvider); - - final Hash blockHash = Hash.ZERO; - final Transaction pmt = spy(privateMarkerTransaction()); - when(blockchain.getTransactionByHash(eq(pmt.getHash()))).thenReturn(Optional.of(pmt)); - when(blockchain.getTransactionLocation(eq(pmt.getHash()))) - .thenReturn(Optional.of(new TransactionLocation(blockHash, 0))); - - final BlockHeader blockHeader = mock(BlockHeader.class); - when(blockHeader.getHash()).thenReturn(blockHash); - when(blockchain.getBlockHeader(eq(blockHash))).thenReturn(Optional.of(blockHeader)); - - final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); - privateTransaction.writeTo(bvrlp); - - final String payload = Base64.getEncoder().encodeToString(bvrlp.encoded().toArrayUnsafe()); - final ArrayList to = Lists.newArrayList("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="); - final SendResponse sendResponse = enclave.send(payload, ENCLAVE_PUBLIC_KEY, to); - - final Bytes hexKey = Bytes.fromBase64String(sendResponse.getKey()); - when(pmt.getPayload()).thenReturn(hexKey); - - final Object[] params = new Object[] {pmt.getHash()}; - - final JsonRpcRequestContext request = - new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getPrivateTransaction", params)); - - final JsonRpcSuccessResponse response = - (JsonRpcSuccessResponse) privGetPrivateTransaction.response(request); - final PrivateTransactionLegacyResult result = - (PrivateTransactionLegacyResult) response.getResult(); - - assertThat(new PrivateTransactionLegacyResult(this.privateTransaction)) - .usingRecursiveComparison() - .isEqualTo(result); - } -} diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java deleted file mode 100644 index a5ee5f068e..0000000000 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.ethereum.mainnet.precompiles.privacy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.enclave.Enclave; -import org.hyperledger.besu.enclave.EnclaveFactory; -import org.hyperledger.besu.enclave.types.SendResponse; -import org.hyperledger.besu.ethereum.core.Block; -import org.hyperledger.besu.ethereum.core.BlockDataGenerator; -import org.hyperledger.besu.ethereum.core.MutableWorldState; -import org.hyperledger.besu.ethereum.core.PrivateTransactionDataFixture; -import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader; -import org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils; -import org.hyperledger.besu.ethereum.privacy.PrivateStateGenesisAllocator; -import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; -import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; -import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor; -import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap; -import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; -import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage; -import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; -import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; -import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; -import org.hyperledger.besu.evm.operation.BlockHashOperation.BlockHashLookup; -import org.hyperledger.besu.evm.precompile.PrecompiledContract; -import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; -import org.hyperledger.enclave.testutil.EnclaveEncryptorType; -import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration; -import org.hyperledger.enclave.testutil.TesseraTestHarness; -import org.hyperledger.enclave.testutil.TesseraTestHarnessFactory; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import com.google.common.collect.Lists; -import io.vertx.core.Vertx; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -public class PrivacyPrecompiledContractIntegrationTest { - - // this tempDir is deliberately static - @TempDir private static Path folder; - - private static final Bytes VALID_PRIVATE_TRANSACTION_RLP = - Bytes.fromHexString( - "0xf90113800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87" - + "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - + "ffff801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d" - + "495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab94" - + "9f53faa07bd2c804ac41316156744d784c4355486d425648586f5a7a7a4267" - + "5062572f776a3561784470573958386c393153476f3df85aac41316156744d" - + "784c4355486d425648586f5a7a7a42675062572f776a356178447057395838" - + "6c393153476f3dac4b6f32625671442b6e4e6c4e594c35454537793349644f" - + "6e766966746a69697a706a52742b4854754642733d8a726573747269637465" - + "64"); - private static final String DEFAULT_OUTPUT = "0x01"; - - private static Enclave enclave; - private static MessageFrame messageFrame; - - private static TesseraTestHarness testHarness; - private static WorldStateArchive worldStateArchive; - private static PrivateStateStorage privateStateStorage; - private static final Vertx vertx = Vertx.vertx(); - - private PrivateTransactionProcessor mockPrivateTxProcessor() { - final PrivateTransactionProcessor mockPrivateTransactionProcessor = - mock(PrivateTransactionProcessor.class); - final TransactionProcessingResult result = - TransactionProcessingResult.successful( - null, 0, 0, Bytes.fromHexString(DEFAULT_OUTPUT), null); - when(mockPrivateTransactionProcessor.processTransaction( - nullable(WorldUpdater.class), - nullable(WorldUpdater.class), - nullable(ProcessableBlockHeader.class), - nullable(Hash.class), - nullable(PrivateTransaction.class), - nullable(Address.class), - nullable(OperationTracer.class), - nullable(BlockHashLookup.class), - nullable(Bytes.class))) - .thenReturn(result); - - return mockPrivateTransactionProcessor; - } - - @BeforeAll - public static void setUpOnce() throws Exception { - - testHarness = - TesseraTestHarnessFactory.create( - "enclave", - Files.createTempDirectory(folder, "enclave"), - new EnclaveKeyConfiguration( - new String[] {"enclave_key_0.pub"}, - new String[] {"enclave_key_1.key"}, - EnclaveEncryptorType.NOOP), - Optional.empty()); - - testHarness.start(); - - final EnclaveFactory factory = new EnclaveFactory(vertx); - enclave = factory.createVertxEnclave(testHarness.clientUrl()); - messageFrame = mock(MessageFrame.class); - final BlockDataGenerator blockGenerator = new BlockDataGenerator(); - final Block genesis = blockGenerator.genesisBlock(); - final Block block = - blockGenerator.block( - new BlockDataGenerator.BlockOptions().setParentHash(genesis.getHeader().getHash())); - when(messageFrame.getBlockValues()).thenReturn(block.getHeader()); - final PrivateMetadataUpdater privateMetadataUpdater = mock(PrivateMetadataUpdater.class); - when(privateMetadataUpdater.getPrivateBlockMetadata(any())).thenReturn(null); - when(privateMetadataUpdater.getPrivacyGroupHeadBlockMap()) - .thenReturn(PrivacyGroupHeadBlockMap.empty()); - when(messageFrame.getContextVariable( - eq(PrivateStateUtils.KEY_IS_PERSISTING_PRIVATE_STATE), anyBoolean())) - .thenReturn(false); - when(messageFrame.getContextVariable(eq(PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER))) - .thenReturn(privateMetadataUpdater); - when(messageFrame.hasContextVariable(eq(PrivateStateUtils.KEY_PRIVATE_METADATA_UPDATER))) - .thenReturn(true); - - worldStateArchive = mock(WorldStateArchive.class); - final MutableWorldState mutableWorldState = mock(MutableWorldState.class); - when(mutableWorldState.updater()).thenReturn(mock(WorldUpdater.class)); - when(worldStateArchive.getMutable()).thenReturn(mutableWorldState); - when(worldStateArchive.getMutable(any(), any())).thenReturn(Optional.of(mutableWorldState)); - - privateStateStorage = mock(PrivateStateStorage.class); - final PrivateStateStorage.Updater storageUpdater = mock(PrivateStateStorage.Updater.class); - when(privateStateStorage.getPrivacyGroupHeadBlockMap(any())) - .thenReturn(Optional.of(PrivacyGroupHeadBlockMap.empty())); - when(storageUpdater.putPrivateBlockMetadata( - nullable(Bytes32.class), nullable(Bytes32.class), any())) - .thenReturn(storageUpdater); - when(storageUpdater.putTransactionReceipt( - nullable(Bytes32.class), nullable(Bytes32.class), any())) - .thenReturn(storageUpdater); - when(privateStateStorage.updater()).thenReturn(storageUpdater); - } - - @AfterAll - public static void tearDownOnce() { - testHarness.stop(); - vertx.close(); - } - - @Test - public void testUpCheck() { - assertThat(enclave.upCheck()).isTrue(); - } - - @Test - public void testSendAndReceive() { - final List publicKeys = testHarness.getPublicKeys(); - - final PrivateTransaction privateTransaction = - PrivateTransactionDataFixture.privateContractDeploymentTransactionBesu(publicKeys.get(0)); - final BytesValueRLPOutput bytesValueRLPOutput = new BytesValueRLPOutput(); - privateTransaction.writeTo(bytesValueRLPOutput); - - final String s = bytesValueRLPOutput.encoded().toBase64String(); - final SendResponse sr = - enclave.send(s, publicKeys.get(0), Lists.newArrayList(publicKeys.get(0))); - - final PrivacyPrecompiledContract privacyPrecompiledContract = - new PrivacyPrecompiledContract( - new SpuriousDragonGasCalculator(), - enclave, - worldStateArchive, - new PrivateStateRootResolver(privateStateStorage), - new PrivateStateGenesisAllocator( - false, (privacyGroupId, blockNumber) -> Collections::emptyList), - false, - "IntegrationTest"); - - privacyPrecompiledContract.setPrivateTransactionProcessor(mockPrivateTxProcessor()); - - final PrecompiledContract.PrecompileContractResult result = - privacyPrecompiledContract.computePrecompile( - Bytes.fromBase64String(sr.getKey()), messageFrame); - final Bytes actual = result.getOutput(); - - assertThat(actual).isEqualTo(Bytes.fromHexString(DEFAULT_OUTPUT)); - } - - @Test - public void testNoPrivateKeyError() throws RuntimeException { - final List publicKeys = testHarness.getPublicKeys(); - publicKeys.add("noPrivateKey"); - - final String s = VALID_PRIVATE_TRANSACTION_RLP.toBase64String(); - - final Throwable thrown = catchThrowable(() -> enclave.send(s, publicKeys.get(0), publicKeys)); - - assertThat(thrown).hasMessageContaining("Index 9 out of bounds for length 9"); - } - - @Test - public void testWrongPrivateKeyError() throws RuntimeException { - final List publicKeys = testHarness.getPublicKeys(); - publicKeys.add("noPrivateKenoPrivateKenoPrivateKenoPrivateK"); - - final String s = VALID_PRIVATE_TRANSACTION_RLP.toBase64String(); - - final Throwable thrown = catchThrowable(() -> enclave.send(s, publicKeys.get(0), publicKeys)); - - assertThat(thrown).hasMessageContaining("Recipient not found for key:"); - } -} diff --git a/testutil/src/main/resources/enclave_key_0.key b/testutil/src/main/resources/enclave_key_0.key deleted file mode 100644 index eaae9b0867..0000000000 --- a/testutil/src/main/resources/enclave_key_0.key +++ /dev/null @@ -1 +0,0 @@ -{"data":{"bytes":"hBsuQsGJzx4QHmFmBkNoI7YGnTmaZP4P+wBOdu56ljk="},"type":"unlocked"} \ No newline at end of file