Add eea_findPrivacyGroup endpoint in Pantheon (#1635)

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Puneetha Karamsetty 5 years ago committed by Lucas Saldanha
parent 2c64a9ceba
commit af1ca586c1
  1. 52
      enclave/src/integration-test/java/tech/pegasys/pantheon/enclave/EnclaveTest.java
  2. 8
      enclave/src/main/java/tech/pegasys/pantheon/enclave/Enclave.java
  3. 31
      enclave/src/main/java/tech/pegasys/pantheon/enclave/types/FindPrivacyGroupRequest.java
  4. 60
      enclave/src/main/java/tech/pegasys/pantheon/enclave/types/FindPrivacyGroupResponse.java
  5. 43
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/JsonRpcEnclaveErrorConverter.java
  6. 2
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/JsonRpcMethodsFactory.java
  7. 1
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/RpcMethod.java
  8. 67
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/privacy/EeaFindPrivacyGroup.java
  9. 11
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/response/JsonRpcError.java

@ -21,6 +21,8 @@ import tech.pegasys.orion.testutil.OrionTestHarness;
import tech.pegasys.orion.testutil.OrionTestHarnessFactory;
import tech.pegasys.pantheon.enclave.types.CreatePrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.DeletePrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.FindPrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.FindPrivacyGroupResponse;
import tech.pegasys.pantheon.enclave.types.PrivacyGroup;
import tech.pegasys.pantheon.enclave.types.ReceiveRequest;
import tech.pegasys.pantheon.enclave.types.ReceiveResponse;
@ -33,8 +35,8 @@ import java.net.URI;
import java.util.List;
import com.google.common.collect.Lists;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@ -48,8 +50,8 @@ public class EnclaveTest {
private static OrionTestHarness testHarness;
@BeforeClass
public static void setUpOnce() throws Exception {
@Before
public void setUpOnce() throws Exception {
folder.create();
testHarness =
@ -59,8 +61,8 @@ public class EnclaveTest {
enclave = new Enclave(testHarness.clientUrl());
}
@AfterClass
public static void tearDownOnce() {
@After
public void tearDownOnce() {
testHarness.getOrion().stop();
}
@ -126,6 +128,44 @@ public class EnclaveTest {
assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response);
}
@Test
public void testCreateFindDeleteFindPrivacyGroup() throws Exception {
List<String> publicKeys = testHarness.getPublicKeys();
String name = "name";
String description = "desc";
CreatePrivacyGroupRequest privacyGroupRequest =
new CreatePrivacyGroupRequest(
publicKeys.toArray(new String[0]), publicKeys.get(0), name, description);
PrivacyGroup privacyGroupResponse = enclave.createPrivacyGroup(privacyGroupRequest);
assertThat(privacyGroupResponse.getPrivacyGroupId()).isNotNull();
assertThat(privacyGroupResponse.getName()).isEqualTo(name);
assertThat(privacyGroupResponse.getDescription()).isEqualTo(description);
assertThat(privacyGroupResponse.getType()).isEqualTo(PrivacyGroup.Type.PANTHEON);
FindPrivacyGroupRequest findPrivacyGroupRequest =
new FindPrivacyGroupRequest(publicKeys.toArray(new String[0]));
FindPrivacyGroupResponse[] findPrivacyGroupResponse =
enclave.findPrivacyGroup(findPrivacyGroupRequest);
assertThat(findPrivacyGroupResponse.length).isEqualTo(1);
assertThat(findPrivacyGroupResponse[0].privacyGroupId())
.isEqualTo(privacyGroupResponse.getPrivacyGroupId());
DeletePrivacyGroupRequest deletePrivacyGroupRequest =
new DeletePrivacyGroupRequest(privacyGroupResponse.getPrivacyGroupId(), publicKeys.get(0));
String response = enclave.deletePrivacyGroup(deletePrivacyGroupRequest);
assertThat(privacyGroupResponse.getPrivacyGroupId()).isEqualTo(response);
findPrivacyGroupRequest = new FindPrivacyGroupRequest(publicKeys.toArray(new String[0]));
findPrivacyGroupResponse = enclave.findPrivacyGroup(findPrivacyGroupRequest);
assertThat(findPrivacyGroupResponse.length).isEqualTo(0);
}
@Test
public void whenUpCheckFailsThrows() {
final Throwable thrown = catchThrowable(() -> new Enclave(URI.create("http://null")).upCheck());

@ -15,6 +15,8 @@ package tech.pegasys.pantheon.enclave;
import tech.pegasys.pantheon.enclave.types.CreatePrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.DeletePrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.ErrorResponse;
import tech.pegasys.pantheon.enclave.types.FindPrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.FindPrivacyGroupResponse;
import tech.pegasys.pantheon.enclave.types.PrivacyGroup;
import tech.pegasys.pantheon.enclave.types.ReceiveRequest;
import tech.pegasys.pantheon.enclave.types.ReceiveResponse;
@ -75,6 +77,12 @@ public class Enclave {
return executePost(buildPostRequest(JSON, content, "/deletePrivacyGroup"), String.class);
}
public FindPrivacyGroupResponse[] findPrivacyGroup(final FindPrivacyGroupRequest content)
throws Exception {
Request request = buildPostRequest(JSON, content, "/findPrivacyGroup");
return executePost(request, FindPrivacyGroupResponse[].class);
}
private Request buildPostRequest(
final MediaType mediaType, final Object content, final String endpoint) throws Exception {
final RequestBody body =

@ -0,0 +1,31 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.enclave.types;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class FindPrivacyGroupRequest {
private final String[] addresses;
@JsonCreator
public FindPrivacyGroupRequest(@JsonProperty("addresses") final String[] addresses) {
this.addresses = addresses;
}
@JsonProperty("addresses")
public String[] addresses() {
return addresses;
}
}

@ -0,0 +1,60 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.enclave.types;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class FindPrivacyGroupResponse implements Serializable {
private String privacyGroupId;
private String name;
private String description;
private String[] members;
@JsonCreator
public FindPrivacyGroupResponse(
@JsonProperty("privacyGroupId") final String privacyGroupId,
@JsonProperty("name") final String name,
@JsonProperty("description") final String description,
@JsonProperty("members") final String[] members) {
this.privacyGroupId = privacyGroupId;
this.name = name;
this.description = description;
this.members = members;
}
@JsonProperty("privacyGroupId")
public String privacyGroupId() {
return privacyGroupId;
}
@JsonProperty("name")
public String name() {
return name;
}
@JsonProperty("description")
public String description() {
return description;
}
@JsonProperty("members")
public String[] members() {
return members;
}
public FindPrivacyGroupResponse() {}
}

@ -14,43 +14,22 @@ package tech.pegasys.pantheon.ethereum.jsonrpc;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcError;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class JsonRpcEnclaveErrorConverter {
public static JsonRpcError convertEnclaveInvalidReason(final String reason) {
switch (reason) {
case "NodeMissingPeerUrl":
return JsonRpcError.NODE_MISSING_PEER_URL;
case "NodePushingToPeer":
return JsonRpcError.NODE_PUSHING_TO_PEER;
case "NodePropagatingToAllPeers":
return JsonRpcError.NODE_PROPAGATING_TO_ALL_PEERS;
case "NoSenderKey":
return JsonRpcError.NO_SENDER_KEY;
case "InvalidPayload":
return JsonRpcError.INVALID_PAYLOAD;
case "EnclaveCreateKeyPair":
return JsonRpcError.ENCLAVE_CREATE_KEY_PAIR;
case "EnclaveDecodePublicKey":
return JsonRpcError.ENCLAVE_DECODE_PUBLIC_KEY;
case "EnclaveDecryptWrongPrivateKey":
return JsonRpcError.ENCLAVE_DECRYPT_WRONG_PRIVATE_KEY;
case "EnclaveEncryptCombineKeys":
return JsonRpcError.ENCLAVE_ENCRYPT_COMBINE_KEYS;
case "EnclaveMissingPrivateKeyPasswords":
return JsonRpcError.ENCLAVE_MISSING_PRIVATE_KEY_PASSWORD;
case "EnclaveNoMatchingPrivateKey":
return JsonRpcError.ENCLAVE_NO_MATCHING_PRIVATE_KEY;
case "EnclaveNotPayloadOwner":
return JsonRpcError.ENCLAVE_NOT_PAYLOAD_OWNER;
case "EnclaveUnsupportedPrivateKeyType":
return JsonRpcError.ENCLAVE_UNSUPPORTED_PRIVATE_KEY_TYPE;
case "EnclaveStorageDecrypt":
return JsonRpcError.ENCLAVE_STORAGE_DECRYPT;
case "EnclavePrivacyGroupIdCreation":
return JsonRpcError.ENCLAVE_PRIVACY_GROUP_CREATION;
List<JsonRpcError> err =
Arrays.stream(JsonRpcError.values())
.filter(e -> e.getMessage().contains(reason))
.collect(Collectors.toList());
default:
if (err.size() == 1) {
return err.get(0);
} else {
return JsonRpcError.ENCLAVE_ERROR;
}
}

@ -92,6 +92,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.permissioning.Per
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.permissioning.PermRemoveNodesFromWhitelist;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.EeaCreatePrivacyGroup;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.EeaDeletePrivacyGroup;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.EeaFindPrivacyGroup;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.EeaGetPrivacyPrecompileAddress;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.EeaGetPrivateTransaction;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy.EeaGetTransactionCount;
@ -333,6 +334,7 @@ public class JsonRpcMethodsFactory {
new EeaGetPrivateTransaction(enclave, parameter, privacyParameters),
new EeaCreatePrivacyGroup(new Enclave(privacyParameters.getEnclaveUri()), parameter),
new EeaDeletePrivacyGroup(new Enclave(privacyParameters.getEnclaveUri()), parameter),
new EeaFindPrivacyGroup(new Enclave(privacyParameters.getEnclaveUri()), parameter),
new EeaGetPrivacyPrecompileAddress(privacyParameters));
}
return enabledMethods;

@ -38,6 +38,7 @@ public enum RpcMethod {
EEA_GET_TRANSACTION_RECEIPT("eea_getTransactionReceipt"),
EEA_CREATE_PRIVACY_GROUP("eea_createPrivacyGroup"),
EEA_DELETE_PRIVACY_GROUP("eea_deletePrivacyGroup"),
EEA_FIND_PRIVACY_GROUP("eea_findPrivacyGroup"),
EEA_SEND_RAW_TRANSACTION("eea_sendRawTransaction"),
ETH_ACCOUNTS("eth_accounts"),
ETH_BLOCK_NUMBER("eth_blockNumber"),

@ -0,0 +1,67 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.privacy;
import static org.apache.logging.log4j.LogManager.getLogger;
import tech.pegasys.pantheon.enclave.Enclave;
import tech.pegasys.pantheon.enclave.types.FindPrivacyGroupRequest;
import tech.pegasys.pantheon.enclave.types.FindPrivacyGroupResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.RpcMethod;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.JsonRpcRequest;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.JsonRpcMethod;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.parameters.JsonRpcParameter;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcError;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import java.util.Arrays;
import org.apache.logging.log4j.Logger;
public class EeaFindPrivacyGroup implements JsonRpcMethod {
private static final Logger LOG = getLogger();
private final Enclave enclave;
private final JsonRpcParameter parameters;
public EeaFindPrivacyGroup(final Enclave enclave, final JsonRpcParameter parameters) {
this.enclave = enclave;
this.parameters = parameters;
}
@Override
public String getName() {
return RpcMethod.EEA_FIND_PRIVACY_GROUP.getMethodName();
}
@Override
public JsonRpcResponse response(final JsonRpcRequest request) {
LOG.trace("Executing {}", RpcMethod.EEA_FIND_PRIVACY_GROUP.getMethodName());
final String[] addresses = parameters.required(request.getParams(), 0, String[].class);
LOG.trace("Finding a privacy group with members {}", Arrays.toString(addresses));
FindPrivacyGroupRequest findPrivacyGroupRequest = new FindPrivacyGroupRequest(addresses);
FindPrivacyGroupResponse[] response;
try {
response = enclave.findPrivacyGroup(findPrivacyGroupRequest);
} catch (Exception e) {
LOG.error("Failed to fetch group from Enclave with error " + e.getMessage());
LOG.error(e);
return new JsonRpcSuccessResponse(request.getId(), JsonRpcError.FIND_PRIVACY_GROUP_ERROR);
}
return new JsonRpcSuccessResponse(request.getId(), response);
}
}

@ -105,6 +105,7 @@ public enum JsonRpcError {
PRIVACY_NOT_ENABLED(-50100, "Privacy is not enabled to get the precompiled address"),
CREATE_PRIVACY_GROUP_ERROR(-50100, "Error creating privacy group"),
DELETE_PRIVACY_GROUP_ERROR(-50100, "Error deleting privacy group"),
FIND_PRIVACY_GROUP_ERROR(-50100, "Error finding privacy group"),
VALUE_NOT_ZERO(-50100, "We cannot transfer ether in private transaction yet."),
DECODE_ERROR(-50100, "Unable to decode the private signed raw transaction"),
@ -131,7 +132,15 @@ public enum JsonRpcError {
ENCLAVE_UNSUPPORTED_PRIVATE_KEY_TYPE(-50200, "EnclaveUnsupportedPrivateKeyType"),
ENCLAVE_STORAGE_DECRYPT(-50200, "EnclaveStorageDecrypt"),
ENCLAVE_PRIVACY_GROUP_CREATION(-50200, "EnclavePrivacyGroupIdCreation"),
CREATE_GROUP_INCLUDE_SELF(-50200, "CreatePrivacyGroupShouldIncludeSelf");
CREATE_GROUP_INCLUDE_SELF(-50200, "CreatePrivacyGroupShouldIncludeSelf"),
/** Storing privacy group issue */
ENCLAVE_UNABLE_STORE_PRIVACY_GROUP(-50200, "PrivacyGroupNotStored"),
ENCLAVE_UNABLE_DELETE_PRIVACY_GROUP(-50200, "PrivacyGroupNotDeleted"),
ENCLAVE_UNABLE_PUSH_DELETE_PRIVACY_GROUP(-50200, "PrivacyGroupNotPushed"),
ENCLAVE_PRIVACY_GROUP_MISSING(-50200, "PrivacyGroupNotFound"),
ENCLAVE_PRIVACY_QUERY_ERROR(-50200, "PrivacyGroupQueryError"),
METHOD_UNIMPLEMENTED(-50200, "MethodUnimplemented");
private final int code;
private final String message;

Loading…
Cancel
Save