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

Commit

Permalink
Update Privacy pre-compiled contract.
Browse files Browse the repository at this point in the history
  • Loading branch information
Puneetha17 committed Feb 8, 2019
1 parent f661049 commit e6f7944
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@
import tech.pegasys.pantheon.ethereum.core.PrivacyParameters;
import tech.pegasys.pantheon.ethereum.core.WorldUpdater;
import tech.pegasys.pantheon.ethereum.mainnet.AbstractPrecompiledContract;
import tech.pegasys.pantheon.ethereum.mainnet.TransactionProcessor;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransaction;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionProcessor;
import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPInput;
import tech.pegasys.pantheon.ethereum.vm.GasCalculator;
import tech.pegasys.pantheon.ethereum.vm.MessageFrame;
import tech.pegasys.pantheon.util.bytes.BytesValue;

import java.io.IOException;
import java.util.Base64;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -68,18 +72,25 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram
ReceiveRequest receiveRequest = new ReceiveRequest(key, enclavePublicKey);
ReceiveResponse receiveResponse = enclave.receive(receiveRequest);

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

PrivateTransaction transaction = PrivateTransaction.readFrom(bytesValueRLPInput);

WorldUpdater privateWorldState = messageFrame.getPrivateWorldState(DEFAULT_PRIVACY_GROUP_ID);
// TransactionProcessor.Result result =
// privateTransactionProcessor.processTransaction(
// messageFrame.getBlockchain(),
// privateWorldState,
// messageFrame.getBlockHeader(),
// null,
// messageFrame.getMiningBeneficiary(),
// messageFrame.getBlockHashLookup());
WorldUpdater publicWorldState = messageFrame.getWorldState();
TransactionProcessor.Result result =
privateTransactionProcessor.processPrivateTransaction(
messageFrame.getBlockchain(),
privateWorldState,
publicWorldState,
messageFrame.getBlockHeader(),
transaction,
messageFrame.getMiningBeneficiary(),
messageFrame.getBlockHashLookup());

