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

[PAN-2852] privacy group id consistent #1667

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import tech.pegasys.pantheon.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaGetTransactionCountTransaction;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.io.IOException;
import java.util.Arrays;
Expand Down Expand Up @@ -113,7 +114,7 @@ public void testOrionConnection(final PrivacyNode... otherNodes) {
public long nextNonce(final BytesValue privacyGroupId) {
return execute(
new EeaGetTransactionCountTransaction(
getAddress().toString(), privacyGroupId.toString()))
getAddress().toString(), BytesValues.asBase64String(privacyGroupId)))
.longValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*/
package tech.pegasys.pantheon.tests.web3j.privacy;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static tech.pegasys.pantheon.tests.web3j.privacy.PrivacyGroup.generatePrivacyGroup;
Expand All @@ -23,6 +22,7 @@
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.PrivateTransactionBuilder;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.PrivateTransactionBuilder.TransactionType;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.util.Base64;

Expand All @@ -32,7 +32,7 @@
import org.junit.Before;
import org.junit.Test;

public class PrivateTxEnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this file get renamed? It's unclear from the Github commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the file was renamed. It should be PrivateTransactionEnclaveErrorAcceptanceTest but that is a mouthful so I have gone with EnclaveErrorAcceptanceTest which describes the test well

protected static final String CONTRACT_NAME = "Event Emitter";

private EventEmitterHarness eventEmitterHarness;
Expand All @@ -54,7 +54,8 @@ public void setUp() throws Exception {
privateTransactionVerifier,
eea);
wrongPublicKey =
BytesValue.wrap(Base64.getEncoder().encode(Box.KeyPair.random().publicKey().bytesArray()));
BytesValues.fromBase64(
Base64.getEncoder().encode(Box.KeyPair.random().publicKey().bytesArray()));
}

