Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PAN-2752] Add eea_findPrivacyGroup endpoint to pantheon #1635

Merged
merged 3 commits into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
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;
Expand All @@ -33,8 +35,8 @@
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;
Expand All @@ -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 =
Expand All @@ -59,8 +61,8 @@ public static void setUpOnce() throws Exception {
enclave = new Enclave(testHarness.clientUrl());
}

@AfterClass
public static void tearDownOnce() {
@After
public void tearDownOnce() {
testHarness.getOrion().stop();
}

Expand Down Expand Up @@ -126,6 +128,44 @@ public void testCreateAndDeletePrivacyGroup() throws Exception {
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
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;
Expand Down Expand Up @@ -75,6 +77,12 @@ public String deletePrivacyGroup(final DeletePrivacyGroupRequest content) throws
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 =
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,23 @@

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:
return JsonRpcError.ENCLAVE_ERROR;
if (err.size() == 1) {
return err.get(0);
} else {
return JsonRpcError.ENCLAVE_ERROR;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
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;
Expand Down Expand Up @@ -333,6 +334,7 @@ blockchainQueries, new TransactionTracer(blockReplay), parameter),
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"),

Expand All @@ -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;
Expand Down