// return result.getOutput();
return BytesValue.wrap(receiveResponse.getPayload());
return result.getOutput();
} catch (IOException e) {
LOG.fatal("Enclave threw an unhandled exception.", e);
return BytesValue.EMPTY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ private SendRequest createSendRequest(final PrivateTransaction privateTransactio
final BytesValueRLPOutput bvrlp = new BytesValueRLPOutput();
privateTransaction.writeTo(bvrlp);

// String s = new String(bvrlp.encoded().extractArray(), UTF_8);
return new SendRequest(
Base64.getEncoder().encodeToString(bvrlp.encoded().extractArray()),
BytesValues.asString(privateTransaction.getPrivateFrom()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
package tech.pegasys.pantheon.ethereum.privacy;

import static tech.pegasys.pantheon.ethereum.vm.OperationTracer.NO_TRACING;

import tech.pegasys.pantheon.ethereum.chain.Blockchain;
import tech.pegasys.pantheon.ethereum.core.Account;
import tech.pegasys.pantheon.ethereum.core.Address;
Expand Down Expand Up @@ -53,6 +55,9 @@ public class PrivateTransactionProcessor implements TransactionProcessor {

private final AbstractMessageProcessor messageCallProcessor;

private MutableAccount sender;
private Address senderAddress;

public static class Result implements TransactionProcessor.Result {

private final Status status;
Expand Down Expand Up @@ -139,6 +144,46 @@ public PrivateTransactionProcessor(
this.clearEmptyAccounts = clearEmptyAccounts;
}

public TransactionProcessor.Result processPrivateTransaction(
final Blockchain blockchain,
final WorldUpdater privateWorldState,
final WorldUpdater publicWorldState,
final ProcessableBlockHeader blockHeader,
final PrivateTransaction privateTransaction,
final Address miningBeneficiary,
final BlockHashLookup blockHashLookup) {
Transaction transaction =
new Transaction(
privateTransaction.getNonce(),
privateTransaction.getGasPrice(),
privateTransaction.getGasLimit(),
privateTransaction.getTo(),
privateTransaction.getValue(),
privateTransaction.getSignature(),
privateTransaction.getPayload(),
privateTransaction.getSender(),
privateTransaction.getChainId().getAsInt());

final Address senderAddress = transaction.getSender();
this.senderAddress = senderAddress;
Account sender = privateWorldState.get(senderAddress);
if (sender == null) {
sender = publicWorldState.get(senderAddress);
this.sender = privateWorldState.createAccount(sender.getAddress(), 0, sender.getBalance());
} else {
this.sender = privateWorldState.getMutable(senderAddress);
}

return processTransaction(
blockchain,
privateWorldState,
blockHeader,
transaction,
miningBeneficiary,
NO_TRACING,
blockHashLookup);
}

@Override
public Result processTransaction(
final Blockchain blockchain,
Expand All @@ -160,8 +205,6 @@ public Result processTransaction(
return Result.invalid(validationResult);
}

final Address senderAddress = transaction.getSender();
final MutableAccount sender = worldState.getOrCreate(senderAddress);
validationResult =
transactionValidator.validateForSender(transaction, sender, OptionalLong.empty());
if (!validationResult.isValid()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,27 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;

import tech.pegasys.pantheon.enclave.Enclave;
import tech.pegasys.pantheon.enclave.types.ReceiveRequest;
import tech.pegasys.pantheon.enclave.types.ReceiveResponse;
import tech.pegasys.pantheon.ethereum.chain.Blockchain;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.ProcessableBlockHeader;
import tech.pegasys.pantheon.ethereum.core.WorldUpdater;
import tech.pegasys.pantheon.ethereum.mainnet.SpuriousDragonGasCalculator;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransaction;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionProcessor;
import tech.pegasys.pantheon.ethereum.vm.BlockHashLookup;
import tech.pegasys.pantheon.ethereum.vm.MessageFrame;
import tech.pegasys.pantheon.util.bytes.BytesValue;

import java.io.IOException;
import java.util.Base64;

import org.junit.Before;
import org.junit.Test;
Expand All @@ -37,15 +47,51 @@ public class PrivacyPrecompiledContractTest {
private PrivacyPrecompiledContract privacyPrecompiledContract;
private PrivacyPrecompiledContract brokenPrivateTransactionHandler;
private MessageFrame messageFrame;
private final String DEFAULT_OUTPUT = "0x01";

Enclave mockEnclave() throws IOException {
private static final byte[] VALID_PRIVATE_TRANSACTION_RLP_BASE64 =
Base64.getEncoder()
.encode(
BytesValue.fromHexString(
"0xf90113800182520894095e7baea6a6c7c4c2dfeb977efac326af552d87"
+ "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffff801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d"
+ "495a36649353a01fffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab94"
+ "9f53faa07bd2c804ac41316156744d784c4355486d425648586f5a7a7a4267"
+ "5062572f776a3561784470573958386c393153476f3df85aac41316156744d"
+ "784c4355486d425648586f5a7a7a42675062572f776a356178447057395838"
+ "6c393153476f3dac4b6f32625671442b6e4e6c4e594c35454537793349644f"
+ "6e766966746a69697a706a52742b4854754642733d8a726573747269637465"
+ "64")
.extractArray());

private Enclave mockEnclave() throws IOException {
Enclave mockEnclave = mock(Enclave.class);
ReceiveResponse response = new ReceiveResponse(actual.getBytes(UTF_8));
ReceiveResponse response = new ReceiveResponse(VALID_PRIVATE_TRANSACTION_RLP_BASE64);
when(mockEnclave.receive(any(ReceiveRequest.class))).thenReturn(response);
return mockEnclave;
}

Enclave brokenMockEnclave() throws IOException {
private PrivateTransactionProcessor mockPrivateTxProcessor() {
PrivateTransactionProcessor mockPrivateTransactionProcessor =
mock(PrivateTransactionProcessor.class, withSettings().verboseLogging());
PrivateTransactionProcessor.Result result =
PrivateTransactionProcessor.Result.successful(
null, 0, BytesValue.fromHexString(DEFAULT_OUTPUT), null);
when(mockPrivateTransactionProcessor.processPrivateTransaction(
nullable(Blockchain.class),
nullable(WorldUpdater.class),
nullable(WorldUpdater.class),
nullable(ProcessableBlockHeader.class),
nullable(PrivateTransaction.class),
nullable(Address.class),
nullable(BlockHashLookup.class)))
.thenReturn(result);

return mockPrivateTransactionProcessor;
}

private Enclave brokenMockEnclave() throws IOException {
Enclave mockEnclave = mock(Enclave.class);
when(mockEnclave.receive(any(ReceiveRequest.class))).thenThrow(IOException.class);
return mockEnclave;
Expand All @@ -55,6 +101,7 @@ Enclave brokenMockEnclave() throws IOException {
public void setUp() throws IOException {
privacyPrecompiledContract =
new PrivacyPrecompiledContract(new SpuriousDragonGasCalculator(), publicKey, mockEnclave());
privacyPrecompiledContract.setPrivateTransactionProcessor(mockPrivateTxProcessor());
brokenPrivateTransactionHandler =
new PrivacyPrecompiledContract(
new SpuriousDragonGasCalculator(), publicKey, brokenMockEnclave());
Expand All @@ -64,10 +111,9 @@ public void setUp() throws IOException {
@Test
public void testPrivacyPrecompiledContract() {

final BytesValue expected = privacyPrecompiledContract.compute(key, messageFrame);
final BytesValue actual = privacyPrecompiledContract.compute(key, messageFrame);

String exp = new String(expected.extractArray(), UTF_8);
assertThat(exp).isEqualTo(actual);
assertThat(actual).isEqualTo(BytesValue.fromHexString(DEFAULT_OUTPUT));
}

@Test
Expand Down

0 comments on commit e6f7944

Please sign in to comment.