(internal) Refactor PrivacyReorgTest to use mock enclave (#3103)

* init

Signed-off-by: Frank Li <b439988l@gmail.com>

* working test

Signed-off-by: Frank Li <b439988l@gmail.com>

* WIP | 3/4 tests working

Signed-off-by: Frank Li <b439988l@gmail.com>
pull/3116/head
Frank Li 3 years ago committed by GitHub
parent 0b4c03c8ca
commit 78758cc796
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 124
      besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java

@ -32,7 +32,7 @@ import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.Enclave; import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.EnclaveFactory; import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.enclave.types.PrivacyGroup; import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.enclave.types.SendResponse; import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.GasLimitCalculator; import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.ProtocolContext; import org.hyperledger.besu.ethereum.ProtocolContext;
import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain;
@ -61,25 +61,19 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.data.Restriction; import org.hyperledger.besu.plugin.data.Restriction;
import org.hyperledger.besu.plugin.data.TransactionType; import org.hyperledger.besu.plugin.data.TransactionType;
import org.hyperledger.besu.testutil.TestClock; import org.hyperledger.besu.testutil.TestClock;
import org.hyperledger.enclave.testutil.EnclaveKeyConfiguration;
import org.hyperledger.enclave.testutil.EnclaveTestHarness;
import org.hyperledger.enclave.testutil.OrionTestHarnessFactory;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URI; import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import io.vertx.core.Vertx;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@ -136,31 +130,52 @@ public class PrivacyReorgTest {
private final BlockDataGenerator gen = new BlockDataGenerator(); private final BlockDataGenerator gen = new BlockDataGenerator();
private BesuController besuController; private BesuController besuController;
private EnclaveTestHarness enclave;
private PrivateStateRootResolver privateStateRootResolver; private PrivateStateRootResolver privateStateRootResolver;
private PrivacyParameters privacyParameters; private PrivacyParameters privacyParameters;
private RestrictedDefaultPrivacyController privacyController; private RestrictedDefaultPrivacyController privacyController;
private Enclave mockEnclave;
private Transaction privacyMarkerTransaction;
@Before @Before
public void setUp() throws IOException { public void setUp() throws IOException {
enclave = mockEnclave = mock(Enclave.class);
OrionTestHarnessFactory.create( final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
"orion", PRIVATE_TRANSACTION.writeTo(rlpOutput);
folder.newFolder().toPath(),
new EnclaveKeyConfiguration("enclavePublicKey", "enclavePrivateKey")); when(mockEnclave.receive(any()))
enclave.start(); .thenReturn(
new ReceiveResponse(
rlpOutput.encoded().toBase64String().getBytes(StandardCharsets.UTF_8),
PRIVACY_GROUP_BYTES32.toBase64String(),
ENCLAVE_PUBLIC_KEY.toBase64String()));
privacyMarkerTransaction =
Transaction.builder()
.type(TransactionType.FRONTIER)
.chainId(BigInteger.valueOf(1337))
.gasLimit(60000)
.gasPrice(Wei.of(1000))
.nonce(0)
.payload(Bytes32.random())
.to(DEFAULT_PRIVACY)
.value(Wei.ZERO)
.signAndBuild(KEY_PAIR);
// Create Storage // Create Storage
final Path dataDir = folder.newFolder().toPath(); final Path dataDir = folder.newFolder().toPath();
// Configure Privacy // Configure Privacy
EnclaveFactory enclaveFactory = mock(EnclaveFactory.class);
when(enclaveFactory.createVertxEnclave(any())).thenReturn(mockEnclave);
privacyParameters = privacyParameters =
new PrivacyParameters.Builder() new PrivacyParameters.Builder()
.setEnabled(true) .setEnabled(true)
.setStorageProvider(createKeyValueStorageProvider()) .setStorageProvider(createKeyValueStorageProvider())
.setEnclaveUrl(enclave.clientUrl()) .setEnclaveUrl(URI.create("http//1.1.1.1:1234"))
.setEnclaveFactory(new EnclaveFactory(Vertx.vertx())) .setEnclaveFactory(enclaveFactory)
.build(); .build();
privacyParameters.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String()); privacyParameters.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String());
privacyController = mock(RestrictedDefaultPrivacyController.class); privacyController = mock(RestrictedDefaultPrivacyController.class);
when(privacyController.findPrivacyGroupByGroupId(any(), any())) when(privacyController.findPrivacyGroupByGroupId(any(), any()))
@ -192,11 +207,6 @@ public class PrivacyReorgTest {
.build(); .build();
} }
@After
public void tearDown() {
enclave.stop();
}
@Test @Test
public void privacyGroupHeadIsTracked() { public void privacyGroupHeadIsTracked() {
// Setup an initial blockchain with one private transaction // Setup an initial blockchain with one private transaction
@ -204,13 +214,11 @@ public class PrivacyReorgTest {
final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain(); final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain();
final PrivateStateStorage privateStateStorage = privacyParameters.getPrivateStateStorage(); final PrivateStateStorage privateStateStorage = privacyParameters.getPrivateStateStorage();
final Transaction privateMarkerTransaction =
buildMarkerTransaction(getEnclaveKey(enclave.clientUrl()));
final Block firstBlock = final Block firstBlock =
gen.block( gen.block(
getBlockOptionsWithTransaction( getBlockOptionsWithTransaction(
blockchain.getGenesisBlock(), blockchain.getGenesisBlock(),
privateMarkerTransaction, privacyMarkerTransaction,
FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT)); FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT));
appendBlock(besuController, blockchain, protocolContext, firstBlock); appendBlock(besuController, blockchain, protocolContext, firstBlock);
@ -249,7 +257,7 @@ public class PrivacyReorgTest {
gen.block( gen.block(
getBlockOptionsWithTransaction( getBlockOptionsWithTransaction(
blockchain.getGenesisBlock(), blockchain.getGenesisBlock(),
buildMarkerTransaction(getEnclaveKey(enclave.clientUrl())), privacyMarkerTransaction,
FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT)); FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT));
appendBlock(besuController, blockchain, protocolContext, firstBlock); appendBlock(besuController, blockchain, protocolContext, firstBlock);
@ -288,9 +296,7 @@ public class PrivacyReorgTest {
final Block secondBlock = final Block secondBlock =
gen.block( gen.block(
getBlockOptionsWithTransaction( getBlockOptionsWithTransaction(
firstBlock, firstBlock, privacyMarkerTransaction, secondBlockStateRoot));
buildMarkerTransaction(getEnclaveKey(enclave.clientUrl())),
secondBlockStateRoot));
appendBlock(besuController, blockchain, protocolContext, firstBlock); appendBlock(besuController, blockchain, protocolContext, firstBlock);
appendBlock(besuController, blockchain, protocolContext, secondBlock); appendBlock(besuController, blockchain, protocolContext, secondBlock);
@ -337,7 +343,7 @@ public class PrivacyReorgTest {
gen.block( gen.block(
getBlockOptionsWithTransaction( getBlockOptionsWithTransaction(
blockchain.getGenesisBlock(), blockchain.getGenesisBlock(),
buildMarkerTransaction(getEnclaveKey(enclave.clientUrl())), privacyMarkerTransaction,
FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT)); FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT));
appendBlock(besuController, blockchain, protocolContext, firstBlock); appendBlock(besuController, blockchain, protocolContext, firstBlock);
@ -384,7 +390,7 @@ public class PrivacyReorgTest {
gen.block( gen.block(
getBlockOptionsWithTransactionAndDifficulty( getBlockOptionsWithTransactionAndDifficulty(
secondForkBlock, secondForkBlock,
buildMarkerTransaction(getEnclaveKey(enclave.clientUrl())), privacyMarkerTransaction,
secondForkBlock.getHeader().getDifficulty().plus(10L), secondForkBlock.getHeader().getDifficulty().plus(10L),
thirdForkBlockStateRoot)); thirdForkBlockStateRoot));
@ -412,62 +418,6 @@ public class PrivacyReorgTest {
return new InMemoryPrivacyStorageProvider(); return new InMemoryPrivacyStorageProvider();
} }
private Bytes getEnclaveKey(final URI enclaveURI) {
final Enclave enclave = new EnclaveFactory(Vertx.vertx()).createVertxEnclave(enclaveURI);
final SendResponse sendResponse =
sendRequest(enclave, PRIVATE_TRANSACTION, ENCLAVE_PUBLIC_KEY.toBase64String());
final Bytes payload = Bytes.fromBase64String(sendResponse.getKey());
// If the key has 0 bytes generate a new key.
// This is to keep the gasUsed constant allowing
// hard-coded receipt roots in the block headers
for (int i = 0; i < payload.size(); i++) {
if (payload.get(i) == 0) {
return getEnclaveKey(enclaveURI);
}
}
return payload;
}
private SendResponse sendRequest(
final Enclave enclave,
final PrivateTransaction privateTransaction,
final String privacyUserId) {
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
privateTransaction.writeTo(rlpOutput);
final String payload = rlpOutput.encoded().toBase64String();
if (privateTransaction.getPrivacyGroupId().isPresent()) {
return enclave.send(
payload, privacyUserId, privateTransaction.getPrivacyGroupId().get().toBase64String());
} else {
final List<String> privateFor =
privateTransaction.getPrivateFor().get().stream()
.map(Bytes::toBase64String)
.collect(Collectors.toList());
if (privateFor.isEmpty()) {
privateFor.add(privateTransaction.getPrivateFrom().toBase64String());
}
return enclave.send(
payload, privateTransaction.getPrivateFrom().toBase64String(), privateFor);
}
}
private Transaction buildMarkerTransaction(final Bytes payload) {
return Transaction.builder()
.type(TransactionType.FRONTIER)
.chainId(BigInteger.valueOf(1337))
.gasLimit(60000)
.gasPrice(Wei.of(1000))
.nonce(0)
.payload(payload)
.to(DEFAULT_PRIVACY)
.value(Wei.ZERO)
.signAndBuild(KEY_PAIR);
}
private void assertPrivateStateRoot( private void assertPrivateStateRoot(
final PrivateStateRootResolver privateStateRootResolver, final PrivateStateRootResolver privateStateRootResolver,
final DefaultBlockchain blockchain, final DefaultBlockchain blockchain,

Loading…
Cancel
Save