@Test
Expand Down Expand Up @@ -91,8 +92,7 @@ public void enclaveNoPeerUrlError() {
.nonce(privacyNet.getNode("Alice").nextNonce(privacyGroup))
.from(privacyNet.getNode("Alice").getAddress())
.privateFrom(
BytesValue.wrap(
privacyNet.getEnclave("Alice").getPublicKeys().get(0).getBytes(UTF_8)))
BytesValues.fromBase64(privacyNet.getEnclave("Alice").getPublicKeys().get(0)))
.privateFor(Lists.newArrayList(wrongPublicKey))
.keyPair(privacyNet.getNode("Alice").keyPair())
.build(TransactionType.CREATE_CONTRACT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*/
package tech.pegasys.pantheon.tests.web3j.privacy;

import static java.nio.charset.StandardCharsets.UTF_8;
import static tech.pegasys.pantheon.tests.acceptance.dsl.WaitUtils.waitFor;
import static tech.pegasys.pantheon.tests.web3j.privacy.PrivacyGroup.generatePrivacyGroup;

Expand All @@ -24,6 +23,7 @@
import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivateTransactions;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.PrivateTransactionBuilder;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -118,8 +118,7 @@ public void store(
.from(privacyNet.getNode(sender).getAddress())
.to(Address.fromHexString(contractAddress))
.privateFrom(
BytesValue.wrap(
privacyNet.getEnclave(sender).getPublicKeys().get(0).getBytes(UTF_8)))
BytesValues.fromBase64(privacyNet.getEnclave(sender).getPublicKeys().get(0)))
.privateFor(convertNamesToOrionPublicKeys(receivers))
.keyPair(privacyNet.getNode(sender).keyPair())
.build(PrivateTransactionBuilder.TransactionType.STORE);
Expand Down Expand Up @@ -159,8 +158,7 @@ public void get(
.from(privacyNet.getNode(sender).getAddress())
.to(Address.fromHexString(contractAddress))
.privateFrom(
BytesValue.wrap(
privacyNet.getEnclave(sender).getPublicKeys().get(0).getBytes(UTF_8)))
BytesValues.fromBase64(privacyNet.getEnclave(sender).getPublicKeys().get(0)))
.privateFor(convertNamesToOrionPublicKeys(receivers))
.keyPair(privacyNet.getNode(sender).keyPair())
.build(PrivateTransactionBuilder.TransactionType.GET);
Expand Down Expand Up @@ -190,8 +188,7 @@ private void deploy(
.from(privacyNet.getNode(sender).getAddress())
.to(null)
.privateFrom(
BytesValue.wrap(
privacyNet.getEnclave(sender).getPublicKeys().get(0).getBytes(UTF_8)))
BytesValues.fromBase64(privacyNet.getEnclave(sender).getPublicKeys().get(0)))
.privateFor(convertNamesToOrionPublicKeys(receivers))
.keyPair(privacyNet.getNode(sender).keyPair())
.build(PrivateTransactionBuilder.TransactionType.CREATE_CONTRACT);
Expand Down Expand Up @@ -229,9 +226,7 @@ private void waitForTransactionToBeMined(final String transactionHash) {

private List<BytesValue> convertNamesToOrionPublicKeys(final String... toNodeNames) {
return Arrays.stream(toNodeNames)
.map(
name ->
BytesValue.wrap(privacyNet.getEnclave(name).getPublicKeys().get(0).getBytes(UTF_8)))
.map(name -> BytesValues.fromBase64(privacyNet.getEnclave(name).getPublicKeys().get(0)))
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivacyNet;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -27,7 +28,6 @@
import org.web3j.rlp.RlpList;
import org.web3j.rlp.RlpString;
import org.web3j.rlp.RlpType;
import org.web3j.utils.Numeric;

public class PrivacyGroup {
public static BytesValue generatePrivacyGroup(
Expand All @@ -47,8 +47,7 @@ public static BytesValue generatePrivacyGroup(
.sorted(Comparator.comparing(Arrays::hashCode))
.map(RlpString::create)
.collect(Collectors.toList());
return BytesValue.fromHexString(
Numeric.toHexString(
Base64.getEncoder().encode(Hash.sha3(RlpEncoder.encode(new RlpList(rlpList))))));
return BytesValues.fromBase64(
Base64.getEncoder().encode(Hash.sha3(RlpEncoder.encode(new RlpList(rlpList)))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive;
import tech.pegasys.pantheon.util.bytes.Bytes32;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.util.Base64;

import com.google.common.base.Charsets;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -107,15 +105,14 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram
}

final BytesValueRLPInput bytesValueRLPInput =
new BytesValueRLPInput(
BytesValue.wrap(Base64.getDecoder().decode(receiveResponse.getPayload())), false);
new BytesValueRLPInput(BytesValues.fromBase64(receiveResponse.getPayload()), false);

final PrivateTransaction privateTransaction = PrivateTransaction.readFrom(bytesValueRLPInput);

final WorldUpdater publicWorldState = messageFrame.getWorldState();

final BytesValue privacyGroupId =
BytesValue.wrap(receiveResponse.getPrivacyGroupId().getBytes(Charsets.UTF_8));
final BytesValue privacyGroupId = BytesValues.fromBase64(receiveResponse.getPrivacyGroupId());

// get the last world state root hash - or create a new one
final Hash lastRootHash =
privateStateStorage.getPrivateAccountState(privacyGroupId).orElse(EMPTY_ROOT_HASH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -98,18 +97,18 @@ public String sendToOrion(final PrivateTransaction privateTransaction) throws Ex
public String getPrivacyGroup(final String key, final PrivateTransaction privateTransaction)
throws Exception {
if (privateTransaction.getPrivacyGroupId().isPresent()) {
return privateTransaction.getPrivacyGroupId().get().toString();
return BytesValues.asBase64String(privateTransaction.getPrivacyGroupId().get());
}
final ReceiveRequest receiveRequest =
new ReceiveRequest(key, BytesValues.asString(privateTransaction.getPrivateFrom().get()));
new ReceiveRequest(
key, BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()));
LOG.debug(
"Getting privacy group for {}",
BytesValues.asString(privateTransaction.getPrivateFrom().get()));
BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()));
final ReceiveResponse receiveResponse;
try {
receiveResponse = enclave.receive(receiveRequest);
return BytesValue.wrap(receiveResponse.getPrivacyGroupId().getBytes(Charsets.UTF_8))
.toString();
return receiveResponse.getPrivacyGroupId();
} catch (Exception e) {
LOG.error("Failed to retrieve private transaction in enclave", e);
throw e;
Expand Down Expand Up @@ -159,33 +158,34 @@ public ValidationResult<TransactionInvalidReason> validatePrivateTransaction(
private SendRequest createSendRequest(final PrivateTransaction privateTransaction) {
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
privateTransaction.writeTo(bvrlp);
final String payload = BytesValues.asBase64String(bvrlp.encoded());

if (privateTransaction.getPrivacyGroupId().isPresent()) {
return new SendRequestPantheon(
Base64.getEncoder().encodeToString(bvrlp.encoded().extractArray()),
payload,
enclavePublicKey,
BytesValues.asString(privateTransaction.getPrivacyGroupId().get()));
BytesValues.asBase64String(privateTransaction.getPrivacyGroupId().get()));
} else {
final List<String> privateFor =
privateTransaction.getPrivateFor().get().stream()
.map(BytesValues::asString)
.map(BytesValues::asBase64String)
.collect(Collectors.toList());

// FIXME: orion should accept empty privateFor
if (privateFor.isEmpty()) {
privateFor.add(BytesValues.asString(privateTransaction.getPrivateFrom().get()));
privateFor.add(BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()));
}

return new SendRequestLegacy(
Base64.getEncoder().encodeToString(bvrlp.encoded().extractArray()),
BytesValues.asString(privateTransaction.getPrivateFrom().get()),
payload,
BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()),
privateFor);
}
}

public long getSenderNonce(final Address sender, final String privacyGroupId) {
return privateStateStorage
.getPrivateAccountState(BytesValue.fromHexString(privacyGroupId))
.getPrivateAccountState(BytesValues.fromBase64(privacyGroupId))
.map(
lastRootHash ->
privateWorldStateArchive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransaction;
import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPInput;
import tech.pegasys.pantheon.util.bytes.BytesValue;

import java.util.Base64;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -56,16 +54,15 @@ public String getName() {

@Override
public JsonRpcResponse response(final JsonRpcRequest request) {
LOG.trace("Executing {}", RpcMethod.EEA_GET_TRANSACTION_RECEIPT.getMethodName());
LOG.trace("Executing {}", RpcMethod.EEA_GET_PRIVATE_TRANSACTION.getMethodName());
final String enclaveKey = parameters.required(request.getParams(), 0, String.class);
try {
ReceiveResponse receiveResponse =
getReceiveResponseFromEnclave(enclaveKey, privacyParameters.getEnclavePublicKey());
LOG.trace("Received transaction information from Enclave");

final BytesValueRLPInput bytesValueRLPInput =
new BytesValueRLPInput(
BytesValue.wrap(Base64.getDecoder().decode(receiveResponse.getPayload())), false);
new BytesValueRLPInput(BytesValues.fromBase64(receiveResponse.getPayload()), false);

final PrivateTransaction privateTransaction = PrivateTransaction.readFrom(bytesValueRLPInput);
return new JsonRpcSuccessResponse(request.getId(), privateTransaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@
import tech.pegasys.pantheon.ethereum.rlp.RLP;
import tech.pegasys.pantheon.util.bytes.Bytes32;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import com.google.common.base.Charsets;
import org.apache.logging.log4j.Logger;

public class EeaGetTransactionReceipt implements JsonRpcMethod {
Expand Down Expand Up @@ -98,8 +97,7 @@ public JsonRpcResponse response(final JsonRpcRequest request) {
LOG.trace("Received transaction information from Enclave");

final BytesValueRLPInput bytesValueRLPInput =
new BytesValueRLPInput(
BytesValue.wrap(Base64.getDecoder().decode(receiveResponse.getPayload())), false);
new BytesValueRLPInput(BytesValues.fromBase64(receiveResponse.getPayload()), false);

privateTransaction = PrivateTransaction.readFrom(bytesValueRLPInput);
privacyGroupId = receiveResponse.getPrivacyGroupId();
Expand All @@ -114,7 +112,7 @@ public JsonRpcResponse response(final JsonRpcRequest request) {
? Address.privateContractAddress(
privateTransaction.getSender(),
privateTransaction.getNonce(),
BytesValue.wrap(privacyGroupId.getBytes(Charsets.UTF_8)))
BytesValues.fromBase64(privacyGroupId))
.toString()
: null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionHandler;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

import org.junit.Test;

public class EeaGetTransactionCountTest {

private final JsonRpcParameter parameters = new JsonRpcParameter();
private final BytesValue privacyGroupId = BytesValue.wrap("0x123".getBytes(UTF_8));
private final String privacyGroupId =
BytesValues.asBase64String(BytesValue.wrap("0x123".getBytes(UTF_8)));

private final Address senderAddress =
Address.fromHexString("0x627306090abab3a6e1400e9345bc60c78a8bef57");
Expand All @@ -39,13 +41,12 @@ public class EeaGetTransactionCountTest {
public void verifyTransactionCount() {
final PrivateTransactionHandler privateTransactionHandler =
mock(PrivateTransactionHandler.class);
when(privateTransactionHandler.getSenderNonce(senderAddress, privacyGroupId.toString()))
.thenReturn(NONCE);
when(privateTransactionHandler.getSenderNonce(senderAddress, privacyGroupId)).thenReturn(NONCE);

final EeaGetTransactionCount eeaGetTransactionCount =
new EeaGetTransactionCount(parameters, privateTransactionHandler);

final Object[] params = new Object[] {senderAddress, privacyGroupId.toString()};
final Object[] params = new Object[] {senderAddress, privacyGroupId};
final JsonRpcRequest request = new JsonRpcRequest("1", "eea_getTransactionCount", params);

final JsonRpcSuccessResponse response =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/** Static utility methods to work with {@link BytesValue} and {@link MutableBytesValue}. */
public abstract class BytesValues {
Expand Down Expand Up @@ -254,6 +255,18 @@ public static BigInteger asSignedBigInteger(final BytesValue bytes) {
return new BigInteger(bytes.getArrayUnsafe());
}

public static String asBase64String(final BytesValue bytesValue) {
return Base64.getEncoder().encodeToString(bytesValue.extractArray());
}

public static BytesValue fromBase64(final byte[] bytes) {
return BytesValue.wrap(Base64.getDecoder().decode(bytes));
}

public static BytesValue fromBase64(final String str) {
return BytesValue.wrap(Base64.getDecoder().decode(str));
}

// In Java9, this could be moved to BytesValue and made private
static BytesValue fromHexString(final String str, final int destSize, final boolean lenient) {
return BytesValue.wrap(fromRawHexString(str, destSize, lenient));
Expand Down