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

[PAN-2910] Eea get private transaction fix #1707

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -12,7 +12,6 @@
*/
package tech.pegasys.pantheon.ethereum.mainnet.precompiles.privacy;

import static java.nio.charset.StandardCharsets.UTF_8;
import static tech.pegasys.pantheon.crypto.Hash.keccak256;

import tech.pegasys.pantheon.enclave.Enclave;
Expand Down Expand Up @@ -93,7 +92,7 @@ public Gas gasRequirement(final BytesValue input) {

@Override
public BytesValue compute(final BytesValue input, final MessageFrame messageFrame) {
final String key = new String(input.extractArray(), UTF_8);
final String key = BytesValues.asBase64String(input);
final ReceiveRequest receiveRequest = new ReceiveRequest(key, enclavePublicKey);

ReceiveResponse receiveResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ public class PrivateTransaction {

private final Optional<BigInteger> chainId;

private final Optional<BytesValue> privacyGroupId;

private final Optional<BytesValue> privateFrom;
private final BytesValue privateFrom;

private final Optional<List<BytesValue>> privateFor;

private final Optional<BytesValue> privacyGroupId;

private final Restriction restriction;

// Caches a "hash" of a portion of the transaction used for sender recovery.
Expand All @@ -91,6 +91,12 @@ public static Builder builder() {
}

public static PrivateTransaction readFrom(final RLPInput input) throws RLPException {
return readFrom(input, null);
}

@SuppressWarnings({"unchecked"})
public static PrivateTransaction readFrom(final RLPInput input, final BytesValue enclavePublicKey)
throws RLPException {
input.enterList();

final Builder builder =
Expand All @@ -117,34 +123,49 @@ public static PrivateTransaction readFrom(final RLPInput input) throws RLPExcept
final BigInteger r = BytesValues.asUnsignedBigInteger(input.readUInt256Scalar().getBytes());
final BigInteger s = BytesValues.asUnsignedBigInteger(input.readUInt256Scalar().getBytes());
final SECP256K1.Signature signature = SECP256K1.Signature.create(r, s, recId);
final BytesValue tempValue = input.readBytesValue();
Optional<List<BytesValue>> privateFor = Optional.empty();
if (input.nextIsList()) {
privateFor = Optional.of(input.readList(RLPInput::readBytesValue));
}

final Restriction restriction = convertToEnum(input.readBytesValue());
final RLPInput item1 = input.readAsRlp(); // privateFrom or privateFor/PrivacyGroupId
final RLPInput item2 = input.readAsRlp(); // privateFor/PrivacyGroupId or restriction

final BytesValue privateFrom;
final Object privateForOrPrivacyGroupId;
final Restriction restriction;

if (input.isEndOfCurrentList()) {
privateFrom = enclavePublicKey;
privateForOrPrivacyGroupId = resolvePrivateForOrPrivacyGroupId(item1);
restriction = convertToEnum(item2.readBytesValue());
} else {
privateFrom = item1.readBytesValue();
privateForOrPrivacyGroupId = resolvePrivateForOrPrivacyGroupId(item2);
restriction = convertToEnum(input.readBytesValue());
}

input.leaveList();

chainId.ifPresent(builder::chainId);

if (privateFor.isPresent()) {
if (privateForOrPrivacyGroupId instanceof List) {
return builder
.signature(signature)
.privateFrom(tempValue)
.privateFor(privateFor.get())
.privateFrom(privateFrom)
.privateFor((List<BytesValue>) privateForOrPrivacyGroupId)
.restriction(restriction)
.build();
} else {
return builder
.signature(signature)
.privacyGroupId(tempValue)
.privateFrom(privateFrom)
.privacyGroupId((BytesValue) privateForOrPrivacyGroupId)
.restriction(restriction)
.build();
}
}

private static Object resolvePrivateForOrPrivacyGroupId(final RLPInput item) {
return item.nextIsList() ? item.readList(RLPInput::readBytesValue) : item.readBytesValue();
}

private static Restriction convertToEnum(final BytesValue readBytesValue) {
if (readBytesValue.equals(Restriction.RESTRICTED.getBytes())) {
return Restriction.RESTRICTED;
Expand Down Expand Up @@ -186,9 +207,9 @@ protected PrivateTransaction(
final BytesValue payload,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<BytesValue> privacyGroupId,
final Optional<BytesValue> privateFrom,
final BytesValue privateFrom,
final Optional<List<BytesValue>> privateFor,
final Optional<BytesValue> privacyGroupId,
final Restriction restriction) {
this.nonce = nonce;
this.gasPrice = gasPrice;
Expand All @@ -199,9 +220,9 @@ protected PrivateTransaction(
this.payload = payload;
this.sender = sender;
this.chainId = chainId;
this.privacyGroupId = privacyGroupId;
this.privateFrom = privateFrom;
this.privateFor = privateFor;
this.privacyGroupId = privacyGroupId;
this.restriction = restriction;
}

Expand Down Expand Up @@ -283,21 +304,12 @@ public Optional<BigInteger> getChainId() {
return chainId;
}

/**
* Returns the enclave privacy group id.
*
* @return the enclave privacy group id.
*/
public Optional<BytesValue> getPrivacyGroupId() {
return privacyGroupId;
}

/**
* Returns the enclave public key of the sender.
*
* @return the enclave public key of the sender.
*/
public Optional<BytesValue> getPrivateFrom() {
public BytesValue getPrivateFrom() {
return privateFrom;
}

Expand All @@ -310,6 +322,15 @@ public Optional<List<BytesValue>> getPrivateFor() {
return privateFor;
}

/**
* Returns the enclave privacy group id.
*
* @return the enclave privacy group id.
*/
public Optional<BytesValue> getPrivacyGroupId() {
return privacyGroupId;
}

/**
* Returns the restriction of this private transaction.
*
Expand Down Expand Up @@ -348,9 +369,9 @@ private Bytes32 getOrComputeSenderRecoveryHash() {
value,
payload,
chainId,
privacyGroupId,
privateFrom,
privateFor,
privacyGroupId,
restriction.getBytes());
}
return hashNoSignature;
Expand All @@ -371,10 +392,10 @@ public void writeTo(final RLPOutput out) {
out.writeUInt256Scalar(getValue());
out.writeBytesValue(getPayload());
writeSignature(out);
getPrivacyGroupId().ifPresent(out::writeBytesValue);
getPrivateFrom().ifPresent(out::writeBytesValue);
out.writeBytesValue(getPrivateFrom());
getPrivateFor()
.ifPresent(privateFor -> out.writeList(privateFor, (bv, rlpO) -> rlpO.writeBytesValue(bv)));
getPrivacyGroupId().ifPresent(out::writeBytesValue);
out.writeBytesValue(getRestriction().getBytes());

out.endList();
Expand Down Expand Up @@ -457,9 +478,9 @@ private static Bytes32 computeSenderRecoveryHash(
final Wei value,
final BytesValue payload,
final Optional<BigInteger> chainId,
final Optional<BytesValue> privacyGroupId,
final Optional<BytesValue> privateFrom,
final BytesValue privateFrom,
final Optional<List<BytesValue>> privateFor,
final Optional<BytesValue> privacyGroupId,
final BytesValue restriction) {
return keccak256(
RLP.encode(
Expand All @@ -476,9 +497,9 @@ private static Bytes32 computeSenderRecoveryHash(
out.writeUInt256Scalar(UInt256.ZERO);
out.writeUInt256Scalar(UInt256.ZERO);
}
privacyGroupId.ifPresent(out::writeBytesValue);
privateFrom.ifPresent(out::writeBytesValue);
out.writeBytesValue(privateFrom);
privateFor.ifPresent(pF -> out.writeList(pF, (bv, rlpO) -> rlpO.writeBytesValue(bv)));
privacyGroupId.ifPresent(out::writeBytesValue);
out.writeBytesValue(restriction);
out.endList();
}));
Expand Down Expand Up @@ -530,15 +551,14 @@ public String toString() {
sb.append("value=").append(getValue()).append(", ");
sb.append("sig=").append(getSignature()).append(", ");
if (chainId.isPresent()) sb.append("chainId=").append(getChainId().get()).append(", ");
sb.append("payload=").append(getPayload());
if (getPrivacyGroupId().isPresent())
sb.append("privacyGroupId=").append(getPrivacyGroupId().get()).append(", ");
if (getPrivateFrom().isPresent())
sb.append("privateFrom=").append(getPrivateFrom().get()).append(", ");
sb.append("payload=").append(getPayload()).append(", ");
sb.append("privateFrom=").append(getPrivateFrom()).append(", ");
if (getPrivateFor().isPresent())
sb.append("privateFor=")
.append(Arrays.toString(getPrivateFor().get().toArray()))
.append(", ");
if (getPrivacyGroupId().isPresent())
sb.append("privacyGroupId=").append(getPrivacyGroupId().get()).append(", ");
sb.append("restriction=").append(getRestriction());
return sb.append("}").toString();
}
Expand Down Expand Up @@ -570,12 +590,12 @@ public static class Builder {

protected Optional<BigInteger> chainId = Optional.empty();

protected Optional<BytesValue> privacyGroupId = Optional.empty();

protected Optional<BytesValue> privateFrom = Optional.empty();
protected BytesValue privateFrom;

protected Optional<List<BytesValue>> privateFor = Optional.empty();

protected Optional<BytesValue> privacyGroupId = Optional.empty();

protected Restriction restriction;

public Builder chainId(final BigInteger chainId) {
Expand Down Expand Up @@ -629,7 +649,7 @@ public Builder privacyGroupId(final BytesValue privacyGroupId) {
}

public Builder privateFrom(final BytesValue privateFrom) {
this.privateFrom = Optional.of(privateFrom);
this.privateFrom = privateFrom;
return this;
}

Expand All @@ -644,9 +664,9 @@ public Builder restriction(final Restriction restriction) {
}

public PrivateTransaction build() {
if (privacyGroupId.isPresent() && (privateFrom.isPresent() || privateFor.isPresent())) {
if (privacyGroupId.isPresent() && privateFor.isPresent()) {
throw new IllegalArgumentException(
"Private transaction should contain either privacyGroup by itself or privateFrom and privateFor together, but not both");
"Private transaction should contain either privacyGroup or privateFor, but not both");
}
return new PrivateTransaction(
nonce,
Expand All @@ -658,9 +678,9 @@ public PrivateTransaction build() {
payload,
sender,
chainId,
privacyGroupId,
privateFrom,
privateFor,
privacyGroupId,
restriction);
}

Expand All @@ -682,9 +702,9 @@ protected SECP256K1.Signature computeSignature(final SECP256K1.KeyPair keys) {
value,
payload,
chainId,
privacyGroupId,
privateFrom,
privateFor,
privacyGroupId,
restriction.getBytes());
return SECP256K1.sign(hash, keys);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@
import tech.pegasys.pantheon.ethereum.mainnet.ValidationResult;
import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPOutput;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;

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

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

Expand Down Expand Up @@ -100,11 +98,10 @@ public String getPrivacyGroup(final String key, final PrivateTransaction private
return BytesValues.asBase64String(privateTransaction.getPrivacyGroupId().get());
}
final ReceiveRequest receiveRequest =
new ReceiveRequest(
key, BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()));
new ReceiveRequest(key, BytesValues.asBase64String(privateTransaction.getPrivateFrom()));
LOG.debug(
"Getting privacy group for {}",
BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()));
BytesValues.asBase64String(privateTransaction.getPrivateFrom()));
final ReceiveResponse receiveResponse;
try {
receiveResponse = enclave.receive(receiveRequest);
Expand All @@ -126,7 +123,7 @@ public Transaction createPrivacyMarkerTransaction(
.gasLimit(privateTransaction.getGasLimit())
.to(privacyPrecompileAddress)
.value(privateTransaction.getValue())
.payload(BytesValue.wrap(transactionEnclaveKey.getBytes(Charsets.UTF_8)))
.payload(BytesValues.fromBase64(transactionEnclaveKey))
.sender(signerAddress)
.signAndBuild(nodeKeyPair);
}
Expand Down Expand Up @@ -173,13 +170,11 @@ private SendRequest createSendRequest(final PrivateTransaction privateTransactio

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

return new SendRequestLegacy(
payload,
BytesValues.asBase64String(privateTransaction.getPrivateFrom().get()),
privateFor);
payload, BytesValues.asBase64String(privateTransaction.getPrivateFrom()), privateFor);
}
}

Expand Down Expand Up @@ -210,4 +205,8 @@ public long getSenderNonce(final Address sender, final String privacyGroupId) {
public Address getSignerAddress() {
return signerAddress;
}

public String getEnclaveKey() {
return enclavePublicKey;
}
}
Loading