Implemented priv_debugGetStateRoot JSON RPC API. (#1326)

* Implemented priv_debugGetStateRoot JSON RPC API.

Signed-off-by: Mark Terry <mark.terry@consensys.net>
pull/1343/head
mark-terry 4 years ago committed by GitHub
parent b0cdf665d7
commit 2691deb126
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      CHANGELOG.md
  2. 2
      ethereum/api/src/integration-test/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivGetPrivateTransactionIntegrationTest.java
  3. 1
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java
  4. 96
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRoot.java
  5. 90
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java
  6. 132
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivDebugGetStateRootTest.java
  7. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/DefaultPrivacyController.java
  8. 12
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/MultiTenancyPrivacyController.java
  9. 22
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/OnchainPrivacyGroupContract.java
  10. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/privacy/PrivacyController.java
  11. 10
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/DefaultPrivacyControllerTest.java
  12. 7
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/privacy/MultiTenancyPrivacyControllerOnchainTest.java

@ -1,12 +1,16 @@
# Changelog
### Additions and Improvements
* Added `priv_debugGetStateRoot` JSON-RPC API to retrieve the state root of a specified privacy group. [\#1326](https://github.com/hyperledger/besu/pull/1326)
## 1.5.3
### Additions and Improvements
* The EvmTool now processes State Tests from the Ethereum Reference Tests. [\#1311](https://github.com/hyperledger/besu/pull/1311)
* Experimental dns support added via the `Xdns-enabled` and `Xdns-update-enabled` CLI commands. [\#1247](https://github.com/hyperledger/besu/pull/1247)
* Add genesis config option `ecip1017EraRounds` for Ethereum Classic chanis. [\#1329](https://github.com/hyperledger/besu/pull/1329)
* Add genesis config option `ecip1017EraRounds` for Ethereum Classic chains. [\#1329](https://github.com/hyperledger/besu/pull/1329)
### Bug Fixes

@ -132,7 +132,7 @@ public class PrivGetPrivateTransactionIntegrationTest {
privacyController =
new DefaultPrivacyController(
blockchain, privateStateStorage, enclave, null, null, null, null, null);
blockchain, privateStateStorage, enclave, null, null, null, null, null, null);
}
@After

@ -46,6 +46,7 @@ public enum RpcMethod {
PRIV_CREATE_PRIVACY_GROUP("priv_createPrivacyGroup"),
PRIV_DELETE_PRIVACY_GROUP("priv_deletePrivacyGroup"),
PRIV_FIND_PRIVACY_GROUP("priv_findPrivacyGroup"),
PRIV_DEBUG_GET_STATE_ROOT("priv_debugGetStateRoot"),
PRIV_DISTRIBUTE_RAW_TRANSACTION("priv_distributeRawTransaction"),
PRIV_GET_EEA_TRANSACTION_COUNT("priv_getEeaTransactionCount"),
PRIV_GET_CODE("priv_getCode"),

@ -0,0 +1,96 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import static org.apache.logging.log4j.LogManager.getLogger;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.FIND_PRIVACY_GROUP_ERROR;
import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.AbstractBlockParameterMethod;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import java.util.Collections;
import org.apache.logging.log4j.Logger;
public class PrivDebugGetStateRoot extends AbstractBlockParameterMethod {
private static final Logger LOG = getLogger();
private final EnclavePublicKeyProvider enclavePublicKeyProvider;
private final PrivacyController privacyController;
public PrivDebugGetStateRoot(
final BlockchainQueries blockchainQueries,
final EnclavePublicKeyProvider enclavePublicKeyProvider,
final PrivacyController privacyController) {
super(blockchainQueries);
this.enclavePublicKeyProvider = enclavePublicKeyProvider;
this.privacyController = privacyController;
}
@Override
public String getName() {
return RpcMethod.PRIV_DEBUG_GET_STATE_ROOT.getMethodName();
}
@Override
protected BlockParameter blockParameter(final JsonRpcRequestContext request) {
return request.getRequiredParameter(1, BlockParameter.class);
}
@Override
protected Object resultByBlockNumber(
final JsonRpcRequestContext requestContext, final long blockNumber) {
final String privacyGroupId = requestContext.getRequiredParameter(0, String.class);
final String enclavePublicKey =
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser());
LOG.trace("Executing {}", this::getName);
final PrivacyGroup[] privacyGroups =
privacyController.findPrivacyGroup(
Collections.singletonList(privacyGroupId),
enclavePublicKeyProvider.getEnclaveKey(requestContext.getUser()));
if (privacyGroups.length == 0) {
LOG.error("Failed to fetch privacy group");
return new JsonRpcErrorResponse(
requestContext.getRequest().getId(), FIND_PRIVACY_GROUP_ERROR);
}
return privacyController
.getStateRootByBlockNumber(privacyGroupId, enclavePublicKey, blockNumber)
.<JsonRpcResponse>map(
stateRootHash ->
new JsonRpcSuccessResponse(requestContext.getRequest().getId(), stateRootHash))
.orElse(
new JsonRpcErrorResponse(
requestContext.getRequest().getId(), JsonRpcError.INVALID_PARAMS));
}
@Override
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) {
return (JsonRpcResponse) findResultByParamType(requestContext);
}
}

@ -24,6 +24,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivGe
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.PrivUninstallFilter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivCall;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivCreatePrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDebugGetStateRoot;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDeletePrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivDistributeRawTransaction;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivFindPrivacyGroup;
@ -65,57 +66,44 @@ public class PrivJsonRpcMethods extends PrivacyApiGroupJsonRpcMethods {
protected Map<String, JsonRpcMethod> create(
final PrivacyController privacyController,
final EnclavePublicKeyProvider enclavePublicKeyProvider) {
if (getPrivacyParameters().isOnchainPrivacyGroupsEnabled()) {
return mapOf(
new PrivGetTransactionReceipt(
getPrivacyParameters().getPrivateStateStorage(),
privacyController,
enclavePublicKeyProvider),
new PrivGetPrivacyPrecompileAddress(getPrivacyParameters()),
new PrivGetTransactionCount(privacyController, enclavePublicKeyProvider),
new PrivGetPrivateTransaction(privacyController, enclavePublicKeyProvider),
new PrivDistributeRawTransaction(
privacyController,
enclavePublicKeyProvider,
getPrivacyParameters().isOnchainPrivacyGroupsEnabled()),
new PrivCall(getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivGetCode(getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivGetLogs(
getBlockchainQueries(),
getPrivacyQueries(),
privacyController,
enclavePublicKeyProvider),
new PrivNewFilter(filterManager, privacyController, enclavePublicKeyProvider),
new PrivUninstallFilter(filterManager, privacyController, enclavePublicKeyProvider),
new PrivGetFilterLogs(filterManager, privacyController, enclavePublicKeyProvider),
new PrivGetFilterChanges(filterManager, privacyController, enclavePublicKeyProvider));
} else {
return mapOf(
new PrivGetTransactionReceipt(
getPrivacyParameters().getPrivateStateStorage(),
privacyController,
enclavePublicKeyProvider),
new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivDeletePrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivFindPrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivGetPrivacyPrecompileAddress(getPrivacyParameters()),
new PrivGetTransactionCount(privacyController, enclavePublicKeyProvider),
new PrivGetPrivateTransaction(privacyController, enclavePublicKeyProvider),
new PrivDistributeRawTransaction(
privacyController,
enclavePublicKeyProvider,
getPrivacyParameters().isOnchainPrivacyGroupsEnabled()),
new PrivCall(getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivGetCode(getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivGetLogs(
getBlockchainQueries(),
getPrivacyQueries(),
privacyController,
enclavePublicKeyProvider),
new PrivNewFilter(filterManager, privacyController, enclavePublicKeyProvider),
new PrivUninstallFilter(filterManager, privacyController, enclavePublicKeyProvider),
new PrivGetFilterLogs(filterManager, privacyController, enclavePublicKeyProvider),
new PrivGetFilterChanges(filterManager, privacyController, enclavePublicKeyProvider));
final Map<String, JsonRpcMethod> RPC_METHODS =
mapOf(
new PrivCall(getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivDebugGetStateRoot(
getBlockchainQueries(), enclavePublicKeyProvider, privacyController),
new PrivDistributeRawTransaction(
privacyController,
enclavePublicKeyProvider,
getPrivacyParameters().isOnchainPrivacyGroupsEnabled()),
new PrivGetCode(getBlockchainQueries(), privacyController, enclavePublicKeyProvider),
new PrivGetLogs(
getBlockchainQueries(),
getPrivacyQueries(),
privacyController,
enclavePublicKeyProvider),
new PrivGetPrivateTransaction(privacyController, enclavePublicKeyProvider),
new PrivGetPrivacyPrecompileAddress(getPrivacyParameters()),
new PrivGetTransactionCount(privacyController, enclavePublicKeyProvider),
new PrivGetTransactionReceipt(
getPrivacyParameters().getPrivateStateStorage(),
privacyController,
enclavePublicKeyProvider),
new PrivGetFilterLogs(filterManager, privacyController, enclavePublicKeyProvider),
new PrivGetFilterChanges(filterManager, privacyController, enclavePublicKeyProvider),
new PrivNewFilter(filterManager, privacyController, enclavePublicKeyProvider),
new PrivUninstallFilter(filterManager, privacyController, enclavePublicKeyProvider));
if (!getPrivacyParameters().isOnchainPrivacyGroupsEnabled()) {
final Map<String, JsonRpcMethod> OFFCHAIN_METHODS =
mapOf(
new PrivCreatePrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivDeletePrivacyGroup(privacyController, enclavePublicKeyProvider),
new PrivFindPrivacyGroup(privacyController, enclavePublicKeyProvider));
OFFCHAIN_METHODS.forEach(
(key, jsonRpcMethod) ->
RPC_METHODS.merge(key, jsonRpcMethod, (oldVal, newVal) -> newVal));
}
return RPC_METHODS;
}
}

@ -0,0 +1,132 @@
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.FIND_PRIVACY_GROUP_ERROR;
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_PARAMS;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.exception.InvalidJsonRpcParameters;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponseType;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.privacy.DefaultPrivacyController;
import org.hyperledger.besu.ethereum.privacy.PrivacyController;
import java.util.Collections;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
public class PrivDebugGetStateRootTest {
private static final String ENCLAVE_PUBLIC_KEY = "A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final PrivacyGroup PRIVACY_GROUP =
new PrivacyGroup(
"1",
PrivacyGroup.Type.LEGACY,
"group",
"Test group",
Collections.singletonList(ENCLAVE_PUBLIC_KEY));
private PrivDebugGetStateRoot method;
private final EnclavePublicKeyProvider enclavePublicKeyProvider = (user) -> ENCLAVE_PUBLIC_KEY;
private final BlockchainQueries blockchainQueries = mock(BlockchainQueries.class);
private final PrivacyController privacyController = mock(DefaultPrivacyController.class);
@Before
public void setUp() {
method =
new PrivDebugGetStateRoot(blockchainQueries, enclavePublicKeyProvider, privacyController);
}
@Test
public void shouldReturnCorrectMethodName() {
assertThat(method.getName()).isEqualTo("priv_debugGetStateRoot");
}
@Test
public void shouldThrowInvalidJsonRpcParametersExceptionWhenNoPrivacyGroup() {
final JsonRpcRequestContext request = request(null, "latest");
final Throwable thrown = catchThrowable(() -> method.response(request));
assertThat(thrown)
.isInstanceOf(InvalidJsonRpcParameters.class)
.hasNoCause()
.hasMessage("Missing required json rpc parameter at index 0");
}
@Test
public void shouldReturnErrorIfPrivacyGroupDoesNotExist() {
when(privacyController.findPrivacyGroup(anyList(), anyString()))
.thenReturn(new PrivacyGroup[] {});
final JsonRpcResponse response = method.response(request("invalid_group", "latest"));
assertThat(response.getType()).isEqualByComparingTo(JsonRpcResponseType.ERROR);
assertThat(((JsonRpcErrorResponse) response).getError().getMessage())
.contains(FIND_PRIVACY_GROUP_ERROR.getMessage());
}
@Test
public void shouldReturnErrorIfUnableToFindStateRoot() {
when(privacyController.findPrivacyGroup(anyList(), anyString()))
.thenReturn(new PrivacyGroup[] {PRIVACY_GROUP});
when(privacyController.getStateRootByBlockNumber(anyString(), anyString(), anyLong()))
.thenReturn(Optional.empty());
final JsonRpcErrorResponse response =
(JsonRpcErrorResponse) method.response(request(ENCLAVE_PUBLIC_KEY, "latest"));
assertThat(response.getError().getMessage()).contains(INVALID_PARAMS.getMessage());
}
@Test
public void shouldReturnSuccessWhenValidPrivacyGroupAndStateRoot() {
final Hash hash = Hash.EMPTY_LIST_HASH;
when(privacyController.findPrivacyGroup(anyList(), anyString()))
.thenReturn(new PrivacyGroup[] {PRIVACY_GROUP});
when(privacyController.getStateRootByBlockNumber(anyString(), anyString(), anyLong()))
.thenReturn(Optional.of(hash));
final JsonRpcSuccessResponse response =
(JsonRpcSuccessResponse) method.response(request(ENCLAVE_PUBLIC_KEY, "latest"));
final Hash result = (Hash) response.getResult();
assertThat(result).isEqualTo(hash);
}
private JsonRpcRequestContext request(final String privacyGroupId, final String params) {
return new JsonRpcRequestContext(
new JsonRpcRequest(
"2.0", method.getName(), new Object[] {privacyGroupId, new BlockParameter(params)}));
}
}

@ -25,7 +25,6 @@ import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.enclave.types.SendResponse;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Transaction;
@ -70,6 +69,7 @@ public class DefaultPrivacyController implements PrivacyController {
private final PrivateNonceProvider privateNonceProvider;
private final PrivateWorldStateReader privateWorldStateReader;
private final PrivateTransactionLocator privateTransactionLocator;
private final PrivateStateRootResolver privateStateRootResolver;
public DefaultPrivacyController(
final Blockchain blockchain,
@ -87,7 +87,8 @@ public class DefaultPrivacyController implements PrivacyController {
privateMarkerTransactionFactory,
privateTransactionSimulator,
privateNonceProvider,
privateWorldStateReader);
privateWorldStateReader,
privacyParameters.getPrivateStateRootResolver());
}
public DefaultPrivacyController(
@ -98,7 +99,8 @@ public class DefaultPrivacyController implements PrivacyController {
final PrivateMarkerTransactionFactory privateMarkerTransactionFactory,
final PrivateTransactionSimulator privateTransactionSimulator,
final PrivateNonceProvider privateNonceProvider,
final PrivateWorldStateReader privateWorldStateReader) {
final PrivateWorldStateReader privateWorldStateReader,
final PrivateStateRootResolver privateStateRootResolver) {
this.blockchain = blockchain;
this.privateStateStorage = privateStateStorage;
this.enclave = enclave;
@ -109,6 +111,7 @@ public class DefaultPrivacyController implements PrivacyController {
this.privateWorldStateReader = privateWorldStateReader;
this.privateTransactionLocator =
new PrivateTransactionLocator(blockchain, enclave, privateStateStorage);
this.privateStateRootResolver = privateStateRootResolver;
}
@Override
@ -543,8 +546,13 @@ public class DefaultPrivacyController implements PrivacyController {
}
@Override
public Optional<Hash> getBlockHashByBlockNumber(final Optional<Long> blockNumber) {
return blockNumber.flatMap(
blockNum -> blockchain.getBlockByNumber(blockNum).map(Block::getHash));
public Optional<Hash> getStateRootByBlockNumber(
final String privacyGroupId, final String enclavePublicKey, final long blockNumber) {
return blockchain
.getBlockByNumber(blockNumber)
.map(
block ->
privateStateRootResolver.resolveLastStateRoot(
Bytes32.wrap(Bytes.fromBase64String(privacyGroupId)), block.getHash()));
}
}

@ -265,9 +265,7 @@ public class MultiTenancyPrivacyController implements PrivacyController {
final PrivacyGroup privacyGroup =
onchainPrivacyGroupContract
.flatMap(
contract ->
contract.getPrivacyGroup(
privacyGroupId, getBlockHashByBlockNumber(blockNumber)))
contract -> contract.getPrivacyGroupByIdAndBlockNumber(privacyGroupId, blockNumber))
.orElse(enclave.retrievePrivacyGroup(privacyGroupId));
if (!privacyGroup.getMembers().contains(enclavePublicKey)) {
@ -282,7 +280,11 @@ public class MultiTenancyPrivacyController implements PrivacyController {
}
@Override
public Optional<Hash> getBlockHashByBlockNumber(final Optional<Long> blockNumber) {
return privacyController.getBlockHashByBlockNumber(blockNumber);
public Optional<Hash> getStateRootByBlockNumber(
final String privacyGroupId, final String enclavePublicKey, final long blockNumber) {
verifyPrivacyGroupContainsEnclavePublicKey(
privacyGroupId, enclavePublicKey, Optional.of(blockNumber));
return privacyController.getStateRootByBlockNumber(
privacyGroupId, enclavePublicKey, blockNumber);
}
}

@ -47,19 +47,35 @@ public class OnchainPrivacyGroupContract {
this.privateTransactionSimulator = privateTransactionSimulator;
}
public Optional<PrivacyGroup> getPrivacyGroup(
public Optional<PrivacyGroup> getPrivacyGroupById(final String privacyGroupId) {
return getPrivacyGroup(privacyGroupId, Optional.empty(), Optional.empty());
}
public Optional<PrivacyGroup> getPrivacyGroupByIdAndBlockNumber(
final String privacyGroupId, final Optional<Long> blockNumber) {
return getPrivacyGroup(privacyGroupId, Optional.empty(), blockNumber);
}
public Optional<PrivacyGroup> getPrivacyGroupByIdAndBlockHash(
final String privacyGroupId, final Optional<Hash> blockHash) {
return getPrivacyGroup(privacyGroupId, blockHash, Optional.empty());
}
private Optional<PrivacyGroup> getPrivacyGroup(
final String privacyGroupId,
final Optional<Hash> blockHash,
final Optional<Long> blockNumber) {
final CallParameter callParams = buildCallParams(GET_PARTICIPANTS_METHOD_SIGNATURE);
final Optional<PrivateTransactionProcessor.Result> result;
if (blockHash.isPresent()) {
result = privateTransactionSimulator.process(privacyGroupId, callParams, blockHash.get());
} else if (blockNumber.isPresent()) {
result = privateTransactionSimulator.process(privacyGroupId, callParams, blockNumber.get());
} else {
result = privateTransactionSimulator.process(privacyGroupId, callParams);
}
return readPrivacyGroupFromResult(privacyGroupId, result);
}

@ -100,5 +100,6 @@ public interface PrivacyController {
PrivateTransactionSimulator getTransactionSimulator();
Optional<Hash> getBlockHashByBlockNumber(Optional<Long> blockNumber);
Optional<Hash> getStateRootByBlockNumber(
final String privacyGroupId, final String enclavePublicKey, final long blockNumber);
}

@ -98,8 +98,9 @@ public class DefaultPrivacyControllerTest {
private Enclave enclave;
private String enclavePublicKey;
private PrivateNonceProvider privateNonceProvider;
private PrivateWorldStateReader privateWorldStateReader;
private PrivateStateRootResolver privateStateRootResolver;
private PrivateTransactionSimulator privateTransactionSimulator;
private PrivateWorldStateReader privateWorldStateReader;
private Blockchain blockchain;
private PrivateStateStorage privateStateStorage;
@ -145,6 +146,7 @@ public class DefaultPrivacyControllerTest {
privateTransactionSimulator = mock(PrivateTransactionSimulator.class);
privateStateStorage = mock(PrivateStateStorage.class);
privateNonceProvider = mock(ChainHeadPrivateNonceProvider.class);
privateStateRootResolver = mock(PrivateStateRootResolver.class);
when(privateNonceProvider.getNonce(any(), any())).thenReturn(1L);
privateWorldStateReader = mock(PrivateWorldStateReader.class);
@ -163,7 +165,8 @@ public class DefaultPrivacyControllerTest {
Address.DEFAULT_PRIVACY, (address) -> 0, KEY_PAIR),
privateTransactionSimulator,
privateNonceProvider,
privateWorldStateReader);
privateWorldStateReader,
privateStateRootResolver);
brokenPrivacyController =
new DefaultPrivacyController(
blockchain,
@ -174,7 +177,8 @@ public class DefaultPrivacyControllerTest {
Address.DEFAULT_PRIVACY, (address) -> 0, KEY_PAIR),
privateTransactionSimulator,
privateNonceProvider,
privateWorldStateReader);
privateWorldStateReader,
privateStateRootResolver);
}
@Test

@ -22,7 +22,6 @@ import static org.mockito.Mockito.when;
import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Log;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
@ -66,15 +65,12 @@ public class MultiTenancyPrivacyControllerOnchainTest {
@Test
public void simulatePrivateTransactionSucceedsForPresentEnclaveKey() {
final Optional<Hash> blockHash = Optional.of(mock(Hash.class));
when(enclave.retrievePrivacyGroup(PRIVACY_GROUP_ID)).thenReturn(ONCHAIN_PRIVACY_GROUP);
when(privacyController.simulatePrivateTransaction(any(), any(), any(), any(long.class)))
.thenReturn(
Optional.of(
PrivateTransactionProcessor.Result.successful(
LOGS, 0, 0, Bytes.EMPTY, ValidationResult.valid())));
when(privacyController.getBlockHashByBlockNumber(any())).thenReturn(blockHash);
final Optional<PrivateTransactionProcessor.Result> result =
multiTenancyPrivacyController.simulatePrivateTransaction(
PRIVACY_GROUP_ID,
@ -88,10 +84,7 @@ public class MultiTenancyPrivacyControllerOnchainTest {
@Test(expected = MultiTenancyValidationException.class)
public void simulatePrivateTransactionFailsForAbsentEnclaveKey() {
final Optional<Hash> blockHash = Optional.of(mock(Hash.class));
when(enclave.retrievePrivacyGroup(PRIVACY_GROUP_ID)).thenReturn(ONCHAIN_PRIVACY_GROUP);
when(privacyController.getBlockHashByBlockNumber(any())).thenReturn(blockHash);
multiTenancyPrivacyController.simulatePrivateTransaction(
PRIVACY_GROUP_ID,

Loading…
Cancel
Save