Use token enclave public key when in privacy multi-tenancy mode (#272)

Signed-off-by: Jason Frame <jasonwframe@gmail.com>
pull/282/head
Jason Frame 5 years ago committed by GitHub
parent 665101345a
commit 8f61ff33bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivGetPrivateTransactionIntegrationTest.java
  2. 24
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/EnclavePublicKeyProvider.java
  3. 11
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/PrivacySendTransaction.java
  4. 14
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransaction.java
  5. 12
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroup.java
  6. 14
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroup.java
  7. 14
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransaction.java
  8. 12
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroup.java
  9. 14
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetEeaTransactionCount.java
  10. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransaction.java
  11. 13
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCount.java
  12. 10
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceipt.java
  13. 16
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/EeaJsonRpcMethods.java
  14. 23
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java
  15. 19
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethods.java
  16. 18
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/privacy/eea/PrivGetEeaTransactionCountTest.java
  17. 47
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/eea/EeaSendRawTransactionTest.java
  18. 38
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivCreatePrivacyGroupTest.java
  19. 88
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDeletePrivacyGroupTest.java
  20. 25
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDistributeRawTransactionTest.java
  21. 101
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivFindPrivacyGroupTest.java
  22. 35
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetPrivateTransactionTest.java
  23. 17
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionCountTest.java
  24. 40
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetTransactionReceiptTest.java
  25. 94
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivacyApiGroupJsonRpcMethodsTest.java
  26. 42
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivacyController.java
  27. 71
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/PrivacyControllerTest.java

@ -26,6 +26,7 @@ import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.enclave.types.SendResponse; import org.hyperledger.besu.enclave.types.SendResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivateTransaction; 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.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult;
@ -76,6 +77,8 @@ public class PrivGetPrivateTransactionIntegrationTest {
private static Vertx vertx = Vertx.vertx(); private static Vertx vertx = Vertx.vertx();
private EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@BeforeClass @BeforeClass
public static void setUpOnce() throws Exception { public static void setUpOnce() throws Exception {
folder.create(); folder.create();
@ -89,7 +92,7 @@ public class PrivGetPrivateTransactionIntegrationTest {
final EnclaveFactory factory = new EnclaveFactory(vertx); final EnclaveFactory factory = new EnclaveFactory(vertx);
enclave = factory.createVertxEnclave(testHarness.clientUrl()); enclave = factory.createVertxEnclave(testHarness.clientUrl());
privacyController = new PrivacyController(enclave, ENCLAVE_PUBLIC_KEY, null, null, null, null); privacyController = new PrivacyController(enclave, null, null, null, null);
} }
@AfterClass @AfterClass
@ -148,7 +151,7 @@ public class PrivGetPrivateTransactionIntegrationTest {
public void returnsStoredPrivateTransaction() { public void returnsStoredPrivateTransaction() {
final PrivGetPrivateTransaction privGetPrivateTransaction = final PrivGetPrivateTransaction privGetPrivateTransaction =
new PrivGetPrivateTransaction(blockchain, privacyController); new PrivGetPrivateTransaction(blockchain, privacyController, enclavePublicKeyProvider);
when(blockchain.transactionByHash(any(Hash.class))) when(blockchain.transactionByHash(any(Hash.class)))
.thenReturn(Optional.of(returnedTransaction)); .thenReturn(Optional.of(returnedTransaction));

@ -0,0 +1,24 @@
/*
* 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.internal.privacy.methods;
import java.util.Optional;
import io.vertx.ext.auth.User;
@FunctionalInterface
public interface EnclavePublicKeyProvider {
String getEnclaveKey(Optional<User> user);
}

@ -37,9 +37,13 @@ public class PrivacySendTransaction {
private static final Logger LOG = LogManager.getLogger(); private static final Logger LOG = LogManager.getLogger();
protected final PrivacyController privacyController; protected final PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivacySendTransaction(final PrivacyController privacyController) { public PrivacySendTransaction(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
public PrivateTransaction validateAndDecodeRequest(final JsonRpcRequestContext request) public PrivateTransaction validateAndDecodeRequest(final JsonRpcRequestContext request)
@ -74,7 +78,10 @@ public class PrivacySendTransaction {
final String privacyGroupId, final String privacyGroupId,
final Supplier<JsonRpcResponse> successfulJsonRpcResponse) { final Supplier<JsonRpcResponse> successfulJsonRpcResponse) {
return privacyController return privacyController
.validatePrivateTransaction(privateTransaction, privacyGroupId) .validatePrivateTransaction(
privateTransaction,
privacyGroupId,
enclavePublicKeyProvider.getEnclaveKey(request.getUser()))
.either( .either(
successfulJsonRpcResponse, successfulJsonRpcResponse,
(errorReason) -> (errorReason) ->

@ -19,6 +19,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcErrorConverter;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction.ErrorResponseException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction.ErrorResponseException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@ -33,14 +34,19 @@ import org.hyperledger.besu.ethereum.privacy.SendTransactionResponse;
public class EeaSendRawTransaction implements JsonRpcMethod { public class EeaSendRawTransaction implements JsonRpcMethod {
private final PrivacySendTransaction privacySendTransaction; private final PrivacySendTransaction privacySendTransaction;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
private TransactionPool transactionPool; private TransactionPool transactionPool;
private PrivacyController privacyController; private PrivacyController privacyController;
public EeaSendRawTransaction( public EeaSendRawTransaction(
final TransactionPool transactionPool, final PrivacyController privacyController) { final TransactionPool transactionPool,
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.transactionPool = transactionPool; this.transactionPool = transactionPool;
this.privacyController = privacyController; this.privacyController = privacyController;
this.privacySendTransaction = new PrivacySendTransaction(privacyController); this.privacySendTransaction =
new PrivacySendTransaction(privacyController, enclavePublicKeyProvider);
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -59,7 +65,9 @@ public class EeaSendRawTransaction implements JsonRpcMethod {
final SendTransactionResponse sendTransactionResponse; final SendTransactionResponse sendTransactionResponse;
try { try {
sendTransactionResponse = privacyController.sendTransaction(privateTransaction); sendTransactionResponse =
privacyController.sendTransaction(
privateTransaction, enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
} catch (final Exception e) { } catch (final Exception e) {
return new JsonRpcErrorResponse( return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), requestContext.getRequest().getId(),

@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@ -33,9 +34,13 @@ public class PrivCreatePrivacyGroup implements JsonRpcMethod {
private static final Logger LOG = getLogger(); private static final Logger LOG = getLogger();
private PrivacyController privacyController; private PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivCreatePrivacyGroup(final PrivacyController privacyController) { public PrivCreatePrivacyGroup(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -59,7 +64,10 @@ public class PrivCreatePrivacyGroup implements JsonRpcMethod {
try { try {
response = response =
privacyController.createPrivacyGroup( privacyController.createPrivacyGroup(
parameter.getAddresses(), parameter.getName(), parameter.getDescription()); parameter.getAddresses(),
parameter.getName(),
parameter.getDescription(),
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
} catch (Exception e) { } catch (Exception e) {
LOG.error("Failed to create privacy group", e); LOG.error("Failed to create privacy group", e);
return new JsonRpcErrorResponse( return new JsonRpcErrorResponse(

@ -19,7 +19,9 @@ import static org.apache.logging.log4j.LogManager.getLogger;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.privacy.PrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController;
@ -30,9 +32,13 @@ public class PrivDeletePrivacyGroup implements JsonRpcMethod {
private static final Logger LOG = getLogger(); private static final Logger LOG = getLogger();
private PrivacyController privacyController; private PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivDeletePrivacyGroup(final PrivacyController privacyController) { public PrivDeletePrivacyGroup(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -48,10 +54,12 @@ public class PrivDeletePrivacyGroup implements JsonRpcMethod {
final String response; final String response;
try { try {
response = privacyController.deletePrivacyGroup(privacyGroupId); response =
privacyController.deletePrivacyGroup(
privacyGroupId, enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
} catch (Exception e) { } catch (Exception e) {
LOG.error("Failed to fetch transaction", e); LOG.error("Failed to fetch transaction", e);
return new JsonRpcSuccessResponse( return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.DELETE_PRIVACY_GROUP_ERROR); requestContext.getRequest().getId(), JsonRpcError.DELETE_PRIVACY_GROUP_ERROR);
} }
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), response); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), response);

@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction.ErrorResponseException; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivacySendTransaction.ErrorResponseException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@ -35,10 +36,15 @@ public class PrivDistributeRawTransaction implements JsonRpcMethod {
private final PrivacyController privacyController; private final PrivacyController privacyController;
private final PrivacySendTransaction privacySendTransaction; private final PrivacySendTransaction privacySendTransaction;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivDistributeRawTransaction(final PrivacyController privacyController) { public PrivDistributeRawTransaction(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.privacySendTransaction = new PrivacySendTransaction(privacyController); this.privacySendTransaction =
new PrivacySendTransaction(privacyController, enclavePublicKeyProvider);
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -57,7 +63,9 @@ public class PrivDistributeRawTransaction implements JsonRpcMethod {
final SendTransactionResponse sendTransactionResponse; final SendTransactionResponse sendTransactionResponse;
try { try {
sendTransactionResponse = privacyController.sendTransaction(privateTransaction); sendTransactionResponse =
privacyController.sendTransaction(
privateTransaction, enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
} catch (final Exception e) { } catch (final Exception e) {
return new JsonRpcErrorResponse( return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), requestContext.getRequest().getId(),

@ -20,6 +20,7 @@ import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@ -34,9 +35,13 @@ public class PrivFindPrivacyGroup implements JsonRpcMethod {
private static final Logger LOG = getLogger(); private static final Logger LOG = getLogger();
private PrivacyController privacyController; private PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivFindPrivacyGroup(final PrivacyController privacyController) { public PrivFindPrivacyGroup(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -54,7 +59,10 @@ public class PrivFindPrivacyGroup implements JsonRpcMethod {
PrivacyGroup[] response; PrivacyGroup[] response;
try { try {
response = privacyController.findPrivacyGroup(Arrays.asList(addresses)); response =
privacyController.findPrivacyGroup(
Arrays.asList(addresses),
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
} catch (Exception e) { } catch (Exception e) {
LOG.error("Failed to fetch privacy group", e); LOG.error("Failed to fetch privacy group", e);
return new JsonRpcErrorResponse( return new JsonRpcErrorResponse(

@ -19,6 +19,7 @@ import static org.apache.logging.log4j.LogManager.getLogger;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@ -34,9 +35,13 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod {
private static final Logger LOG = getLogger(); private static final Logger LOG = getLogger();
private PrivacyController privacyController; private PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivGetEeaTransactionCount(final PrivacyController privacyController) { public PrivGetEeaTransactionCount(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -56,7 +61,12 @@ public class PrivGetEeaTransactionCount implements JsonRpcMethod {
final String[] privateFor = requestContext.getRequiredParameter(2, String[].class); final String[] privateFor = requestContext.getRequiredParameter(2, String[].class);
try { try {
final long nonce = privacyController.determineNonce(privateFrom, privateFor, address); final long nonce =
privacyController.determineNonce(
privateFrom,
privateFor,
address,
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
return new JsonRpcSuccessResponse( return new JsonRpcSuccessResponse(
requestContext.getRequest().getId(), Quantity.create(nonce)); requestContext.getRequest().getId(), Quantity.create(nonce));
} catch (final Exception e) { } catch (final Exception e) {

@ -21,6 +21,7 @@ import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionGroupResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionGroupResult;
@ -41,11 +42,15 @@ public class PrivGetPrivateTransaction implements JsonRpcMethod {
private final BlockchainQueries blockchain; private final BlockchainQueries blockchain;
private final PrivacyController privacyController; private final PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivGetPrivateTransaction( public PrivGetPrivateTransaction(
final BlockchainQueries blockchain, final PrivacyController privacyController) { final BlockchainQueries blockchain,
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.blockchain = blockchain; this.blockchain = blockchain;
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -68,7 +73,8 @@ public class PrivGetPrivateTransaction implements JsonRpcMethod {
LOG.trace("Fetching transaction information"); LOG.trace("Fetching transaction information");
final ReceiveResponse receiveResponse = final ReceiveResponse receiveResponse =
privacyController.retrieveTransaction( privacyController.retrieveTransaction(
resultTransaction.getTransaction().getPayload().toBase64String()); resultTransaction.getTransaction().getPayload().toBase64String(),
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
LOG.trace("Received transaction information"); LOG.trace("Received transaction information");
final BytesValueRLPInput input = final BytesValueRLPInput input =

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@ -28,9 +29,13 @@ import org.hyperledger.besu.ethereum.privacy.PrivacyController;
public class PrivGetTransactionCount implements JsonRpcMethod { public class PrivGetTransactionCount implements JsonRpcMethod {
private final PrivacyController privacyController; private final PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivGetTransactionCount(final PrivacyController privacyController) { public PrivGetTransactionCount(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -48,7 +53,11 @@ public class PrivGetTransactionCount implements JsonRpcMethod {
final Address address = requestContext.getRequiredParameter(0, Address.class); final Address address = requestContext.getRequiredParameter(0, Address.class);
final String privacyGroupId = requestContext.getRequiredParameter(1, String.class); final String privacyGroupId = requestContext.getRequiredParameter(1, String.class);
final long nonce = privacyController.determineNonce(address, privacyGroupId); final long nonce =
privacyController.determineNonce(
address,
privacyGroupId,
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), Quantity.create(nonce)); return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), Quantity.create(nonce));
} }
} }

@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcEnclaveErrorConverter;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
@ -56,14 +57,17 @@ public class PrivGetTransactionReceipt implements JsonRpcMethod {
private final BlockchainQueries blockchain; private final BlockchainQueries blockchain;
private PrivacyParameters privacyParameters; private PrivacyParameters privacyParameters;
private PrivacyController privacyController; private PrivacyController privacyController;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public PrivGetTransactionReceipt( public PrivGetTransactionReceipt(
final BlockchainQueries blockchain, final BlockchainQueries blockchain,
final PrivacyParameters privacyParameters, final PrivacyParameters privacyParameters,
final PrivacyController privacyController) { final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.blockchain = blockchain; this.blockchain = blockchain;
this.privacyParameters = privacyParameters; this.privacyParameters = privacyParameters;
this.privacyController = privacyController; this.privacyController = privacyController;
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
} }
@Override @Override
@ -92,7 +96,9 @@ public class PrivGetTransactionReceipt implements JsonRpcMethod {
final String privacyGroupId; final String privacyGroupId;
try { try {
final ReceiveResponse receiveResponse = final ReceiveResponse receiveResponse =
privacyController.retrieveTransaction(transaction.getPayload().toBase64String()); privacyController.retrieveTransaction(
transaction.getPayload().toBase64String(),
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
LOG.trace("Received transaction information"); LOG.trace("Received transaction information");
final BytesValueRLPInput input = final BytesValueRLPInput input =

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.eea.EeaSendRawTransaction; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.eea.EeaSendRawTransaction;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetEeaTransactionCount; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetEeaTransactionCount;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
@ -38,14 +39,17 @@ public class EeaJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
} }
@Override @Override
protected RpcApi getApiGroup() { protected Map<String, JsonRpcMethod> create(
return RpcApis.EEA; final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
return mapOf(
new EeaSendRawTransaction(
getTransactionPool(), privacyController, enclavePublicKeyProvider),
new PrivGetEeaTransactionCount(privacyController, enclavePublicKeyProvider));
} }
@Override @Override
protected Map<String, JsonRpcMethod> create(final PrivacyController privacyController) { protected RpcApi getApiGroup() {
return mapOf( return RpcApis.EEA;
new EeaSendRawTransaction(getTransactionPool(), privacyController),
new PrivGetEeaTransactionCount(privacyController));
} }
} }

@ -17,6 +17,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApi;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivCreatePrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivCreatePrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDeletePrivacyGroup; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDeletePrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDistributeRawTransaction; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDistributeRawTransaction;
@ -49,16 +50,22 @@ public class PrivJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
} }
@Override @Override
protected Map<String, JsonRpcMethod> create(final PrivacyController privacyController) { protected Map<String, JsonRpcMethod> create(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
return mapOf( return mapOf(
new PrivGetTransactionReceipt( new PrivGetTransactionReceipt(
getBlockchainQueries(), getPrivacyParameters(), privacyController), getBlockchainQueries(),
new PrivCreatePrivacyGroup(privacyController), getPrivacyParameters(),
new PrivDeletePrivacyGroup(privacyController), privacyController,
new PrivFindPrivacyGroup(privacyController), enclavePublicKeyProvider),
new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivDeletePrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivFindPrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivGetPrivacyPrecompileAddress(getPrivacyParameters()), new PrivGetPrivacyPrecompileAddress(getPrivacyParameters()),
new PrivGetTransactionCount(privacyController), new PrivGetTransactionCount(privacyController, enclavePublicKeyProvider),
new PrivGetPrivateTransaction(getBlockchainQueries(), privacyController), new PrivGetPrivateTransaction(
new PrivDistributeRawTransaction(privacyController)); getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivDistributeRawTransaction(privacyController, enclavePublicKeyProvider));
} }
} }

@ -14,9 +14,12 @@
*/ */
package org.hyperledger.besu.ethereum.api.jsonrpc.methods; package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiTenancyUserUtil.enclavePublicKey;
import org.hyperledger.besu.ethereum.api.jsonrpc.LatestNonceProvider; import org.hyperledger.besu.ethereum.api.jsonrpc.LatestNonceProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.DisabledPrivacyRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.DisabledPrivacyRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiTenancyRpcMethodDecorator; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiTenancyRpcMethodDecorator;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.Address; import org.hyperledger.besu.ethereum.core.Address;
@ -77,13 +80,25 @@ public abstract class PrivacyApiGroupJsonRpcMethods extends ApiGroupJsonRpcMetho
new PrivacyController( new PrivacyController(
privacyParameters, protocolSchedule.getChainId(), markerTransactionFactory); privacyParameters, protocolSchedule.getChainId(), markerTransactionFactory);
return create(privacyController).entrySet().stream() final EnclavePublicKeyProvider enclavePublicProvider =
privacyParameters.isMultiTenancyEnabled()
? user ->
enclavePublicKey(user)
.orElseThrow(
() ->
new IllegalStateException(
"Request does not contain an authorization token"))
: user -> privacyParameters.getEnclavePublicKey();
return create(privacyController, enclavePublicProvider).entrySet().stream()
.collect( .collect(
Collectors.toMap( Collectors.toMap(
Entry::getKey, entry -> createPrivacyMethod(privacyParameters, entry.getValue()))); Entry::getKey, entry -> createPrivacyMethod(privacyParameters, entry.getValue())));
} }
protected abstract Map<String, JsonRpcMethod> create(final PrivacyController privacyController); protected abstract Map<String, JsonRpcMethod> create(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider);
private PrivateMarkerTransactionFactory createPrivateMarkerTransactionFactory( private PrivateMarkerTransactionFactory createPrivateMarkerTransactionFactory(
final PrivacyParameters privacyParameters, final PrivacyParameters privacyParameters,

@ -20,6 +20,7 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetEeaTransactionCount; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetEeaTransactionCount;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@ -33,6 +34,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
public class PrivGetEeaTransactionCountTest { public class PrivGetEeaTransactionCountTest {
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
private final PrivacyController privacyController = mock(PrivacyController.class); private final PrivacyController privacyController = mock(PrivacyController.class);
@ -41,6 +43,7 @@ public class PrivGetEeaTransactionCountTest {
private final String privateFrom = "thePrivateFromKey"; private final String privateFrom = "thePrivateFromKey";
private final String[] privateFor = new String[] {"first", "second", "third"}; private final String[] privateFor = new String[] {"first", "second", "third"};
private final Address address = Address.fromHexString("55"); private final Address address = Address.fromHexString("55");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Before @Before
public void setup() { public void setup() {
@ -54,9 +57,10 @@ public class PrivGetEeaTransactionCountTest {
@Test @Test
public void validRequestProducesExpectedNonce() { public void validRequestProducesExpectedNonce() {
final long reportedNonce = 8L; final long reportedNonce = 8L;
final PrivGetEeaTransactionCount method = new PrivGetEeaTransactionCount(privacyController); final PrivGetEeaTransactionCount method =
new PrivGetEeaTransactionCount(privacyController, enclavePublicKeyProvider);
when(privacyController.determineNonce(privateFrom, privateFor, address)) when(privacyController.determineNonce(privateFrom, privateFor, address, ENCLAVE_PUBLIC_KEY))
.thenReturn(reportedNonce); .thenReturn(reportedNonce);
final JsonRpcResponse response = method.response(request); final JsonRpcResponse response = method.response(request);
@ -69,9 +73,10 @@ public class PrivGetEeaTransactionCountTest {
@Test @Test
public void nonceProviderThrowsRuntimeExceptionProducesErrorResponse() { public void nonceProviderThrowsRuntimeExceptionProducesErrorResponse() {
final PrivGetEeaTransactionCount method = new PrivGetEeaTransactionCount(privacyController); final PrivGetEeaTransactionCount method =
new PrivGetEeaTransactionCount(privacyController, enclavePublicKeyProvider);
when(privacyController.determineNonce(privateFrom, privateFor, address)) when(privacyController.determineNonce(privateFrom, privateFor, address, ENCLAVE_PUBLIC_KEY))
.thenThrow(RuntimeException.class); .thenThrow(RuntimeException.class);
final JsonRpcResponse response = method.response(request); final JsonRpcResponse response = method.response(request);
@ -84,9 +89,10 @@ public class PrivGetEeaTransactionCountTest {
@Test @Test
public void nonceProviderThrowsAnExceptionProducesErrorResponse() { public void nonceProviderThrowsAnExceptionProducesErrorResponse() {
final PrivGetEeaTransactionCount method = new PrivGetEeaTransactionCount(privacyController); final PrivGetEeaTransactionCount method =
new PrivGetEeaTransactionCount(privacyController, enclavePublicKeyProvider);
when(privacyController.determineNonce(privateFrom, privateFor, address)) when(privacyController.determineNonce(privateFrom, privateFor, address, ENCLAVE_PUBLIC_KEY))
.thenThrow(RuntimeException.class); .thenThrow(RuntimeException.class);
final JsonRpcResponse response = method.response(request); final JsonRpcResponse response = method.response(request);

@ -16,6 +16,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.eea;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.verifyZeroInteractions;
@ -25,6 +26,7 @@ import org.hyperledger.besu.crypto.SECP256K1;
import org.hyperledger.besu.enclave.EnclaveServerException; import org.hyperledger.besu.enclave.EnclaveServerException;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@ -42,6 +44,9 @@ import org.hyperledger.besu.ethereum.privacy.SendTransactionResponse;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Optional; import java.util.Optional;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -106,9 +111,13 @@ public class EeaSendRawTransactionTest {
Bytes.fromHexString("0x"), Bytes.fromHexString("0x"),
Address.wrap(Bytes.fromHexString("0x8411b12666f68ef74cace3615c9d5a377729d03f")), Address.wrap(Bytes.fromHexString("0x8411b12666f68ef74cace3615c9d5a377729d03f")),
Optional.empty()); Optional.empty());
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
final String MOCK_ORION_KEY = ""; private final String MOCK_ORION_KEY = "";
final String MOCK_PRIVACY_GROUP = ""; private final String MOCK_PRIVACY_GROUP = "";
private final User user =
new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Mock private TransactionPool transactionPool; @Mock private TransactionPool transactionPool;
@ -118,7 +127,8 @@ public class EeaSendRawTransactionTest {
@Before @Before
public void before() { public void before() {
method = new EeaSendRawTransaction(transactionPool, privacyController); method =
new EeaSendRawTransaction(transactionPool, privacyController, enclavePublicKeyProvider);
} }
@Test @Test
@ -195,10 +205,10 @@ public class EeaSendRawTransactionTest {
@Test @Test
public void validTransactionIsSentToTransactionPool() { public void validTransactionIsSentToTransactionPool() {
when(privacyController.sendTransaction(any(PrivateTransaction.class))) when(privacyController.sendTransaction(any(PrivateTransaction.class), any()))
.thenReturn(new SendTransactionResponse(MOCK_ORION_KEY, MOCK_PRIVACY_GROUP)); .thenReturn(new SendTransactionResponse(MOCK_ORION_KEY, MOCK_PRIVACY_GROUP));
when(privacyController.validatePrivateTransaction( when(privacyController.validatePrivateTransaction(
any(PrivateTransaction.class), any(String.class))) any(PrivateTransaction.class), any(String.class), any()))
.thenReturn(ValidationResult.valid()); .thenReturn(ValidationResult.valid());
when(privacyController.createPrivacyMarkerTransaction( when(privacyController.createPrivacyMarkerTransaction(
any(String.class), any(PrivateTransaction.class))) any(String.class), any(PrivateTransaction.class)))
@ -208,7 +218,8 @@ public class EeaSendRawTransactionTest {
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext( new JsonRpcRequestContext(
new JsonRpcRequest( new JsonRpcRequest(
"2.0", "eea_sendRawTransaction", new String[] {VALID_PRIVATE_TRANSACTION_RLP})); "2.0", "eea_sendRawTransaction", new String[] {VALID_PRIVATE_TRANSACTION_RLP}),
user);
final JsonRpcResponse expectedResponse = final JsonRpcResponse expectedResponse =
new JsonRpcSuccessResponse( new JsonRpcSuccessResponse(
@ -218,9 +229,11 @@ public class EeaSendRawTransactionTest {
final JsonRpcResponse actualResponse = method.response(request); final JsonRpcResponse actualResponse = method.response(request);
assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse);
verify(privacyController).sendTransaction(any(PrivateTransaction.class));
verify(privacyController) verify(privacyController)
.validatePrivateTransaction(any(PrivateTransaction.class), any(String.class)); .sendTransaction(any(PrivateTransaction.class), eq(ENCLAVE_PUBLIC_KEY));
verify(privacyController)
.validatePrivateTransaction(
any(PrivateTransaction.class), any(String.class), eq(ENCLAVE_PUBLIC_KEY));
verify(privacyController) verify(privacyController)
.createPrivacyMarkerTransaction(any(String.class), any(PrivateTransaction.class)); .createPrivacyMarkerTransaction(any(String.class), any(PrivateTransaction.class));
verify(transactionPool).addLocalTransaction(any(Transaction.class)); verify(transactionPool).addLocalTransaction(any(Transaction.class));
@ -228,10 +241,10 @@ public class EeaSendRawTransactionTest {
@Test @Test
public void validTransactionPrivacyGroupIsSentToTransactionPool() { public void validTransactionPrivacyGroupIsSentToTransactionPool() {
when(privacyController.sendTransaction(any(PrivateTransaction.class))) when(privacyController.sendTransaction(any(PrivateTransaction.class), any()))
.thenReturn(new SendTransactionResponse(MOCK_ORION_KEY, MOCK_PRIVACY_GROUP)); .thenReturn(new SendTransactionResponse(MOCK_ORION_KEY, MOCK_PRIVACY_GROUP));
when(privacyController.validatePrivateTransaction( when(privacyController.validatePrivateTransaction(
any(PrivateTransaction.class), any(String.class))) any(PrivateTransaction.class), any(String.class), any()))
.thenReturn(ValidationResult.valid()); .thenReturn(ValidationResult.valid());
when(privacyController.createPrivacyMarkerTransaction( when(privacyController.createPrivacyMarkerTransaction(
any(String.class), any(PrivateTransaction.class))) any(String.class), any(PrivateTransaction.class)))
@ -254,9 +267,9 @@ public class EeaSendRawTransactionTest {
final JsonRpcResponse actualResponse = method.response(request); final JsonRpcResponse actualResponse = method.response(request);
assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse);
verify(privacyController).sendTransaction(any(PrivateTransaction.class)); verify(privacyController).sendTransaction(any(PrivateTransaction.class), any());
verify(privacyController) verify(privacyController)
.validatePrivateTransaction(any(PrivateTransaction.class), any(String.class)); .validatePrivateTransaction(any(PrivateTransaction.class), any(String.class), any());
verify(privacyController) verify(privacyController)
.createPrivacyMarkerTransaction(any(String.class), any(PrivateTransaction.class)); .createPrivacyMarkerTransaction(any(String.class), any(PrivateTransaction.class));
verify(transactionPool).addLocalTransaction(any(Transaction.class)); verify(transactionPool).addLocalTransaction(any(Transaction.class));
@ -282,7 +295,7 @@ public class EeaSendRawTransactionTest {
@Test @Test
public void invalidTransactionIsNotSentToTransactionPool() { public void invalidTransactionIsNotSentToTransactionPool() {
when(privacyController.sendTransaction(any(PrivateTransaction.class))) when(privacyController.sendTransaction(any(PrivateTransaction.class), any()))
.thenThrow(new EnclaveServerException(500, "enclave failed to execute")); .thenThrow(new EnclaveServerException(500, "enclave failed to execute"));
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
@ -346,10 +359,10 @@ public class EeaSendRawTransactionTest {
private void verifyErrorForInvalidTransaction( private void verifyErrorForInvalidTransaction(
final TransactionInvalidReason transactionInvalidReason, final JsonRpcError expectedError) { final TransactionInvalidReason transactionInvalidReason, final JsonRpcError expectedError) {
when(privacyController.sendTransaction(any(PrivateTransaction.class))) when(privacyController.sendTransaction(any(PrivateTransaction.class), any()))
.thenReturn(new SendTransactionResponse(MOCK_ORION_KEY, MOCK_PRIVACY_GROUP)); .thenReturn(new SendTransactionResponse(MOCK_ORION_KEY, MOCK_PRIVACY_GROUP));
when(privacyController.validatePrivateTransaction( when(privacyController.validatePrivateTransaction(
any(PrivateTransaction.class), any(String.class))) any(PrivateTransaction.class), any(String.class), any()))
.thenReturn(ValidationResult.valid()); .thenReturn(ValidationResult.valid());
when(privacyController.createPrivacyMarkerTransaction( when(privacyController.createPrivacyMarkerTransaction(
any(String.class), any(PrivateTransaction.class))) any(String.class), any(PrivateTransaction.class)))
@ -367,9 +380,9 @@ public class EeaSendRawTransactionTest {
final JsonRpcResponse actualResponse = method.response(request); final JsonRpcResponse actualResponse = method.response(request);
assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse);
verify(privacyController).sendTransaction(any(PrivateTransaction.class)); verify(privacyController).sendTransaction(any(PrivateTransaction.class), any());
verify(privacyController) verify(privacyController)
.validatePrivateTransaction(any(PrivateTransaction.class), any(String.class)); .validatePrivateTransaction(any(PrivateTransaction.class), any(String.class), any());
verify(privacyController) verify(privacyController)
.createPrivacyMarkerTransaction(any(String.class), any(PrivateTransaction.class)); .createPrivacyMarkerTransaction(any(String.class), any(PrivateTransaction.class));
verify(transactionPool).addLocalTransaction(any(Transaction.class)); verify(transactionPool).addLocalTransaction(any(Transaction.class));

@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowableOfType; import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.Enclave; import org.hyperledger.besu.enclave.Enclave;
@ -26,6 +27,7 @@ import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.parameters.CreatePrivacyGroupParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
@ -35,6 +37,9 @@ import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import java.util.List; import java.util.List;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.assertj.core.util.Lists; import org.assertj.core.util.Lists;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -45,10 +50,14 @@ public class PrivCreatePrivacyGroupTest {
private static final String NAME = "testName"; private static final String NAME = "testName";
private static final String DESCRIPTION = "testDesc"; private static final String DESCRIPTION = "testDesc";
private static final List<String> ADDRESSES = Lists.newArrayList(FROM, "second participant"); private static final List<String> ADDRESSES = Lists.newArrayList(FROM, "second participant");
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private final Enclave enclave = mock(Enclave.class); private final Enclave enclave = mock(Enclave.class);
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
private final PrivacyController privacyController = mock(PrivacyController.class); private final PrivacyController privacyController = mock(PrivacyController.class);
private final User user =
new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Before @Before
public void setUp() { public void setUp() {
@ -61,12 +70,12 @@ public class PrivCreatePrivacyGroupTest {
final String expected = "a wonderful group"; final String expected = "a wonderful group";
final PrivacyGroup privacyGroup = final PrivacyGroup privacyGroup =
new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES); new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES);
when(privacyController.createPrivacyGroup(ADDRESSES, NAME, DESCRIPTION)) when(privacyController.createPrivacyGroup(ADDRESSES, NAME, DESCRIPTION, ENCLAVE_PUBLIC_KEY))
.thenReturn(privacyGroup); .thenReturn(privacyGroup);
when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM); when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM);
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final CreatePrivacyGroupParameter param = final CreatePrivacyGroupParameter param =
new CreatePrivacyGroupParameter(ADDRESSES, NAME, DESCRIPTION); new CreatePrivacyGroupParameter(ADDRESSES, NAME, DESCRIPTION);
@ -74,7 +83,7 @@ public class PrivCreatePrivacyGroupTest {
final Object[] params = new Object[] {param}; final Object[] params = new Object[] {param};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_createPrivacyGroup", params)); new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_createPrivacyGroup", params), user);
final JsonRpcSuccessResponse response = final JsonRpcSuccessResponse response =
(JsonRpcSuccessResponse) privCreatePrivacyGroup.response(request); (JsonRpcSuccessResponse) privCreatePrivacyGroup.response(request);
@ -82,6 +91,7 @@ public class PrivCreatePrivacyGroupTest {
final String result = (String) response.getResult(); final String result = (String) response.getResult();
assertThat(result).isEqualTo(expected); assertThat(result).isEqualTo(expected);
verify(privacyController).createPrivacyGroup(ADDRESSES, NAME, DESCRIPTION, ENCLAVE_PUBLIC_KEY);
} }
@Test @Test
@ -89,11 +99,12 @@ public class PrivCreatePrivacyGroupTest {
final String expected = "a wonderful group"; final String expected = "a wonderful group";
final PrivacyGroup privacyGroup = final PrivacyGroup privacyGroup =
new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES); new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES);
when(privacyController.createPrivacyGroup(ADDRESSES, NAME, null)).thenReturn(privacyGroup); when(privacyController.createPrivacyGroup(ADDRESSES, NAME, null, ENCLAVE_PUBLIC_KEY))
.thenReturn(privacyGroup);
when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM); when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM);
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final Object[] params = final Object[] params =
new Object[] { new Object[] {
@ -124,12 +135,12 @@ public class PrivCreatePrivacyGroupTest {
final String expected = "a wonderful group"; final String expected = "a wonderful group";
final PrivacyGroup privacyGroup = final PrivacyGroup privacyGroup =
new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES); new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES);
when(privacyController.createPrivacyGroup(ADDRESSES, null, DESCRIPTION)) when(privacyController.createPrivacyGroup(ADDRESSES, null, DESCRIPTION, ENCLAVE_PUBLIC_KEY))
.thenReturn(privacyGroup); .thenReturn(privacyGroup);
when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM); when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM);
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final Object[] params = final Object[] params =
new Object[] { new Object[] {
@ -160,11 +171,12 @@ public class PrivCreatePrivacyGroupTest {
final String expected = "a wonderful group"; final String expected = "a wonderful group";
final PrivacyGroup privacyGroup = final PrivacyGroup privacyGroup =
new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES); new PrivacyGroup(expected, PrivacyGroup.Type.PANTHEON, NAME, DESCRIPTION, ADDRESSES);
when(privacyController.createPrivacyGroup(ADDRESSES, null, null)).thenReturn(privacyGroup); when(privacyController.createPrivacyGroup(ADDRESSES, null, null, ENCLAVE_PUBLIC_KEY))
.thenReturn(privacyGroup);
when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM); when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM);
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final Object[] params = final Object[] params =
new Object[] { new Object[] {
@ -196,7 +208,7 @@ public class PrivCreatePrivacyGroupTest {
when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM); when(privacyParameters.getEnclavePublicKey()).thenReturn(FROM);
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final Object[] params = final Object[] params =
new Object[] { new Object[] {
@ -225,7 +237,7 @@ public class PrivCreatePrivacyGroupTest {
public void returnsCorrectExceptionMissingParam() { public void returnsCorrectExceptionMissingParam() {
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {}; final Object[] params = new Object[] {};
@ -241,10 +253,10 @@ public class PrivCreatePrivacyGroupTest {
@Test @Test
public void returnsCorrectErrorEnclaveError() { public void returnsCorrectErrorEnclaveError() {
when(privacyController.createPrivacyGroup(ADDRESSES, NAME, DESCRIPTION)) when(privacyController.createPrivacyGroup(ADDRESSES, NAME, DESCRIPTION, ENCLAVE_PUBLIC_KEY))
.thenThrow(new EnclaveServerException(500, "")); .thenThrow(new EnclaveServerException(500, ""));
final PrivCreatePrivacyGroup privCreatePrivacyGroup = final PrivCreatePrivacyGroup privCreatePrivacyGroup =
new PrivCreatePrivacyGroup(privacyController); new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider);
final CreatePrivacyGroupParameter param = final CreatePrivacyGroupParameter param =
new CreatePrivacyGroupParameter(ADDRESSES, NAME, DESCRIPTION); new CreatePrivacyGroupParameter(ADDRESSES, NAME, DESCRIPTION);

@ -0,0 +1,88 @@
/*
* 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.internal.privacy.methods.priv;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.Enclave;
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.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.junit.Before;
import org.junit.Test;
public class PrivDeletePrivacyGroupTest {
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final String PRIVACY_GROUP_ID = "privacyGroupId";
private final Enclave enclave = mock(Enclave.class);
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
private final PrivacyController privacyController = mock(PrivacyController.class);
private final User user =
new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
private JsonRpcRequestContext request;
@Before
public void setUp() {
when(privacyParameters.getEnclave()).thenReturn(enclave);
when(privacyParameters.isEnabled()).thenReturn(true);
request =
new JsonRpcRequestContext(
new JsonRpcRequest("1", "priv_deletePrivacyGroup", new Object[] {PRIVACY_GROUP_ID}),
user);
}
@Test
public void deletesPrivacyGroupWithValidGroupId() {
when(privacyController.deletePrivacyGroup(PRIVACY_GROUP_ID, ENCLAVE_PUBLIC_KEY))
.thenReturn(PRIVACY_GROUP_ID);
final PrivDeletePrivacyGroup privDeletePrivacyGroup =
new PrivDeletePrivacyGroup(privacyController, enclavePublicKeyProvider);
final JsonRpcSuccessResponse response =
(JsonRpcSuccessResponse) privDeletePrivacyGroup.response(request);
final String result = (String) response.getResult();
assertThat(result).isEqualTo(PRIVACY_GROUP_ID);
verify(privacyController).deletePrivacyGroup(PRIVACY_GROUP_ID, ENCLAVE_PUBLIC_KEY);
}
@Test
public void failsWithDeletePrivacyGroupErrorIfEnclaveFails() {
when(privacyController.deletePrivacyGroup(PRIVACY_GROUP_ID, ENCLAVE_PUBLIC_KEY))
.thenThrow(new IllegalStateException("some failure"));
final PrivDeletePrivacyGroup privDeletePrivacyGroup =
new PrivDeletePrivacyGroup(privacyController, enclavePublicKeyProvider);
final JsonRpcErrorResponse response =
(JsonRpcErrorResponse) privDeletePrivacyGroup.response(request);
assertThat(response.getError()).isEqualTo(JsonRpcError.DELETE_PRIVACY_GROUP_ERROR);
verify(privacyController).deletePrivacyGroup(PRIVACY_GROUP_ID, ENCLAVE_PUBLIC_KEY);
}
}

@ -16,11 +16,13 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult; import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
@ -30,6 +32,9 @@ import org.hyperledger.besu.ethereum.privacy.SendTransactionResponse;
import java.util.Base64; import java.util.Base64;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -48,22 +53,27 @@ public class PrivDistributeRawTransactionTest {
+ "e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa00f" + "e60551d7a19cf30603db5bfc23e5ac43a56f57f25f75486aa00f"
+ "200e885ff29e973e2576b6600181d1b0a2b5294e30d9be4a1981" + "200e885ff29e973e2576b6600181d1b0a2b5294e30d9be4a1981"
+ "ffb33a0b8c8a72657374726963746564"; + "ffb33a0b8c8a72657374726963746564";
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private final User user =
new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Mock private PrivDistributeRawTransaction method; @Mock private PrivDistributeRawTransaction method;
@Mock private PrivacyController privacyController; @Mock private PrivacyController privacyController;
@Before @Before
public void before() { public void before() {
method = new PrivDistributeRawTransaction(privacyController); method = new PrivDistributeRawTransaction(privacyController, enclavePublicKeyProvider);
} }
@Test @Test
public void validTransactionHashReturnedAfterDistribute() { public void validTransactionHashReturnedAfterDistribute() {
final String enclavePublicKey = "93Ky7lXwFkMc7+ckoFgUMku5bpr9tz4zhmWmk9RlNng="; final String enclavePublicKey = "93Ky7lXwFkMc7+ckoFgUMku5bpr9tz4zhmWmk9RlNng=";
when(privacyController.sendTransaction(any(PrivateTransaction.class))) when(privacyController.sendTransaction(any(PrivateTransaction.class), any()))
.thenReturn(new SendTransactionResponse(enclavePublicKey, "")); .thenReturn(new SendTransactionResponse(enclavePublicKey, ""));
when(privacyController.validatePrivateTransaction( when(privacyController.validatePrivateTransaction(
any(PrivateTransaction.class), any(String.class))) any(PrivateTransaction.class), any(String.class), any()))
.thenReturn(ValidationResult.valid()); .thenReturn(ValidationResult.valid());
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
@ -71,7 +81,8 @@ public class PrivDistributeRawTransactionTest {
new JsonRpcRequest( new JsonRpcRequest(
"2.0", "2.0",
"priv_distributeRawTransaction", "priv_distributeRawTransaction",
new String[] {VALID_PRIVATE_TRANSACTION_RLP_PRIVACY_GROUP})); new String[] {VALID_PRIVATE_TRANSACTION_RLP_PRIVACY_GROUP}),
user);
final JsonRpcResponse expectedResponse = final JsonRpcResponse expectedResponse =
new JsonRpcSuccessResponse( new JsonRpcSuccessResponse(
@ -81,8 +92,10 @@ public class PrivDistributeRawTransactionTest {
final JsonRpcResponse actualResponse = method.response(request); final JsonRpcResponse actualResponse = method.response(request);
assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse); assertThat(actualResponse).isEqualToComparingFieldByField(expectedResponse);
verify(privacyController).sendTransaction(any(PrivateTransaction.class));
verify(privacyController) verify(privacyController)
.validatePrivateTransaction(any(PrivateTransaction.class), any(String.class)); .sendTransaction(any(PrivateTransaction.class), eq(ENCLAVE_PUBLIC_KEY));
verify(privacyController)
.validatePrivateTransaction(
any(PrivateTransaction.class), any(String.class), eq(ENCLAVE_PUBLIC_KEY));
} }
} }

@ -0,0 +1,101 @@
/*
* 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.internal.privacy.methods.priv;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.types.PrivacyGroup;
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.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import java.util.List;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.assertj.core.util.Lists;
import org.junit.Before;
import org.junit.Test;
public class PrivFindPrivacyGroupTest {
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final List<String> ADDRESSES =
List.of(
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"0x627306090abab3a6e1400e9345bc60c78a8bef57");
private final Enclave enclave = mock(Enclave.class);
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
private final PrivacyController privacyController = mock(PrivacyController.class);
private final User user =
new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
private JsonRpcRequestContext request;
private PrivacyGroup privacyGroup;
@Before
public void setUp() {
when(privacyParameters.getEnclave()).thenReturn(enclave);
when(privacyParameters.isEnabled()).thenReturn(true);
request =
new JsonRpcRequestContext(
new JsonRpcRequest("1", "priv_deletePrivacyGroup", new Object[] {ADDRESSES}), user);
privacyGroup = new PrivacyGroup();
privacyGroup.setName("privacyGroup");
privacyGroup.setDescription("privacyGroup desc");
privacyGroup.setPrivacyGroupId("privacy group id");
privacyGroup.setMembers(Lists.list("member1"));
}
@Test
public void findsPrivacyGroupWithValidAddresses() {
when(privacyController.findPrivacyGroup(ADDRESSES, ENCLAVE_PUBLIC_KEY))
.thenReturn(new PrivacyGroup[] {privacyGroup});
final PrivFindPrivacyGroup privFindPrivacyGroup =
new PrivFindPrivacyGroup(privacyController, enclavePublicKeyProvider);
final JsonRpcSuccessResponse response =
(JsonRpcSuccessResponse) privFindPrivacyGroup.response(request);
final PrivacyGroup[] result = (PrivacyGroup[]) response.getResult();
assertThat(result).hasSize(1);
assertThat(result[0]).isEqualToComparingFieldByField(privacyGroup);
verify(privacyController).findPrivacyGroup(ADDRESSES, ENCLAVE_PUBLIC_KEY);
}
@Test
public void failsWithFindPrivacyGroupErrorIfEnclaveFails() {
when(privacyController.findPrivacyGroup(ADDRESSES, ENCLAVE_PUBLIC_KEY))
.thenThrow(new IllegalStateException("some failure"));
final PrivFindPrivacyGroup privFindPrivacyGroup =
new PrivFindPrivacyGroup(privacyController, enclavePublicKeyProvider);
final JsonRpcErrorResponse response =
(JsonRpcErrorResponse) privFindPrivacyGroup.response(request);
assertThat(response.getError()).isEqualTo(JsonRpcError.FIND_PRIVACY_GROUP_ERROR);
verify(privacyController).findPrivacyGroup(ADDRESSES, ENCLAVE_PUBLIC_KEY);
}
}

@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.crypto.SECP256K1; import org.hyperledger.besu.crypto.SECP256K1;
@ -26,6 +27,7 @@ import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.types.ReceiveResponse; import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionGroupResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionGroupResult;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionLegacyResult;
@ -48,6 +50,9 @@ import java.util.Base64;
import java.util.Optional; import java.util.Optional;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -65,6 +70,11 @@ public class PrivGetPrivateTransactionTest {
SECP256K1.PrivateKey.create( SECP256K1.PrivateKey.create(
new BigInteger( new BigInteger(
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16)));
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final String TRANSACTION_HASH =
Bytes.fromBase64String("5bpr9tz4zhmWmk9RlNng93Ky7lXwFkMc7+ckoFgUMku=").toString();
private static final Bytes ENCLAVE_KEY =
Bytes.fromBase64String("93Ky7lXwFkMc7+ckoFgUMku5bpr9tz4zhmWmk9RlNng=");
private final PrivateTransaction.Builder privateTransactionBuilder = private final PrivateTransaction.Builder privateTransactionBuilder =
PrivateTransaction.builder() PrivateTransaction.builder()
@ -90,15 +100,15 @@ public class PrivGetPrivateTransactionTest {
.privateFrom(Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=")) .privateFrom(Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="))
.restriction(Restriction.RESTRICTED); .restriction(Restriction.RESTRICTED);
private final String enclaveKey =
Bytes.fromBase64String("93Ky7lXwFkMc7+ckoFgUMku5bpr9tz4zhmWmk9RlNng=").toString();
private final Enclave enclave = mock(Enclave.class); private final Enclave enclave = mock(Enclave.class);
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
private final BlockchainQueries blockchain = mock(BlockchainQueries.class); private final BlockchainQueries blockchain = mock(BlockchainQueries.class);
private final TransactionWithMetadata returnedTransaction = mock(TransactionWithMetadata.class); private final TransactionWithMetadata returnedTransaction = mock(TransactionWithMetadata.class);
private final Transaction justTransaction = mock(Transaction.class); private final Transaction justTransaction = mock(Transaction.class);
private final PrivacyController privacyController = mock(PrivacyController.class); private final PrivacyController privacyController = mock(PrivacyController.class);
private final User user =
new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Before @Before
public void before() { public void before() {
@ -111,8 +121,7 @@ public class PrivGetPrivateTransactionTest {
when(blockchain.transactionByHash(any(Hash.class))) when(blockchain.transactionByHash(any(Hash.class)))
.thenReturn(Optional.of(returnedTransaction)); .thenReturn(Optional.of(returnedTransaction));
when(returnedTransaction.getTransaction()).thenReturn(justTransaction); when(returnedTransaction.getTransaction()).thenReturn(justTransaction);
when(justTransaction.getPayload()) when(justTransaction.getPayload()).thenReturn(new UnformattedDataImpl(ENCLAVE_KEY));
.thenReturn(new UnformattedDataImpl(Bytes.fromBase64String("")));
final PrivateTransaction privateTransaction = final PrivateTransaction privateTransaction =
privateTransactionBuilder privateTransactionBuilder
@ -124,14 +133,15 @@ public class PrivGetPrivateTransactionTest {
new PrivateTransactionLegacyResult(privateTransaction); new PrivateTransactionLegacyResult(privateTransaction);
final PrivGetPrivateTransaction privGetPrivateTransaction = final PrivGetPrivateTransaction privGetPrivateTransaction =
new PrivGetPrivateTransaction(blockchain, privacyController); new PrivGetPrivateTransaction(blockchain, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {enclaveKey}; final Object[] params = new Object[] {TRANSACTION_HASH};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getPrivateTransaction", params)); new JsonRpcRequestContext(
new JsonRpcRequest("1", "priv_getPrivateTransaction", params), user);
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
privateTransaction.writeTo(bvrlp); privateTransaction.writeTo(bvrlp);
when(privacyController.retrieveTransaction(anyString())) when(privacyController.retrieveTransaction(anyString(), any()))
.thenReturn( .thenReturn(
new ReceiveResponse( new ReceiveResponse(
Base64.getEncoder().encodeToString(bvrlp.encoded().toArray()).getBytes(UTF_8), "")); Base64.getEncoder().encodeToString(bvrlp.encoded().toArray()).getBytes(UTF_8), ""));
@ -140,6 +150,7 @@ public class PrivGetPrivateTransactionTest {
final PrivateTransactionResult result = (PrivateTransactionResult) response.getResult(); final PrivateTransactionResult result = (PrivateTransactionResult) response.getResult();
assertThat(result).isEqualToComparingFieldByField(privateTransactionLegacyResult); assertThat(result).isEqualToComparingFieldByField(privateTransactionLegacyResult);
verify(privacyController).retrieveTransaction(ENCLAVE_KEY.toBase64String(), ENCLAVE_PUBLIC_KEY);
} }
@Test @Test
@ -158,15 +169,15 @@ public class PrivGetPrivateTransactionTest {
new PrivateTransactionGroupResult(privateTransaction); new PrivateTransactionGroupResult(privateTransaction);
final PrivGetPrivateTransaction privGetPrivateTransaction = final PrivGetPrivateTransaction privGetPrivateTransaction =
new PrivGetPrivateTransaction(blockchain, privacyController); new PrivGetPrivateTransaction(blockchain, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {enclaveKey}; final Object[] params = new Object[] {TRANSACTION_HASH};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getPrivateTransaction", params)); new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getPrivateTransaction", params));
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput(); final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
privateTransaction.writeTo(bvrlp); privateTransaction.writeTo(bvrlp);
when(privacyController.retrieveTransaction(anyString())) when(privacyController.retrieveTransaction(anyString(), any()))
.thenReturn( .thenReturn(
new ReceiveResponse( new ReceiveResponse(
Base64.getEncoder().encodeToString(bvrlp.encoded().toArrayUnsafe()).getBytes(UTF_8), Base64.getEncoder().encodeToString(bvrlp.encoded().toArrayUnsafe()).getBytes(UTF_8),

@ -17,21 +17,27 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.core.Address; import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.privacy.PrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
public class PrivGetTransactionCountTest { public class PrivGetTransactionCountTest {
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
private final PrivacyController privacyController = mock(PrivacyController.class); private final PrivacyController privacyController = mock(PrivacyController.class);
@ -40,25 +46,30 @@ public class PrivGetTransactionCountTest {
private final Address senderAddress = private final Address senderAddress =
Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57"); Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57");
private final long NONCE = 5; private final long NONCE = 5;
private User user = new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
@Before @Before
public void before() { public void before() {
when(privacyParameters.isEnabled()).thenReturn(true); when(privacyParameters.isEnabled()).thenReturn(true);
when(privacyController.determineNonce(senderAddress, privacyGroupId)).thenReturn(NONCE); when(privacyController.determineNonce(senderAddress, privacyGroupId, ENCLAVE_PUBLIC_KEY))
.thenReturn(NONCE);
} }
@Test @Test
public void verifyTransactionCount() { public void verifyTransactionCount() {
final PrivGetTransactionCount privGetTransactionCount = final PrivGetTransactionCount privGetTransactionCount =
new PrivGetTransactionCount(privacyController); new PrivGetTransactionCount(privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {senderAddress, privacyGroupId}; final Object[] params = new Object[] {senderAddress, privacyGroupId};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionCount", params)); new JsonRpcRequestContext(
new JsonRpcRequest("1", "priv_getTransactionCount", params), user);
final JsonRpcSuccessResponse response = final JsonRpcSuccessResponse response =
(JsonRpcSuccessResponse) privGetTransactionCount.response(request); (JsonRpcSuccessResponse) privGetTransactionCount.response(request);
assertThat(response.getResult()).isEqualTo(String.format("0x%X", NONCE)); assertThat(response.getResult()).isEqualTo(String.format("0x%X", NONCE));
verify(privacyController).determineNonce(senderAddress, privacyGroupId, ENCLAVE_PUBLIC_KEY);
} }
} }

@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.hyperledger.besu.crypto.SECP256K1; import org.hyperledger.besu.crypto.SECP256K1;
@ -29,6 +30,7 @@ import org.hyperledger.besu.enclave.EnclaveServerException;
import org.hyperledger.besu.enclave.types.ReceiveResponse; import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionReceiptResult; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.privacy.PrivateTransactionReceiptResult;
@ -54,6 +56,9 @@ import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
import org.junit.Before; import org.junit.Before;
@ -65,6 +70,8 @@ public class PrivGetTransactionReceiptTest {
@Rule public final TemporaryFolder temp = new TemporaryFolder(); @Rule public final TemporaryFolder temp = new TemporaryFolder();
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final Bytes ENCLAVE_KEY = Bytes.wrap("EnclaveKey".getBytes(UTF_8));
private static final Address SENDER = private static final Address SENDER =
Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"); Address.fromHexString("0xfe3b557e8fb62b89f4916b721be55ceb828dbd73");
@ -135,6 +142,9 @@ public class PrivGetTransactionReceiptTest {
null, null,
Quantity.create(Bytes.of(1).toUnsignedBigInteger())); Quantity.create(Bytes.of(1).toUnsignedBigInteger()));
private User user = new JWTUser(new JsonObject().put("privacyPublicKey", ENCLAVE_PUBLIC_KEY), "");
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
private final BlockchainQueries blockchainQueries = mock(BlockchainQueries.class); private final BlockchainQueries blockchainQueries = mock(BlockchainQueries.class);
private final Blockchain blockchain = mock(Blockchain.class); private final Blockchain blockchain = mock(Blockchain.class);
private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class); private final PrivacyParameters privacyParameters = mock(PrivacyParameters.class);
@ -143,7 +153,7 @@ public class PrivGetTransactionReceiptTest {
@Before @Before
public void setUp() { public void setUp() {
when(privacyController.retrieveTransaction(anyString())) when(privacyController.retrieveTransaction(anyString(), any()))
.thenReturn( .thenReturn(
new ReceiveResponse( new ReceiveResponse(
Base64.getEncoder().encode(RLP.encode(privateTransaction::writeTo).toArray()), "")); Base64.getEncoder().encode(RLP.encode(privateTransaction::writeTo).toArray()), ""));
@ -170,10 +180,12 @@ public class PrivGetTransactionReceiptTest {
public void returnReceiptIfTransactionExists() { public void returnReceiptIfTransactionExists() {
final PrivGetTransactionReceipt privGetTransactionReceipt = final PrivGetTransactionReceipt privGetTransactionReceipt =
new PrivGetTransactionReceipt(blockchainQueries, privacyParameters, privacyController); new PrivGetTransactionReceipt(
blockchainQueries, privacyParameters, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {transaction.getHash()}; final Object[] params = new Object[] {transaction.getHash()};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params)); new JsonRpcRequestContext(
new JsonRpcRequest("1", "priv_getTransactionReceipt", params), user);
final JsonRpcSuccessResponse response = final JsonRpcSuccessResponse response =
(JsonRpcSuccessResponse) privGetTransactionReceipt.response(request); (JsonRpcSuccessResponse) privGetTransactionReceipt.response(request);
@ -181,15 +193,17 @@ public class PrivGetTransactionReceiptTest {
(PrivateTransactionReceiptResult) response.getResult(); (PrivateTransactionReceiptResult) response.getResult();
assertThat(result).isEqualToComparingFieldByField(expectedResult); assertThat(result).isEqualToComparingFieldByField(expectedResult);
verify(privacyController).retrieveTransaction(ENCLAVE_KEY.toBase64String(), ENCLAVE_PUBLIC_KEY);
} }
@Test @Test
public void enclavePayloadNotFoundResultsInSuccessButNullResponse() { public void enclavePayloadNotFoundResultsInSuccessButNullResponse() {
when(privacyController.retrieveTransaction(anyString())) when(privacyController.retrieveTransaction(anyString(), any()))
.thenThrow(new EnclaveClientException(404, "EnclavePayloadNotFound")); .thenThrow(new EnclaveClientException(404, "EnclavePayloadNotFound"));
final PrivGetTransactionReceipt privGetTransactionReceipt = final PrivGetTransactionReceipt privGetTransactionReceipt =
new PrivGetTransactionReceipt(blockchainQueries, privacyParameters, privacyController); new PrivGetTransactionReceipt(
blockchainQueries, privacyParameters, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {transaction.getHash()}; final Object[] params = new Object[] {transaction.getHash()};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params)); new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params));
@ -207,7 +221,8 @@ public class PrivGetTransactionReceiptTest {
when(blockchain.getTransactionLocation(nullable(Hash.class))).thenReturn(Optional.empty()); when(blockchain.getTransactionLocation(nullable(Hash.class))).thenReturn(Optional.empty());
final PrivGetTransactionReceipt privGetTransactionReceipt = final PrivGetTransactionReceipt privGetTransactionReceipt =
new PrivGetTransactionReceipt(blockchainQueries, privacyParameters, privacyController); new PrivGetTransactionReceipt(
blockchainQueries, privacyParameters, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {transaction.getHash()}; final Object[] params = new Object[] {transaction.getHash()};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params)); new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params));
@ -222,10 +237,11 @@ public class PrivGetTransactionReceiptTest {
@Test @Test
public void enclaveConnectionIssueThrowsRuntimeException() { public void enclaveConnectionIssueThrowsRuntimeException() {
when(privacyController.retrieveTransaction(anyString())) when(privacyController.retrieveTransaction(anyString(), any()))
.thenThrow(EnclaveServerException.class); .thenThrow(EnclaveServerException.class);
final PrivGetTransactionReceipt privGetTransactionReceipt = final PrivGetTransactionReceipt privGetTransactionReceipt =
new PrivGetTransactionReceipt(blockchainQueries, privacyParameters, privacyController); new PrivGetTransactionReceipt(
blockchainQueries, privacyParameters, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {transaction.getHash()}; final Object[] params = new Object[] {transaction.getHash()};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params)); new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params));
@ -240,7 +256,8 @@ public class PrivGetTransactionReceiptTest {
.thenReturn(Optional.of(Bytes.fromHexString("0x01"))); .thenReturn(Optional.of(Bytes.fromHexString("0x01")));
final PrivGetTransactionReceipt privGetTransactionReceipt = final PrivGetTransactionReceipt privGetTransactionReceipt =
new PrivGetTransactionReceipt(blockchainQueries, privacyParameters, privacyController); new PrivGetTransactionReceipt(
blockchainQueries, privacyParameters, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {transaction.getHash()}; final Object[] params = new Object[] {transaction.getHash()};
final JsonRpcRequest request = new JsonRpcRequest("1", "priv_getTransactionReceipt", params); final JsonRpcRequest request = new JsonRpcRequest("1", "priv_getTransactionReceipt", params);
@ -256,11 +273,12 @@ public class PrivGetTransactionReceiptTest {
@Test @Test
public void enclaveKeysCannotDecryptPayloadThrowsRuntimeException() { public void enclaveKeysCannotDecryptPayloadThrowsRuntimeException() {
final String keysCannotDecryptPayloadMsg = "EnclaveKeysCannotDecryptPayload"; final String keysCannotDecryptPayloadMsg = "EnclaveKeysCannotDecryptPayload";
when(privacyController.retrieveTransaction(any())) when(privacyController.retrieveTransaction(any(), any()))
.thenThrow(new EnclaveClientException(400, keysCannotDecryptPayloadMsg)); .thenThrow(new EnclaveClientException(400, keysCannotDecryptPayloadMsg));
final PrivGetTransactionReceipt privGetTransactionReceipt = final PrivGetTransactionReceipt privGetTransactionReceipt =
new PrivGetTransactionReceipt(blockchainQueries, privacyParameters, privacyController); new PrivGetTransactionReceipt(
blockchainQueries, privacyParameters, privacyController, enclavePublicKeyProvider);
final Object[] params = new Object[] {transaction.getHash()}; final Object[] params = new Object[] {transaction.getHash()};
final JsonRpcRequestContext request = final JsonRpcRequestContext request =
new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params)); new JsonRpcRequestContext(new JsonRpcRequest("1", "priv_getTransactionReceipt", params));

@ -15,6 +15,7 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.methods; package org.hyperledger.besu.ethereum.api.jsonrpc.methods;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.PRIVACY_NOT_ENABLED; import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.PRIVACY_NOT_ENABLED;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -23,6 +24,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; 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.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiTenancyRpcMethodDecorator; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.MultiTenancyRpcMethodDecorator;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
@ -34,7 +36,11 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.privacy.PrivacyController; import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.jwt.impl.JWTUser;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -43,18 +49,23 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class PrivacyApiGroupJsonRpcMethodsTest { public class PrivacyApiGroupJsonRpcMethodsTest {
private static final String DEFAULT_ENCLAVE_PUBLIC_KEY =
"A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
@Mock private JsonRpcMethod rpcMethod; @Mock private JsonRpcMethod rpcMethod;
@Mock private BlockchainQueries blockchainQueries; @Mock private BlockchainQueries blockchainQueries;
@Mock private ProtocolSchedule<?> protocolSchedule; @Mock private ProtocolSchedule<?> protocolSchedule;
@Mock private TransactionPool transactionPool; @Mock private TransactionPool transactionPool;
@Mock private PrivacyParameters privacyParameters; @Mock private PrivacyParameters privacyParameters;
private PrivacyApiGroupJsonRpcMethods privacyApiGroupJsonRpcMethods; private TestPrivacyApiGroupJsonRpcMethods privacyApiGroupJsonRpcMethods;
@Before @Before
public void setup() { public void setup() {
when(rpcMethod.getName()).thenReturn("priv_method"); when(rpcMethod.getName()).thenReturn("priv_method");
privacyApiGroupJsonRpcMethods = createPrivacyApiGroupJsonRpcMethods(); privacyApiGroupJsonRpcMethods =
new TestPrivacyApiGroupJsonRpcMethods(
blockchainQueries, protocolSchedule, transactionPool, privacyParameters, rpcMethod);
} }
@Test @Test
@ -75,6 +86,52 @@ public class PrivacyApiGroupJsonRpcMethodsTest {
assertThat(privMethod).isSameAs(rpcMethod); assertThat(privMethod).isSameAs(rpcMethod);
} }
@Test
public void rpcsCreatedWithoutMultiTenancyUseFixedEnclavePublicKey() {
when(privacyParameters.isEnabled()).thenReturn(true);
when(privacyParameters.getEnclavePublicKey()).thenReturn(DEFAULT_ENCLAVE_PUBLIC_KEY);
final User user = createUser(DEFAULT_ENCLAVE_PUBLIC_KEY);
privacyApiGroupJsonRpcMethods.create();
final EnclavePublicKeyProvider enclavePublicKeyProvider =
privacyApiGroupJsonRpcMethods.enclavePublicKeyProvider;
assertThat(enclavePublicKeyProvider.getEnclaveKey(Optional.of(user)))
.isEqualTo(DEFAULT_ENCLAVE_PUBLIC_KEY);
assertThat(enclavePublicKeyProvider.getEnclaveKey(Optional.empty()))
.isEqualTo(DEFAULT_ENCLAVE_PUBLIC_KEY);
}
@Test
public void rpcsCreatedWithMultiTenancyUseEnclavePublicKeyFromRequest() {
when(privacyParameters.isEnabled()).thenReturn(true);
when(privacyParameters.isMultiTenancyEnabled()).thenReturn(true);
final User user1 = createUser("key1");
final User user2 = createUser("key2");
privacyApiGroupJsonRpcMethods.create();
final EnclavePublicKeyProvider enclavePublicKeyProvider =
privacyApiGroupJsonRpcMethods.enclavePublicKeyProvider;
assertThat(enclavePublicKeyProvider.getEnclaveKey(Optional.of(user1))).isEqualTo("key1");
assertThat(enclavePublicKeyProvider.getEnclaveKey(Optional.of(user2))).isEqualTo("key2");
}
@Test
public void rpcsCreatedWithMultiTenancyAndWithoutUserFail() {
when(privacyParameters.isEnabled()).thenReturn(true);
when(privacyParameters.isMultiTenancyEnabled()).thenReturn(true);
privacyApiGroupJsonRpcMethods.create();
final EnclavePublicKeyProvider enclavePublicKeyProvider =
privacyApiGroupJsonRpcMethods.enclavePublicKeyProvider;
assertThatThrownBy(() -> enclavePublicKeyProvider.getEnclaveKey(Optional.empty()))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Request does not contain an authorization token");
}
@Test @Test
public void rpcMethodsCreatedWhenPrivacyIsNotEnabledAreDisabled() { public void rpcMethodsCreatedWhenPrivacyIsNotEnabledAreDisabled() {
final Map<String, JsonRpcMethod> rpcMethods = privacyApiGroupJsonRpcMethods.create(); final Map<String, JsonRpcMethod> rpcMethods = privacyApiGroupJsonRpcMethods.create();
@ -90,19 +147,36 @@ public class PrivacyApiGroupJsonRpcMethodsTest {
assertThat(errorResponse.getError()).isEqualTo(PRIVACY_NOT_ENABLED); assertThat(errorResponse.getError()).isEqualTo(PRIVACY_NOT_ENABLED);
} }
private PrivacyApiGroupJsonRpcMethods createPrivacyApiGroupJsonRpcMethods() { private User createUser(final String enclavePublicKey) {
return new PrivacyApiGroupJsonRpcMethods( return new JWTUser(new JsonObject().put("privacyPublicKey", enclavePublicKey), "");
blockchainQueries, protocolSchedule, transactionPool, privacyParameters) { }
@Override private static class TestPrivacyApiGroupJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
protected RpcApi getApiGroup() {
return RpcApis.PRIV; private final JsonRpcMethod rpcMethod;
private EnclavePublicKeyProvider enclavePublicKeyProvider;
public TestPrivacyApiGroupJsonRpcMethods(
final BlockchainQueries blockchainQueries,
final ProtocolSchedule<?> protocolSchedule,
final TransactionPool transactionPool,
final PrivacyParameters privacyParameters,
final JsonRpcMethod rpcMethod) {
super(blockchainQueries, protocolSchedule, transactionPool, privacyParameters);
this.rpcMethod = rpcMethod;
} }
@Override @Override
protected Map<String, JsonRpcMethod> create(final PrivacyController privacyController) { protected Map<String, JsonRpcMethod> create(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
return mapOf(rpcMethod); return mapOf(rpcMethod);
} }
};
@Override
protected RpcApi getApiGroup() {
return RpcApis.PRIV;
}
} }
} }

@ -46,7 +46,6 @@ public class PrivacyController {
private static final Logger LOG = LogManager.getLogger(); private static final Logger LOG = LogManager.getLogger();
private final Enclave enclave; private final Enclave enclave;
private final String enclavePublicKey;
private final PrivateStateStorage privateStateStorage; private final PrivateStateStorage privateStateStorage;
private final WorldStateArchive privateWorldStateArchive; private final WorldStateArchive privateWorldStateArchive;
private final PrivateTransactionValidator privateTransactionValidator; private final PrivateTransactionValidator privateTransactionValidator;
@ -58,7 +57,6 @@ public class PrivacyController {
final PrivateMarkerTransactionFactory privateMarkerTransactionFactory) { final PrivateMarkerTransactionFactory privateMarkerTransactionFactory) {
this( this(
privacyParameters.getEnclave(), privacyParameters.getEnclave(),
privacyParameters.getEnclavePublicKey(),
privacyParameters.getPrivateStateStorage(), privacyParameters.getPrivateStateStorage(),
privacyParameters.getPrivateWorldStateArchive(), privacyParameters.getPrivateWorldStateArchive(),
new PrivateTransactionValidator(chainId), new PrivateTransactionValidator(chainId),
@ -67,23 +65,22 @@ public class PrivacyController {
public PrivacyController( public PrivacyController(
final Enclave enclave, final Enclave enclave,
final String enclavePublicKey,
final PrivateStateStorage privateStateStorage, final PrivateStateStorage privateStateStorage,
final WorldStateArchive privateWorldStateArchive, final WorldStateArchive privateWorldStateArchive,
final PrivateTransactionValidator privateTransactionValidator, final PrivateTransactionValidator privateTransactionValidator,
final PrivateMarkerTransactionFactory privateMarkerTransactionFactory) { final PrivateMarkerTransactionFactory privateMarkerTransactionFactory) {
this.enclave = enclave; this.enclave = enclave;
this.enclavePublicKey = enclavePublicKey;
this.privateStateStorage = privateStateStorage; this.privateStateStorage = privateStateStorage;
this.privateWorldStateArchive = privateWorldStateArchive; this.privateWorldStateArchive = privateWorldStateArchive;
this.privateTransactionValidator = privateTransactionValidator; this.privateTransactionValidator = privateTransactionValidator;
this.privateMarkerTransactionFactory = privateMarkerTransactionFactory; this.privateMarkerTransactionFactory = privateMarkerTransactionFactory;
} }
public SendTransactionResponse sendTransaction(final PrivateTransaction privateTransaction) { public SendTransactionResponse sendTransaction(
final PrivateTransaction privateTransaction, final String enclavePublicKey) {
try { try {
LOG.trace("Storing private transaction in enclave"); LOG.trace("Storing private transaction in enclave");
final SendResponse sendResponse = sendRequest(privateTransaction); final SendResponse sendResponse = sendRequest(privateTransaction, enclavePublicKey);
final String enclaveKey = sendResponse.getKey(); final String enclaveKey = sendResponse.getKey();
if (privateTransaction.getPrivacyGroupId().isPresent()) { if (privateTransaction.getPrivacyGroupId().isPresent()) {
final String privacyGroupId = privateTransaction.getPrivacyGroupId().get().toBase64String(); final String privacyGroupId = privateTransaction.getPrivacyGroupId().get().toBase64String();
@ -99,20 +96,25 @@ public class PrivacyController {
} }
} }
public ReceiveResponse retrieveTransaction(final String enclaveKey) { public ReceiveResponse retrieveTransaction(
final String enclaveKey, final String enclavePublicKey) {
return enclave.receive(enclaveKey, enclavePublicKey); return enclave.receive(enclaveKey, enclavePublicKey);
} }
public PrivacyGroup createPrivacyGroup( public PrivacyGroup createPrivacyGroup(
final List<String> addresses, final String name, final String description) { final List<String> addresses,
final String name,
final String description,
final String enclavePublicKey) {
return enclave.createPrivacyGroup(addresses, enclavePublicKey, name, description); return enclave.createPrivacyGroup(addresses, enclavePublicKey, name, description);
} }
public String deletePrivacyGroup(final String privacyGroupId) { public String deletePrivacyGroup(final String privacyGroupId, final String enclavePublicKey) {
return enclave.deletePrivacyGroup(privacyGroupId, enclavePublicKey); return enclave.deletePrivacyGroup(privacyGroupId, enclavePublicKey);
} }
public PrivacyGroup[] findPrivacyGroup(final List<String> addresses) { public PrivacyGroup[] findPrivacyGroup(
final List<String> addresses, final String enclavePublicKey) {
return enclave.findPrivacyGroup(addresses); return enclave.findPrivacyGroup(addresses);
} }
@ -122,13 +124,19 @@ public class PrivacyController {
} }
public ValidationResult<TransactionValidator.TransactionInvalidReason> validatePrivateTransaction( public ValidationResult<TransactionValidator.TransactionInvalidReason> validatePrivateTransaction(
final PrivateTransaction privateTransaction, final String privacyGroupId) { final PrivateTransaction privateTransaction,
final String privacyGroupId,
final String enclavePublicKey) {
return privateTransactionValidator.validate( return privateTransactionValidator.validate(
privateTransaction, determineNonce(privateTransaction.getSender(), privacyGroupId)); privateTransaction,
determineNonce(privateTransaction.getSender(), privacyGroupId, enclavePublicKey));
} }
public long determineNonce( public long determineNonce(
final String privateFrom, final String[] privateFor, final Address address) { final String privateFrom,
final String[] privateFor,
final Address address,
final String enclavePublicKey) {
final List<String> groupMembers = Lists.asList(privateFrom, privateFor); final List<String> groupMembers = Lists.asList(privateFrom, privateFor);
final List<PrivacyGroup> matchingGroups = final List<PrivacyGroup> matchingGroups =
@ -150,10 +158,11 @@ public class PrivacyController {
final String privacyGroupId = legacyGroups.get(0).getPrivacyGroupId(); final String privacyGroupId = legacyGroups.get(0).getPrivacyGroupId();
return determineNonce(address, privacyGroupId); return determineNonce(address, privacyGroupId, enclavePublicKey);
} }
public long determineNonce(final Address sender, final String privacyGroupId) { public long determineNonce(
final Address sender, final String privacyGroupId, final String enclavePublicKey) {
return privateStateStorage return privateStateStorage
.getLatestStateRoot(Bytes.fromBase64String(privacyGroupId)) .getLatestStateRoot(Bytes.fromBase64String(privacyGroupId))
.map( .map(
@ -177,7 +186,8 @@ public class PrivacyController {
Account.DEFAULT_NONCE); Account.DEFAULT_NONCE);
} }
private SendResponse sendRequest(final PrivateTransaction privateTransaction) { private SendResponse sendRequest(
final PrivateTransaction privateTransaction, final String enclavePublicKey) {
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput(); final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
privateTransaction.writeTo(rlpOutput); privateTransaction.writeTo(rlpOutput);
final String payload = rlpOutput.encoded().toBase64String(); final String payload = rlpOutput.encoded().toBase64String();

@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoInteractions;
@ -71,10 +72,12 @@ public class PrivacyControllerTest {
new BigInteger( new BigInteger(
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16)));
private static final byte[] PAYLOAD = new byte[0]; private static final byte[] PAYLOAD = new byte[0];
private static final String PRIVACY_GROUP_ID = "pg_id";
private static final List<String> PRIVACY_GROUP_ADDRESSES = newArrayList("8f2a", "fb23"); private static final List<String> PRIVACY_GROUP_ADDRESSES = newArrayList("8f2a", "fb23");
private static final String PRIVACY_GROUP_NAME = "pg_name"; private static final String PRIVACY_GROUP_NAME = "pg_name";
private static final String PRIVACY_GROUP_DESCRIPTION = "pg_desc"; private static final String PRIVACY_GROUP_DESCRIPTION = "pg_desc";
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final String ENCLAVE_KEY2 = "Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=";
private static final String PRIVACY_GROUP_ID = "DyAOiF/ynpc+JXa2YAGB0bCitSlOMNm+ShmB/7M6C4w=";
private PrivacyController privacyController; private PrivacyController privacyController;
private PrivacyController brokenPrivacyController; private PrivacyController brokenPrivacyController;
@ -140,7 +143,6 @@ public class PrivacyControllerTest {
privacyController = privacyController =
new PrivacyController( new PrivacyController(
enclave, enclave,
enclavePublicKey,
privateStateStorage, privateStateStorage,
worldStateArchive, worldStateArchive,
privateTransactionValidator, privateTransactionValidator,
@ -149,7 +151,6 @@ public class PrivacyControllerTest {
brokenPrivacyController = brokenPrivacyController =
new PrivacyController( new PrivacyController(
brokenMockEnclave(), brokenMockEnclave(),
enclavePublicKey,
privateStateStorage, privateStateStorage,
worldStateArchive, worldStateArchive,
privateTransactionValidator, privateTransactionValidator,
@ -163,11 +164,11 @@ public class PrivacyControllerTest {
final PrivateTransaction transaction = buildLegacyPrivateTransaction(1); final PrivateTransaction transaction = buildLegacyPrivateTransaction(1);
final SendTransactionResponse sendTransactionResponse = final SendTransactionResponse sendTransactionResponse =
privacyController.sendTransaction(transaction); privacyController.sendTransaction(transaction, ENCLAVE_PUBLIC_KEY);
final ValidationResult<TransactionInvalidReason> validationResult = final ValidationResult<TransactionInvalidReason> validationResult =
privacyController.validatePrivateTransaction( privacyController.validatePrivateTransaction(
transaction, sendTransactionResponse.getPrivacyGroupId()); transaction, sendTransactionResponse.getPrivacyGroupId(), ENCLAVE_PUBLIC_KEY);
final Transaction markerTransaction = final Transaction markerTransaction =
privacyController.createPrivacyMarkerTransaction( privacyController.createPrivacyMarkerTransaction(
@ -179,6 +180,8 @@ public class PrivacyControllerTest {
assertThat(markerTransaction.getNonce()).isEqualTo(PUBLIC_TRANSACTION.getNonce()); assertThat(markerTransaction.getNonce()).isEqualTo(PUBLIC_TRANSACTION.getNonce());
assertThat(markerTransaction.getSender()).isEqualTo(PUBLIC_TRANSACTION.getSender()); assertThat(markerTransaction.getSender()).isEqualTo(PUBLIC_TRANSACTION.getSender());
assertThat(markerTransaction.getValue()).isEqualTo(PUBLIC_TRANSACTION.getValue()); assertThat(markerTransaction.getValue()).isEqualTo(PUBLIC_TRANSACTION.getValue());
verify(enclave)
.send(anyString(), eq(ENCLAVE_PUBLIC_KEY), eq(List.of(ENCLAVE_PUBLIC_KEY, ENCLAVE_KEY2)));
} }
@Test @Test
@ -187,11 +190,11 @@ public class PrivacyControllerTest {
final PrivateTransaction transaction = buildBesuPrivateTransaction(1); final PrivateTransaction transaction = buildBesuPrivateTransaction(1);
final SendTransactionResponse sendTransactionResponse = final SendTransactionResponse sendTransactionResponse =
privacyController.sendTransaction(transaction); privacyController.sendTransaction(transaction, ENCLAVE_PUBLIC_KEY);
final ValidationResult<TransactionInvalidReason> validationResult = final ValidationResult<TransactionInvalidReason> validationResult =
privacyController.validatePrivateTransaction( privacyController.validatePrivateTransaction(
transaction, transaction.getPrivacyGroupId().get().toString()); transaction, transaction.getPrivacyGroupId().get().toString(), ENCLAVE_PUBLIC_KEY);
final Transaction markerTransaction = final Transaction markerTransaction =
privacyController.createPrivacyMarkerTransaction( privacyController.createPrivacyMarkerTransaction(
@ -203,12 +206,16 @@ public class PrivacyControllerTest {
assertThat(markerTransaction.getNonce()).isEqualTo(PUBLIC_TRANSACTION.getNonce()); assertThat(markerTransaction.getNonce()).isEqualTo(PUBLIC_TRANSACTION.getNonce());
assertThat(markerTransaction.getSender()).isEqualTo(PUBLIC_TRANSACTION.getSender()); assertThat(markerTransaction.getSender()).isEqualTo(PUBLIC_TRANSACTION.getSender());
assertThat(markerTransaction.getValue()).isEqualTo(PUBLIC_TRANSACTION.getValue()); assertThat(markerTransaction.getValue()).isEqualTo(PUBLIC_TRANSACTION.getValue());
verify(enclave).send(anyString(), eq(ENCLAVE_PUBLIC_KEY), eq(PRIVACY_GROUP_ID));
} }
@Test @Test
public void sendTransactionWhenEnclaveFailsThrowsEnclaveError() { public void sendTransactionWhenEnclaveFailsThrowsEnclaveError() {
assertThatExceptionOfType(EnclaveServerException.class) assertThatExceptionOfType(EnclaveServerException.class)
.isThrownBy(() -> brokenPrivacyController.sendTransaction(buildLegacyPrivateTransaction())); .isThrownBy(
() ->
brokenPrivacyController.sendTransaction(
buildLegacyPrivateTransaction(), ENCLAVE_PUBLIC_KEY));
} }
@Test @Test
@ -218,10 +225,10 @@ public class PrivacyControllerTest {
final PrivateTransaction transaction = buildLegacyPrivateTransaction(0); final PrivateTransaction transaction = buildLegacyPrivateTransaction(0);
final SendTransactionResponse sendTransactionResponse = final SendTransactionResponse sendTransactionResponse =
privacyController.sendTransaction(transaction); privacyController.sendTransaction(transaction, ENCLAVE_PUBLIC_KEY);
final ValidationResult<TransactionInvalidReason> validationResult = final ValidationResult<TransactionInvalidReason> validationResult =
privacyController.validatePrivateTransaction( privacyController.validatePrivateTransaction(
transaction, sendTransactionResponse.getPrivacyGroupId()); transaction, sendTransactionResponse.getPrivacyGroupId(), ENCLAVE_PUBLIC_KEY);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(PRIVATE_NONCE_TOO_LOW)); assertThat(validationResult).isEqualTo(ValidationResult.invalid(PRIVATE_NONCE_TOO_LOW));
} }
@ -233,10 +240,10 @@ public class PrivacyControllerTest {
final PrivateTransaction transaction = buildLegacyPrivateTransaction(2); final PrivateTransaction transaction = buildLegacyPrivateTransaction(2);
final SendTransactionResponse sendTransactionResponse = final SendTransactionResponse sendTransactionResponse =
privacyController.sendTransaction(transaction); privacyController.sendTransaction(transaction, ENCLAVE_PUBLIC_KEY);
final ValidationResult<TransactionInvalidReason> validationResult = final ValidationResult<TransactionInvalidReason> validationResult =
privacyController.validatePrivateTransaction( privacyController.validatePrivateTransaction(
transaction, sendTransactionResponse.getPrivacyGroupId()); transaction, sendTransactionResponse.getPrivacyGroupId(), ENCLAVE_PUBLIC_KEY);
assertThat(validationResult).isEqualTo(ValidationResult.invalid(INCORRECT_PRIVATE_NONCE)); assertThat(validationResult).isEqualTo(ValidationResult.invalid(INCORRECT_PRIVATE_NONCE));
} }
@ -245,7 +252,8 @@ public class PrivacyControllerTest {
when(enclave.receive(anyString(), anyString())) when(enclave.receive(anyString(), anyString()))
.thenReturn(new ReceiveResponse(PAYLOAD, PRIVACY_GROUP_ID)); .thenReturn(new ReceiveResponse(PAYLOAD, PRIVACY_GROUP_ID));
final ReceiveResponse receiveResponse = privacyController.retrieveTransaction(TRANSACTION_KEY); final ReceiveResponse receiveResponse =
privacyController.retrieveTransaction(TRANSACTION_KEY, ENCLAVE_PUBLIC_KEY);
assertThat(receiveResponse.getPayload()).isEqualTo(PAYLOAD); assertThat(receiveResponse.getPayload()).isEqualTo(PAYLOAD);
assertThat(receiveResponse.getPrivacyGroupId()).isEqualTo(PRIVACY_GROUP_ID); assertThat(receiveResponse.getPrivacyGroupId()).isEqualTo(PRIVACY_GROUP_ID);
@ -266,7 +274,10 @@ public class PrivacyControllerTest {
final PrivacyGroup privacyGroup = final PrivacyGroup privacyGroup =
privacyController.createPrivacyGroup( privacyController.createPrivacyGroup(
PRIVACY_GROUP_ADDRESSES, PRIVACY_GROUP_NAME, PRIVACY_GROUP_DESCRIPTION); PRIVACY_GROUP_ADDRESSES,
PRIVACY_GROUP_NAME,
PRIVACY_GROUP_DESCRIPTION,
ENCLAVE_PUBLIC_KEY);
assertThat(privacyGroup).isEqualToComparingFieldByField(enclavePrivacyGroupResponse); assertThat(privacyGroup).isEqualToComparingFieldByField(enclavePrivacyGroupResponse);
verify(enclave) verify(enclave)
@ -281,7 +292,8 @@ public class PrivacyControllerTest {
public void deletesPrivacyGroup() { public void deletesPrivacyGroup() {
when(enclave.deletePrivacyGroup(anyString(), anyString())).thenReturn(PRIVACY_GROUP_ID); when(enclave.deletePrivacyGroup(anyString(), anyString())).thenReturn(PRIVACY_GROUP_ID);
final String deletedPrivacyGroupId = privacyController.deletePrivacyGroup(PRIVACY_GROUP_ID); final String deletedPrivacyGroupId =
privacyController.deletePrivacyGroup(PRIVACY_GROUP_ID, ENCLAVE_PUBLIC_KEY);
assertThat(deletedPrivacyGroupId).isEqualTo(PRIVACY_GROUP_ID); assertThat(deletedPrivacyGroupId).isEqualTo(PRIVACY_GROUP_ID);
verify(enclave).deletePrivacyGroup(PRIVACY_GROUP_ID, enclavePublicKey); verify(enclave).deletePrivacyGroup(PRIVACY_GROUP_ID, enclavePublicKey);
@ -299,7 +311,7 @@ public class PrivacyControllerTest {
when(enclave.findPrivacyGroup(any())).thenReturn(new PrivacyGroup[] {privacyGroup}); when(enclave.findPrivacyGroup(any())).thenReturn(new PrivacyGroup[] {privacyGroup});
final PrivacyGroup[] privacyGroups = final PrivacyGroup[] privacyGroups =
privacyController.findPrivacyGroup(PRIVACY_GROUP_ADDRESSES); privacyController.findPrivacyGroup(PRIVACY_GROUP_ADDRESSES, ENCLAVE_PUBLIC_KEY);
assertThat(privacyGroups).hasSize(1); assertThat(privacyGroups).hasSize(1);
assertThat(privacyGroups[0]).isEqualToComparingFieldByField(privacyGroup); assertThat(privacyGroups[0]).isEqualToComparingFieldByField(privacyGroup);
verify(enclave).findPrivacyGroup(PRIVACY_GROUP_ADDRESSES); verify(enclave).findPrivacyGroup(PRIVACY_GROUP_ADDRESSES);
@ -318,7 +330,8 @@ public class PrivacyControllerTest {
when(account.getNonce()).thenReturn(8L); when(account.getNonce()).thenReturn(8L);
final long nonce = final long nonce =
privacyController.determineNonce("privateFrom", new String[] {"first", "second"}, address); privacyController.determineNonce(
"privateFrom", new String[] {"first", "second"}, address, ENCLAVE_PUBLIC_KEY);
assertThat(nonce).isEqualTo(reportedNonce); assertThat(nonce).isEqualTo(reportedNonce);
verify(enclave) verify(enclave)
@ -335,7 +348,8 @@ public class PrivacyControllerTest {
when(enclave.findPrivacyGroup(any())).thenReturn(returnedGroups); when(enclave.findPrivacyGroup(any())).thenReturn(returnedGroups);
final long nonce = final long nonce =
privacyController.determineNonce("privateFrom", new String[] {"first", "second"}, address); privacyController.determineNonce(
"privateFrom", new String[] {"first", "second"}, address, ENCLAVE_PUBLIC_KEY);
assertThat(nonce).isEqualTo(reportedNonce); assertThat(nonce).isEqualTo(reportedNonce);
verify(enclave) verify(enclave)
@ -358,7 +372,7 @@ public class PrivacyControllerTest {
.isThrownBy( .isThrownBy(
() -> () ->
privacyController.determineNonce( privacyController.determineNonce(
"privateFrom", new String[] {"first", "second"}, address)); "privateFrom", new String[] {"first", "second"}, address, ENCLAVE_PUBLIC_KEY));
} }
@Test @Test
@ -367,7 +381,7 @@ public class PrivacyControllerTest {
when(account.getNonce()).thenReturn(4L); when(account.getNonce()).thenReturn(4L);
final long nonce = privacyController.determineNonce(address, "Group1"); final long nonce = privacyController.determineNonce(address, "Group1", ENCLAVE_PUBLIC_KEY);
assertThat(nonce).isEqualTo(4L); assertThat(nonce).isEqualTo(4L);
verify(privateStateStorage).getLatestStateRoot(Base64.decode("Group1")); verify(privateStateStorage).getLatestStateRoot(Base64.decode("Group1"));
@ -382,7 +396,7 @@ public class PrivacyControllerTest {
when(privateStateStorage.getLatestStateRoot(Base64.decode("Group1"))) when(privateStateStorage.getLatestStateRoot(Base64.decode("Group1")))
.thenReturn(Optional.empty()); .thenReturn(Optional.empty());
final long nonce = privacyController.determineNonce(address, "Group1"); final long nonce = privacyController.determineNonce(address, "Group1", ENCLAVE_PUBLIC_KEY);
assertThat(nonce).isEqualTo(Account.DEFAULT_NONCE); assertThat(nonce).isEqualTo(Account.DEFAULT_NONCE);
verifyNoInteractions(worldStateArchive, mutableWorldState, account); verifyNoInteractions(worldStateArchive, mutableWorldState, account);
@ -396,7 +410,7 @@ public class PrivacyControllerTest {
.thenReturn(Optional.of(hash)); .thenReturn(Optional.of(hash));
when(worldStateArchive.getMutable(hash)).thenReturn(Optional.empty()); when(worldStateArchive.getMutable(hash)).thenReturn(Optional.empty());
final long nonce = privacyController.determineNonce(address, "Group1"); final long nonce = privacyController.determineNonce(address, "Group1", ENCLAVE_PUBLIC_KEY);
assertThat(nonce).isEqualTo(Account.DEFAULT_NONCE); assertThat(nonce).isEqualTo(Account.DEFAULT_NONCE);
verifyNoInteractions(mutableWorldState, account); verifyNoInteractions(mutableWorldState, account);
@ -411,7 +425,7 @@ public class PrivacyControllerTest {
when(worldStateArchive.getMutable(hash)).thenReturn(Optional.of(mutableWorldState)); when(worldStateArchive.getMutable(hash)).thenReturn(Optional.of(mutableWorldState));
when(mutableWorldState.get(address)).thenReturn(null); when(mutableWorldState.get(address)).thenReturn(null);
final long nonce = privacyController.determineNonce(address, "Group1"); final long nonce = privacyController.determineNonce(address, "Group1", ENCLAVE_PUBLIC_KEY);
assertThat(nonce).isEqualTo(Account.DEFAULT_NONCE); assertThat(nonce).isEqualTo(Account.DEFAULT_NONCE);
verifyNoInteractions(account); verifyNoInteractions(account);
@ -423,19 +437,16 @@ public class PrivacyControllerTest {
private static PrivateTransaction buildLegacyPrivateTransaction(final long nonce) { private static PrivateTransaction buildLegacyPrivateTransaction(final long nonce) {
return buildPrivateTransaction(nonce) return buildPrivateTransaction(nonce)
.privateFrom(Base64.decode("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=")) .privateFrom(Base64.decode(ENCLAVE_PUBLIC_KEY))
.privateFor( .privateFor(newArrayList(Base64.decode(ENCLAVE_PUBLIC_KEY), Base64.decode(ENCLAVE_KEY2)))
newArrayList(
Base64.decode("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo="),
Base64.decode("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=")))
.signAndBuild(KEY_PAIR); .signAndBuild(KEY_PAIR);
} }
private static PrivateTransaction buildBesuPrivateTransaction(final long nonce) { private static PrivateTransaction buildBesuPrivateTransaction(final long nonce) {
return buildPrivateTransaction(nonce) return buildPrivateTransaction(nonce)
.privateFrom(Base64.decode("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=")) .privateFrom(Base64.decode(ENCLAVE_PUBLIC_KEY))
.privacyGroupId(Base64.decode("DyAOiF/ynpc+JXa2YAGB0bCitSlOMNm+ShmB/7M6C4w=")) .privacyGroupId(Base64.decode(PRIVACY_GROUP_ID))
.signAndBuild(KEY_PAIR); .signAndBuild(KEY_PAIR);
} }

Loading…
Cancel
Save