mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 21:17:54 -05:00
[PAN-2852] privacy group id consistent (#1667)
Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
This commit is contained in:
committed by
Lucas Saldanha
parent
ef47ffe050
commit
2c64a9ceba
@@ -30,6 +30,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.node.PantheonNode;
|
||||
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;
|
||||
@@ -113,7 +114,7 @@ public class PrivacyNode extends PantheonNode {
|
||||
public long nextNonce(final BytesValue privacyGroupId) {
|
||||
return execute(
|
||||
new EeaGetTransactionCountTransaction(
|
||||
getAddress().toString(), privacyGroupId.toString()))
|
||||
getAddress().toString(), BytesValues.asBase64String(privacyGroupId)))
|
||||
.longValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -23,6 +22,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivacyNet;
|
||||
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;
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PrivateTxEnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
|
||||
public class EnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBase {
|
||||
protected static final String CONTRACT_NAME = "Event Emitter";
|
||||
|
||||
private EventEmitterHarness eventEmitterHarness;
|
||||
@@ -54,7 +54,8 @@ public class PrivateTxEnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBa
|
||||
privateTransactionVerifier,
|
||||
eea);
|
||||
wrongPublicKey =
|
||||
BytesValue.wrap(Base64.getEncoder().encode(Box.KeyPair.random().publicKey().bytesArray()));
|
||||
BytesValues.fromBase64(
|
||||
Base64.getEncoder().encode(Box.KeyPair.random().publicKey().bytesArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -91,8 +92,7 @@ public class PrivateTxEnclaveErrorAcceptanceTest extends PrivacyAcceptanceTestBa
|
||||
.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);
|
||||
@@ -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;
|
||||
|
||||
@@ -24,6 +23,7 @@ import tech.pegasys.pantheon.tests.acceptance.dsl.privacy.PrivateTransactionVeri
|
||||
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;
|
||||
@@ -118,8 +118,7 @@ public class EventEmitterHarness {
|
||||
.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);
|
||||
@@ -159,8 +158,7 @@ public class EventEmitterHarness {
|
||||
.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);
|
||||
@@ -190,8 +188,7 @@ public class EventEmitterHarness {
|
||||
.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);
|
||||
@@ -229,9 +226,7 @@ public class EventEmitterHarness {
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ package tech.pegasys.pantheon.tests.web3j.privacy;
|
||||
|
||||
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;
|
||||
@@ -27,7 +28,6 @@ import org.web3j.rlp.RlpEncoder;
|
||||
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(
|
||||
@@ -47,8 +47,7 @@ public class PrivacyGroup {
|
||||
.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)))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,8 @@ import tech.pegasys.pantheon.ethereum.vm.MessageFrame;
|
||||
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;
|
||||
|
||||
@@ -107,15 +105,14 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -35,7 +35,6 @@ import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive;
|
||||
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;
|
||||
|
||||
@@ -98,18 +97,18 @@ public class PrivateTransactionHandler {
|
||||
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;
|
||||
@@ -159,33 +158,34 @@ public class PrivateTransactionHandler {
|
||||
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
|
||||
|
||||
@@ -26,9 +26,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
|
||||
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;
|
||||
|
||||
@@ -56,7 +54,7 @@ public class EeaGetPrivateTransaction implements JsonRpcMethod {
|
||||
|
||||
@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 =
|
||||
@@ -64,8 +62,7 @@ public class EeaGetPrivateTransaction implements JsonRpcMethod {
|
||||
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);
|
||||
|
||||
@@ -39,13 +39,12 @@ import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPInput;
|
||||
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 {
|
||||
@@ -98,8 +97,7 @@ public class EeaGetTransactionReceipt implements JsonRpcMethod {
|
||||
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();
|
||||
@@ -114,7 +112,7 @@ public class EeaGetTransactionReceipt implements JsonRpcMethod {
|
||||
? Address.privateContractAddress(
|
||||
privateTransaction.getSender(),
|
||||
privateTransaction.getNonce(),
|
||||
BytesValue.wrap(privacyGroupId.getBytes(Charsets.UTF_8)))
|
||||
BytesValues.fromBase64(privacyGroupId))
|
||||
.toString()
|
||||
: null;
|
||||
|
||||
|
||||
@@ -23,13 +23,15 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.parameters.JsonRpcParamet
|
||||
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");
|
||||
@@ -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 =
|
||||
|
||||
@@ -16,6 +16,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
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 {
|
||||
@@ -254,6 +255,18 @@ public abstract class BytesValues {
|
||||
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));
|
||||
|
||||
Reference in New Issue
Block a user