Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor-privacy-storage #7

Merged
merged 15 commits into from
Sep 29, 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 @@ -93,8 +93,8 @@ public JsonRpcResponse response(final JsonRpcRequest request) {
final long blockNumber = blockchain.getBlockchain().getBlockHeader(blockhash).get().getNumber();

final String publicKey = privacyParameters.getEnclavePublicKey();
PrivateTransaction privateTransaction;
String privacyGroupId;
final PrivateTransaction privateTransaction;
final String privacyGroupId;
try {
final ReceiveResponse receiveResponse = getReceiveResponseFromEnclave(transaction, publicKey);
LOG.trace("Received transaction information from Enclave");
Expand Down Expand Up @@ -123,34 +123,34 @@ public JsonRpcResponse response(final JsonRpcRequest request) {

LOG.trace("Calculated contractAddress: {}", contractAddress);

BytesValue rlpEncoded = RLP.encode(privateTransaction::writeTo);
Bytes32 txHash = org.hyperledger.besu.crypto.Hash.keccak256(rlpEncoded);
final BytesValue rlpEncoded = RLP.encode(privateTransaction::writeTo);
final Bytes32 txHash = org.hyperledger.besu.crypto.Hash.keccak256(rlpEncoded);

LOG.trace("Calculated private transaction hash: {}", txHash);

List<Log> events =
final List<Log> transactionLogs =
privacyParameters
.getPrivateTransactionStorage()
.getEvents(txHash)
.getPrivateStateStorage()
.getTransactionLogs(txHash)
.orElse(Collections.emptyList());

LOG.trace("Processed private transaction events");

BytesValue output =
final BytesValue transactionOutput =
privacyParameters
.getPrivateTransactionStorage()
.getOutput(txHash)
.getPrivateStateStorage()
.getTransactionOutput(txHash)
.orElse(BytesValue.wrap(new byte[0]));

LOG.trace("Processed private transaction output");

PrivateTransactionReceiptResult result =
final PrivateTransactionReceiptResult result =
new PrivateTransactionReceiptResult(
contractAddress,
privateTransaction.getSender().toString(),
privateTransaction.getTo().map(Address::toString).orElse(null),
events,
output,
transactionLogs,
transactionOutput,
blockhash,
transactionHash,
blockNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionStorage;
import org.hyperledger.besu.ethereum.privacy.Restriction;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.util.bytes.Bytes32;
import org.hyperledger.besu.util.bytes.BytesValue;
Expand Down Expand Up @@ -154,11 +154,10 @@ public void setUp() {
final BlockHeader mockBlockHeader = mock(BlockHeader.class);
when(blockchain.getBlockHeader(any(Hash.class))).thenReturn(Optional.of(mockBlockHeader));
when(mockBlockHeader.getNumber()).thenReturn(0L);
final PrivateTransactionStorage privateTransactionStorage =
mock(PrivateTransactionStorage.class);
when(privacyParameters.getPrivateTransactionStorage()).thenReturn(privateTransactionStorage);
when(privateTransactionStorage.getEvents(any(Bytes32.class))).thenReturn(Optional.empty());
when(privateTransactionStorage.getOutput(any(Bytes32.class))).thenReturn(Optional.empty());
final PrivateStateStorage privateStateStorage = mock(PrivateStateStorage.class);
when(privacyParameters.getPrivateStateStorage()).thenReturn(privateStateStorage);
when(privateStateStorage.getTransactionLogs(any(Bytes32.class))).thenReturn(Optional.empty());
when(privateStateStorage.getTransactionOutput(any(Bytes32.class))).thenReturn(Optional.empty());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import org.hyperledger.besu.ethereum.core.WorldUpdater;
import org.hyperledger.besu.ethereum.mainnet.SpuriousDragonGasCalculator;
import org.hyperledger.besu.ethereum.privacy.PrivateStateStorage;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionStorage;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.ethereum.vm.OperationTracer;
Expand Down Expand Up @@ -85,15 +84,13 @@ public class PrivacyPrecompiledContractIntegrationTest {

private static OrionTestHarness testHarness;
private static WorldStateArchive worldStateArchive;
private static PrivateTransactionStorage privateTransactionStorage;
private static PrivateTransactionStorage.Updater updater;
private static PrivateStateStorage privateStateStorage;
private static PrivateStateStorage.Updater storageUpdater;

private PrivateTransactionProcessor mockPrivateTxProcessor() {
PrivateTransactionProcessor mockPrivateTransactionProcessor =
final PrivateTransactionProcessor mockPrivateTransactionProcessor =
mock(PrivateTransactionProcessor.class);
PrivateTransactionProcessor.Result result =
final PrivateTransactionProcessor.Result result =
PrivateTransactionProcessor.Result.successful(
null, 0, BytesValue.fromHexString(DEFAULT_OUTPUT), null);
when(mockPrivateTransactionProcessor.processTransaction(
Expand Down Expand Up @@ -126,19 +123,18 @@ public static void setUpOnce() throws Exception {
messageFrame = mock(MessageFrame.class);

worldStateArchive = mock(WorldStateArchive.class);
MutableWorldState mutableWorldState = mock(MutableWorldState.class);
final MutableWorldState mutableWorldState = mock(MutableWorldState.class);
when(mutableWorldState.updater()).thenReturn(mock(WorldUpdater.class));
when(worldStateArchive.getMutable()).thenReturn(mutableWorldState);
when(worldStateArchive.getMutable(any())).thenReturn(Optional.of(mutableWorldState));
privateTransactionStorage = mock(PrivateTransactionStorage.class);
updater = mock(PrivateTransactionStorage.Updater.class);
when(updater.putTransactionLogs(nullable(Bytes32.class), any())).thenReturn(updater);
when(updater.putTransactionResult(nullable(Bytes32.class), any())).thenReturn(updater);
when(privateTransactionStorage.updater()).thenReturn(updater);

privateStateStorage = mock(PrivateStateStorage.class);
storageUpdater = mock(PrivateStateStorage.Updater.class);
when(storageUpdater.putPrivateAccountState(nullable(Bytes32.class), any()))
when(storageUpdater.putLatestStateRoot(nullable(Bytes32.class), any()))
.thenReturn(storageUpdater);
when(storageUpdater.putTransactionLogs(nullable(Bytes32.class), any()))
.thenReturn(storageUpdater);
when(storageUpdater.putTransactionResult(nullable(Bytes32.class), any()))
.thenReturn(storageUpdater);
when(privateStateStorage.updater()).thenReturn(storageUpdater);
}
Expand All @@ -154,38 +150,37 @@ public void testUpCheck() throws IOException {
}

@Test
public void testSendAndReceive() throws Exception {
List<String> publicKeys = testHarness.getPublicKeys();
public void testSendAndReceive() {
final List<String> publicKeys = testHarness.getPublicKeys();

String s = new String(VALID_PRIVATE_TRANSACTION_RLP_BASE64, UTF_8);
SendRequest sc =
final String s = new String(VALID_PRIVATE_TRANSACTION_RLP_BASE64, UTF_8);
final SendRequest sc =
new SendRequestLegacy(s, publicKeys.get(0), Lists.newArrayList(publicKeys.get(0)));
SendResponse sr = enclave.send(sc);
final SendResponse sr = enclave.send(sc);

PrivacyPrecompiledContract privacyPrecompiledContract =
final PrivacyPrecompiledContract privacyPrecompiledContract =
new PrivacyPrecompiledContract(
new SpuriousDragonGasCalculator(),
publicKeys.get(0),
enclave,
worldStateArchive,
privateTransactionStorage,
privateStateStorage);

privacyPrecompiledContract.setPrivateTransactionProcessor(mockPrivateTxProcessor());

BytesValue actual =
final BytesValue actual =
privacyPrecompiledContract.compute(BytesValues.fromBase64(sr.getKey()), messageFrame);

assertThat(actual).isEqualTo(BytesValue.fromHexString(DEFAULT_OUTPUT));
}

@Test
public void testNoPrivateKeyError() throws RuntimeException {
List<String> publicKeys = testHarness.getPublicKeys();
final List<String> publicKeys = testHarness.getPublicKeys();
publicKeys.add("noPrivateKey");

String s = new String(VALID_PRIVATE_TRANSACTION_RLP_BASE64, UTF_8);
SendRequest sc = new SendRequestLegacy(s, publicKeys.get(0), publicKeys);
final String s = new String(VALID_PRIVATE_TRANSACTION_RLP_BASE64, UTF_8);
final SendRequest sc = new SendRequestLegacy(s, publicKeys.get(0), publicKeys);

final Throwable thrown = catchThrowable(() -> enclave.send(sc));

Expand All @@ -194,11 +189,11 @@ public void testNoPrivateKeyError() throws RuntimeException {

@Test
public void testWrongPrivateKeyError() throws RuntimeException {
List<String> publicKeys = testHarness.getPublicKeys();
final List<String> publicKeys = testHarness.getPublicKeys();
publicKeys.add("noPrivateKenoPrivateKenoPrivateKenoPrivateK");

String s = new String(VALID_PRIVATE_TRANSACTION_RLP_BASE64, UTF_8);
SendRequest sc = new SendRequestLegacy(s, publicKeys.get(0), publicKeys);
final String s = new String(VALID_PRIVATE_TRANSACTION_RLP_BASE64, UTF_8);
final SendRequest sc = new SendRequestLegacy(s, publicKeys.get(0), publicKeys);

final Throwable thrown = catchThrowable(() -> enclave.send(sc));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@

import org.hyperledger.besu.crypto.SECP256K1;
import org.hyperledger.besu.crypto.SECP256K1.KeyPair;
import org.hyperledger.besu.ethereum.privacy.PrivateStateStorage;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionStorage;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.ethereum.worldstate.WorldStatePreimageStorage;
Expand All @@ -44,10 +43,9 @@ public class PrivacyParameters {
private String enclavePublicKey;
private File enclavePublicKeyFile;
private Optional<SECP256K1.KeyPair> signingKeyPair = Optional.empty();

private WorldStateArchive privateWorldStateArchive;
private StorageProvider privateStorageProvider;

private PrivateTransactionStorage privateTransactionStorage;
private PrivateStateStorage privateStateStorage;

public Integer getPrivacyAddress() {
Expand Down Expand Up @@ -114,15 +112,6 @@ public void setPrivateStorageProvider(final StorageProvider privateStorageProvid
this.privateStorageProvider = privateStorageProvider;
}

public PrivateTransactionStorage getPrivateTransactionStorage() {
return privateTransactionStorage;
}

public void setPrivateTransactionStorage(
final PrivateTransactionStorage privateTransactionStorage) {
this.privateTransactionStorage = privateTransactionStorage;
}

public PrivateStateStorage getPrivateStateStorage() {
return privateStateStorage;
}
Expand Down Expand Up @@ -181,16 +170,14 @@ public PrivacyParameters build() throws IOException {
final WorldStateArchive privateWorldStateArchive =
new WorldStateArchive(privateWorldStateStorage, privatePreimageStorage);

final PrivateTransactionStorage privateTransactionStorage =
storageProvider.createPrivateTransactionStorage();
final PrivateStateStorage privateStateStorage = storageProvider.createPrivateStateStorage();

config.setPrivateWorldStateArchive(privateWorldStateArchive);
config.setEnclavePublicKey(enclavePublicKey);
config.setEnclavePublicKeyFile(enclavePublicKeyFile);
config.setPrivateStorageProvider(storageProvider);
config.setPrivateTransactionStorage(privateTransactionStorage);
config.setPrivateStateStorage(privateStateStorage);

if (privateKeyPath != null) {
config.setSigningKeyPair(KeyPair.load(privateKeyPath.toFile()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@
import org.hyperledger.besu.ethereum.core.WorldUpdater;
import org.hyperledger.besu.ethereum.debug.TraceOptions;
import org.hyperledger.besu.ethereum.mainnet.AbstractPrecompiledContract;
import org.hyperledger.besu.ethereum.privacy.PrivateStateStorage;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionStorage;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.trie.MerklePatriciaTrie;
Expand All @@ -49,7 +48,6 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
private final Enclave enclave;
private final String enclavePublicKey;
private final WorldStateArchive privateWorldStateArchive;
private final PrivateTransactionStorage privateTransactionStorage;
private final PrivateStateStorage privateStateStorage;
private PrivateTransactionProcessor privateTransactionProcessor;
private static final Hash EMPTY_ROOT_HASH = Hash.wrap(MerklePatriciaTrie.EMPTY_TRIE_NODE_HASH);
Expand All @@ -63,7 +61,6 @@ public PrivacyPrecompiledContract(
privacyParameters.getEnclavePublicKey(),
new Enclave(privacyParameters.getEnclaveUri()),
privacyParameters.getPrivateWorldStateArchive(),
privacyParameters.getPrivateTransactionStorage(),
privacyParameters.getPrivateStateStorage());
}

Expand All @@ -72,13 +69,11 @@ public PrivacyPrecompiledContract(
final String publicKey,
final Enclave enclave,
final WorldStateArchive worldStateArchive,
final PrivateTransactionStorage privateTransactionStorage,
final PrivateStateStorage privateStateStorage) {
super("Privacy", gasCalculator);
this.enclave = enclave;
this.enclavePublicKey = publicKey;
this.privateWorldStateArchive = worldStateArchive;
this.privateTransactionStorage = privateTransactionStorage;
this.privateStateStorage = privateStateStorage;
}

Expand All @@ -97,7 +92,7 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram
final String key = BytesValues.asBase64String(input);
final ReceiveRequest receiveRequest = new ReceiveRequest(key, enclavePublicKey);

ReceiveResponse receiveResponse;
final ReceiveResponse receiveResponse;
try {
receiveResponse = enclave.receive(receiveRequest);
} catch (Exception e) {
Expand All @@ -116,7 +111,7 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram

// get the last world state root hash - or create a new one
final Hash lastRootHash =
privateStateStorage.getPrivateAccountState(privacyGroupId).orElse(EMPTY_ROOT_HASH);
privateStateStorage.getLatestStateRoot(privacyGroupId).orElse(EMPTY_ROOT_HASH);
iikirilov marked this conversation as resolved.
Show resolved Hide resolved

final MutableWorldState disposablePrivateState =
privateWorldStateArchive.getMutable(lastRootHash).get();
Expand Down Expand Up @@ -150,17 +145,15 @@ public BytesValue compute(final BytesValue input, final MessageFrame messageFram
disposablePrivateState.persist();

final PrivateStateStorage.Updater privateStateUpdater = privateStateStorage.updater();
privateStateUpdater.putPrivateAccountState(privacyGroupId, disposablePrivateState.rootHash());
privateStateUpdater.commit();
privateStateUpdater.putLatestStateRoot(privacyGroupId, disposablePrivateState.rootHash());

final Bytes32 txHash = keccak256(RLP.encode(privateTransaction::writeTo));
final PrivateTransactionStorage.Updater privateUpdater = privateTransactionStorage.updater();
final LogSeries logs = result.getLogs();
if (!logs.isEmpty()) {
privateUpdater.putTransactionLogs(txHash, result.getLogs());
privateStateUpdater.putTransactionLogs(txHash, result.getLogs());
}
privateUpdater.putTransactionResult(txHash, result.getOutput());
privateUpdater.commit();
privateStateUpdater.putTransactionResult(txHash, result.getOutput());
privateStateUpdater.commit();
}

return result.getOutput();
Expand Down
Loading