From 3f0f3017e8223ae83e3d3045694a733887862ae6 Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Mon, 17 Feb 2020 11:58:23 +0000 Subject: [PATCH 1/7] Adds priv_getcode Signed-off-by: Joshua Richardson --- .../condition/ExpectValidContractCode.java | 29 ++++ .../condition/PrivateContractCondition.java | 4 +- .../condition/PrivateContractVerifier.java | 6 + ...loyPrivateSmartContractAcceptanceTest.java | 6 +- .../besu/ethereum/api/jsonrpc/RpcMethod.java | 1 + .../privacy/methods/priv/PrivGetCode.java | 93 +++++++++++ .../jsonrpc/methods/PrivJsonRpcMethods.java | 17 +- .../privacy/methods/priv/PrivGetCodeTest.java | 151 ++++++++++++++++++ 8 files changed, 295 insertions(+), 12 deletions(-) create mode 100644 acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java create mode 100644 ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java create mode 100644 ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java new file mode 100644 index 00000000000..8582ef6f34e --- /dev/null +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java @@ -0,0 +1,29 @@ +/* + * 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.tests.acceptance.dsl.privacy.condition; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.web3j.tx.Contract; + +public class ExpectValidContractCode implements PrivateContractCondition { + @Override + public void verify(final Contract contract) throws IOException { + assertThat(contract).isNotNull(); + assertThat(contract.isValid()).isEqualTo(true); + } +} diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java index b48a9fca049..fb49600564f 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java @@ -16,6 +16,8 @@ import org.web3j.tx.Contract; +import java.io.IOException; + public interface PrivateContractCondition { - void verify(final Contract contract); + void verify(final Contract contract) throws IOException; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java index 755b1339040..3382fb1f4e4 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java @@ -14,6 +14,8 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.privacy.condition; +import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; + public class PrivateContractVerifier { public PrivateContractVerifier() {} @@ -22,4 +24,8 @@ public ExpectValidPrivateContractDeployedReceipt validPrivateContractDeployed( final String contractAddress, final String senderAddress) { return new ExpectValidPrivateContractDeployedReceipt(contractAddress, senderAddress); } + + public ExpectValidContractCode validContractCodeProvided() { + return new ExpectValidContractCode(); + } } diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java index edbcc275b8e..6db5e9c6e18 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java @@ -21,6 +21,8 @@ import org.junit.Before; import org.junit.Test; +import java.io.IOException; + public class DeployPrivateSmartContractAcceptanceTest extends PrivacyAcceptanceTestBase { private static final long POW_CHAIN_ID = 2018; @@ -36,7 +38,7 @@ public void setUp() throws Exception { } @Test - public void deployingMustGiveValidReceipt() { + public void deployingMustGiveValidReceiptAndCode() throws Exception { final String contractAddress = "0x89ce396d0f9f937ddfa71113e29b2081c4869555"; final EventEmitter eventEmitter = @@ -50,5 +52,7 @@ public void deployingMustGiveValidReceipt() { privateContractVerifier .validPrivateContractDeployed(contractAddress, minerNode.getAddress().toString()) .verify(eventEmitter); + + privateContractVerifier.validContractCodeProvided().verify(eventEmitter); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java index ac115342ab7..acce6a1e31d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/RpcMethod.java @@ -46,6 +46,7 @@ public enum RpcMethod { PRIV_FIND_PRIVACY_GROUP("priv_findPrivacyGroup"), PRIV_DISTRIBUTE_RAW_TRANSACTION("priv_distributeRawTransaction"), PRIV_GET_EEA_TRANSACTION_COUNT("priv_getEeaTransactionCount"), + PRIV_GET_CODE("priv_getCode"), EEA_SEND_RAW_TRANSACTION("eea_sendRawTransaction"), ETH_ACCOUNTS("eth_accounts"), ETH_BLOCK_NUMBER("eth_blockNumber"), diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java new file mode 100644 index 00000000000..0c19f8872f8 --- /dev/null +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -0,0 +1,93 @@ +/* + * 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 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.JsonRpcMethod; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.BlockParameter; +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.core.Address; +import org.hyperledger.besu.ethereum.core.Hash; +import org.hyperledger.besu.ethereum.core.PrivacyParameters; +import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; + +import java.util.Optional; + +import org.apache.logging.log4j.Logger; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +public class PrivGetCode implements JsonRpcMethod { + + private static final Logger LOG = getLogger(); + + private final BlockchainQueries blockchain; + private final PrivateStateRootResolver privateStateRootResolver; + private final PrivacyParameters privacyParameters; + + public PrivGetCode( + final BlockchainQueries blockchain, + final PrivacyParameters privacyParameters, + final PrivateStateRootResolver privateStateRootResolver) { + this.privacyParameters = privacyParameters; + this.blockchain = blockchain; + this.privateStateRootResolver = privateStateRootResolver; + } + + @Override + public String getName() { + return RpcMethod.PRIV_GET_CODE.getMethodName(); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + LOG.trace("Executing {}", RpcMethod.PRIV_GET_CODE.getMethodName()); + + final Address address = + Address.fromHexString(requestContext.getRequiredParameter(0, String.class)); + + final BlockParameter blockParameter = + requestContext.getRequiredParameter(1, BlockParameter.class); + + final String privacyGroupString = requestContext.getRequiredParameter(2, String.class); + + final Bytes32 privacyGroupId = Bytes32.wrap(Bytes.fromBase64String(privacyGroupString)); + + final Hash latestStateRoot = + privateStateRootResolver.resolveLastStateRoot( + privacyGroupId, + blockParameter.isNumeric() && blockParameter.getNumber().isPresent() + ? blockchain + .getBlockchain() + .getBlockByNumber(blockParameter.getNumber().getAsLong()) + .orElseThrow() + .getHash() + : blockchain.getBlockchain().getChainHeadBlock().getHash()); + + return privacyParameters + .getPrivateWorldStateArchive() + .get(latestStateRoot) + .flatMap( + pws -> + Optional.ofNullable(pws.get(address)).map(account -> account.getCode().toString())) + .map(c -> new JsonRpcSuccessResponse(requestContext.getRequest().getId(), c)) + .orElse(new JsonRpcSuccessResponse(requestContext.getRequest().getId(), null)); + } +} diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java index ab9bac5462d..e3ad42b30e4 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java @@ -18,20 +18,13 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider; -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.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; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivacyPrecompileAddress; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivateTransaction; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetTransactionCount; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetTransactionReceipt; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.*; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.privacy.PrivacyController; +import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; import java.util.Map; @@ -68,6 +61,10 @@ protected Map create( new PrivGetPrivateTransaction( getBlockchainQueries(), privacyController, enclavePublicKeyProvider), new PrivDistributeRawTransaction(privacyController, enclavePublicKeyProvider), - new PrivCall(getBlockchainQueries(), privacyController, enclavePublicKeyProvider)); + new PrivCall(getBlockchainQueries(), privacyController, enclavePublicKeyProvider), + new PrivGetCode( + getBlockchainQueries(), + getPrivacyParameters(), + new PrivateStateRootResolver(getPrivacyParameters().getPrivateStateStorage()))); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java new file mode 100644 index 00000000000..7037e88fd8b --- /dev/null +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java @@ -0,0 +1,151 @@ +/* + * 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.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.crypto.SECP256K1; +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.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.chain.Blockchain; +import org.hyperledger.besu.ethereum.core.Account; +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.Wei; +import org.hyperledger.besu.ethereum.core.WorldState; +import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; +import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; +import org.hyperledger.besu.ethereum.privacy.Restriction; +import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; + +import java.math.BigInteger; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class PrivGetCodeTest { + + @Rule public final TemporaryFolder temp = new TemporaryFolder(); + + private final Address sender = + Address.fromHexString("0x0000000000000000000000000000000000000003"); + private static final SECP256K1.KeyPair KEY_PAIR = + SECP256K1.KeyPair.create( + SECP256K1.PrivateKey.create( + new BigInteger( + "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16))); + + private final Bytes privacyGroupId = + Bytes.fromBase64String("Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs="); + + private final PrivateTransaction.Builder privateTransactionBuilder = + PrivateTransaction.builder() + .nonce(0) + .gasPrice(Wei.of(1000)) + .gasLimit(3000000) + .to(null) + .value(Wei.ZERO) + .payload( + Bytes.fromBase64String( + "0x608060405234801561001057600080fd5b5060d08061001f60003960" + + "00f3fe60806040526004361060485763ffffffff7c01000000" + + "00000000000000000000000000000000000000000000000000" + + "60003504166360fe47b18114604d5780636d4ce63c14607557" + + "5b600080fd5b348015605857600080fd5b5060736004803603" + + "6020811015606d57600080fd5b50356099565b005b34801560" + + "8057600080fd5b506087609e565b6040805191825251908190" + + "0360200190f35b600055565b6000549056fea165627a7a7230" + + "5820cb1d0935d14b589300b12fcd0ab849a7e9019c81da24d6" + + "daa4f6b2f003d1b0180029")) + .sender(sender) + .chainId(BigInteger.valueOf(2018)) + .privateFrom(Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=")) + .restriction(Restriction.RESTRICTED); + + private PrivGetCode method; + + @Mock private BlockchainQueries mockBlockchainQueries; + @Mock private PrivacyParameters mockPrivacyParameters; + @Mock private Blockchain mockBlockchain; + @Mock private Block mockBlock; + @Mock private Hash mockHash; + @Mock private PrivateStateRootResolver mockResolver; + @Mock private WorldStateArchive mockArchive; + @Mock private WorldState mockWorldState; + @Mock private Account mockAccount; + + private final Hash lastStateRoot = + Hash.fromHexString("0x2121b68f1333e93bae8cd717a3ca68c9d7e7003f6b288c36dfc59b0f87be9590"); + + private final Bytes fakeAccountCode = Bytes.fromBase64String("ZXhhbXBsZQ=="); + + @Before + public void before() { + method = new PrivGetCode(mockBlockchainQueries, mockPrivacyParameters, mockResolver); + } + + @Test + public void returnValidCodeWhenCalledOnValidContract() { + PrivateTransaction transaction = + privateTransactionBuilder.privacyGroupId(privacyGroupId).signAndBuild(KEY_PAIR); + + Address resultantContractAddress = + Address.privateContractAddress( + transaction.getSender(), transaction.getNonce(), privacyGroupId); + + when(mockBlockchainQueries.getBlockchain()).thenReturn(mockBlockchain); + when(mockBlockchain.getChainHeadBlock()).thenReturn(mockBlock); + when(mockBlock.getHash()).thenReturn(mockHash); + when(mockResolver.resolveLastStateRoot(any(Bytes32.class), any(Hash.class))) + .thenReturn(lastStateRoot); + when(mockPrivacyParameters.getPrivateWorldStateArchive()).thenReturn(mockArchive); + when(mockArchive.get(lastStateRoot)).thenReturn(Optional.of(mockWorldState)); + when(mockWorldState.get(resultantContractAddress)).thenReturn(mockAccount); + when(mockAccount.getCode()).thenReturn(fakeAccountCode); + + final JsonRpcRequestContext request = + new JsonRpcRequestContext( + new JsonRpcRequest( + "2.0", + "priv_getCode", + new Object[] { + resultantContractAddress.toHexString(), + "latest", + "Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=" + })); + + final JsonRpcResponse response = method.response(request); + + assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class); + assertThat(fakeAccountCode.toString()) + .isEqualTo(((JsonRpcSuccessResponse) response).getResult()); + } +} From a592da14144efb058e24b5c33bd3ce5bcab4d2d4 Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Mon, 17 Feb 2020 11:59:21 +0000 Subject: [PATCH 2/7] Spotless Signed-off-by: Joshua Richardson --- .../dsl/privacy/condition/ExpectValidContractCode.java | 10 +++++----- .../privacy/condition/PrivateContractCondition.java | 4 ++-- .../dsl/privacy/condition/PrivateContractVerifier.java | 2 -- .../DeployPrivateSmartContractAcceptanceTest.java | 2 -- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java index 8582ef6f34e..574ace120da 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/ExpectValidContractCode.java @@ -21,9 +21,9 @@ import org.web3j.tx.Contract; public class ExpectValidContractCode implements PrivateContractCondition { - @Override - public void verify(final Contract contract) throws IOException { - assertThat(contract).isNotNull(); - assertThat(contract.isValid()).isEqualTo(true); - } + @Override + public void verify(final Contract contract) throws IOException { + assertThat(contract).isNotNull(); + assertThat(contract.isValid()).isEqualTo(true); + } } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java index fb49600564f..7969e2d3576 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractCondition.java @@ -14,10 +14,10 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.privacy.condition; -import org.web3j.tx.Contract; - import java.io.IOException; +import org.web3j.tx.Contract; + public interface PrivateContractCondition { void verify(final Contract contract) throws IOException; } diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java index 3382fb1f4e4..de9f36d08d7 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/condition/PrivateContractVerifier.java @@ -14,8 +14,6 @@ */ package org.hyperledger.besu.tests.acceptance.dsl.privacy.condition; -import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode; - public class PrivateContractVerifier { public PrivateContractVerifier() {} diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java index 6db5e9c6e18..57858c423d9 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/privacy/DeployPrivateSmartContractAcceptanceTest.java @@ -21,8 +21,6 @@ import org.junit.Before; import org.junit.Test; -import java.io.IOException; - public class DeployPrivateSmartContractAcceptanceTest extends PrivacyAcceptanceTestBase { private static final long POW_CHAIN_ID = 2018; From 654d1b796f9f16d52d64da40e4196277cffae4ff Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Mon, 17 Feb 2020 12:31:23 +0000 Subject: [PATCH 3/7] imports Signed-off-by: Joshua Richardson --- .../api/jsonrpc/methods/PrivJsonRpcMethods.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java index e3ad42b30e4..fe168643cc3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java @@ -18,7 +18,16 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.EnclavePublicKeyProvider; -import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.*; +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.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; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetCode; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivacyPrecompileAddress; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetPrivateTransaction; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetTransactionCount; +import org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv.PrivGetTransactionReceipt; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.eth.transactions.TransactionPool; From 523a4491f7ff6788f50e679e5380951323d67ef4 Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Fri, 21 Feb 2020 11:22:11 +0000 Subject: [PATCH 4/7] Addresses PR comments Signed-off-by: Joshua Richardson --- CHANGELOG.md | 1 + .../privacy/methods/priv/PrivGetCode.java | 61 ++++++++----------- .../jsonrpc/methods/PrivJsonRpcMethods.java | 2 +- .../privacy/methods/priv/PrivGetCodeTest.java | 22 +++---- 4 files changed, 36 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72837156174..918a80d177f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## 1.4.1 +- Added priv_getCode [\#250](https://github.com/hyperledger/besu/pull/408). Gets the bytecode associated with a private address. ### Bug Fixes diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 0c19f8872f8..4f7fe9566e3 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -14,40 +14,36 @@ */ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.privacy.methods.priv; -import static org.apache.logging.log4j.LogManager.getLogger; - 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.JsonRpcMethod; +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.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.core.Address; import org.hyperledger.besu.ethereum.core.Hash; -import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; +import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import java.util.Optional; -import org.apache.logging.log4j.Logger; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -public class PrivGetCode implements JsonRpcMethod { - - private static final Logger LOG = getLogger(); +public class PrivGetCode extends AbstractBlockParameterMethod { private final BlockchainQueries blockchain; private final PrivateStateRootResolver privateStateRootResolver; - private final PrivacyParameters privacyParameters; + private final WorldStateArchive privateWorldStateArchive; public PrivGetCode( - final BlockchainQueries blockchain, - final PrivacyParameters privacyParameters, + final BlockchainQueries blockchainQueries, + final WorldStateArchive privateWorldStateArchive, final PrivateStateRootResolver privateStateRootResolver) { - this.privacyParameters = privacyParameters; - this.blockchain = blockchain; + super(blockchainQueries); + this.privateWorldStateArchive = privateWorldStateArchive; + this.blockchain = blockchainQueries; this.privateStateRootResolver = privateStateRootResolver; } @@ -57,37 +53,32 @@ public String getName() { } @Override - public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { - LOG.trace("Executing {}", RpcMethod.PRIV_GET_CODE.getMethodName()); - - final Address address = - Address.fromHexString(requestContext.getRequiredParameter(0, String.class)); - - final BlockParameter blockParameter = - requestContext.getRequiredParameter(1, BlockParameter.class); + protected BlockParameter blockParameter(JsonRpcRequestContext request) { + return request.getRequiredParameter(2, BlockParameter.class); + } - final String privacyGroupString = requestContext.getRequiredParameter(2, String.class); + @Override + protected Object resultByBlockNumber(JsonRpcRequestContext request, long blockNumber) { + final String privacyGroupId = request.getRequiredParameter(0, String.class); - final Bytes32 privacyGroupId = Bytes32.wrap(Bytes.fromBase64String(privacyGroupString)); + final Address address = Address.fromHexString(request.getRequiredParameter(1, String.class)); final Hash latestStateRoot = privateStateRootResolver.resolveLastStateRoot( - privacyGroupId, - blockParameter.isNumeric() && blockParameter.getNumber().isPresent() - ? blockchain - .getBlockchain() - .getBlockByNumber(blockParameter.getNumber().getAsLong()) - .orElseThrow() - .getHash() - : blockchain.getBlockchain().getChainHeadBlock().getHash()); + Bytes32.wrap(Bytes.fromBase64String(privacyGroupId)), + blockchain.getBlockchain().getBlockByNumber(blockNumber).orElseThrow().getHash()); - return privacyParameters - .getPrivateWorldStateArchive() + return privateWorldStateArchive .get(latestStateRoot) .flatMap( pws -> Optional.ofNullable(pws.get(address)).map(account -> account.getCode().toString())) - .map(c -> new JsonRpcSuccessResponse(requestContext.getRequest().getId(), c)) - .orElse(new JsonRpcSuccessResponse(requestContext.getRequest().getId(), null)); + .map(c -> new JsonRpcSuccessResponse(request.getRequest().getId(), c)) + .orElse(new JsonRpcSuccessResponse(request.getRequest().getId(), null)); + } + + @Override + public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { + return (JsonRpcResponse) findResultByParamType(requestContext); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java index fe168643cc3..7cfdada586e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/methods/PrivJsonRpcMethods.java @@ -73,7 +73,7 @@ protected Map create( new PrivCall(getBlockchainQueries(), privacyController, enclavePublicKeyProvider), new PrivGetCode( getBlockchainQueries(), - getPrivacyParameters(), + getPrivacyParameters().getPrivateWorldStateArchive(), new PrivateStateRootResolver(getPrivacyParameters().getPrivateStateStorage()))); } } diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java index 7037e88fd8b..141e632421e 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java @@ -25,13 +25,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.core.Account; -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.Wei; -import org.hyperledger.besu.ethereum.core.WorldState; +import org.hyperledger.besu.ethereum.core.*; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; import org.hyperledger.besu.ethereum.privacy.Restriction; @@ -43,9 +37,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @@ -53,8 +45,6 @@ @RunWith(MockitoJUnitRunner.class) public class PrivGetCodeTest { - @Rule public final TemporaryFolder temp = new TemporaryFolder(); - private final Address sender = Address.fromHexString("0x0000000000000000000000000000000000000003"); private static final SECP256K1.KeyPair KEY_PAIR = @@ -109,7 +99,11 @@ public class PrivGetCodeTest { @Before public void before() { - method = new PrivGetCode(mockBlockchainQueries, mockPrivacyParameters, mockResolver); + method = + new PrivGetCode( + mockBlockchainQueries, + mockPrivacyParameters.getPrivateWorldStateArchive(), + mockResolver); } @Test @@ -145,7 +139,7 @@ public void returnValidCodeWhenCalledOnValidContract() { final JsonRpcResponse response = method.response(request); assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class); - assertThat(fakeAccountCode.toString()) - .isEqualTo(((JsonRpcSuccessResponse) response).getResult()); + assertThat(((JsonRpcSuccessResponse) response).getResult()) + .isEqualTo(fakeAccountCode.toString()); } } From 2ec4fb5a96dcba0cdc36a9e0d196698ef29a1552 Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Fri, 21 Feb 2020 14:35:04 +0000 Subject: [PATCH 5/7] Bumps web3j version Signed-off-by: Joshua Richardson --- gradle/versions.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/versions.gradle b/gradle/versions.gradle index df1c6865703..3b971e2eef0 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -95,10 +95,10 @@ dependencyManagement { dependency 'org.springframework.security:spring-security-crypto:5.2.1.RELEASE' - dependency 'org.web3j:abi:4.5.11' - dependency 'org.web3j:besu:4.5.11' - dependency 'org.web3j:core:4.5.11' - dependency 'org.web3j:crypto:4.5.11' + dependency 'org.web3j:abi:4.5.15' + dependency 'org.web3j:besu:4.5.15' + dependency 'org.web3j:core:4.5.15' + dependency 'org.web3j:crypto:4.5.15' dependency 'org.xerial.snappy:snappy-java:1.1.7.3' From 3a7707be67b57a26cab3e520666d4bccb448410a Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Sat, 22 Feb 2020 11:39:39 +0000 Subject: [PATCH 6/7] Fixes compilation issue Signed-off-by: Joshua Richardson --- .../jsonrpc/internal/privacy/methods/priv/PrivGetCode.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java index 4f7fe9566e3..8c1a7a946aa 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCode.java @@ -53,12 +53,13 @@ public String getName() { } @Override - protected BlockParameter blockParameter(JsonRpcRequestContext request) { + protected BlockParameter blockParameter(final JsonRpcRequestContext request) { return request.getRequiredParameter(2, BlockParameter.class); } @Override - protected Object resultByBlockNumber(JsonRpcRequestContext request, long blockNumber) { + protected Object resultByBlockNumber( + final JsonRpcRequestContext request, final long blockNumber) { final String privacyGroupId = request.getRequiredParameter(0, String.class); final Address address = Address.fromHexString(request.getRequiredParameter(1, String.class)); From 235d9508c1cf3daa8ac7ec5cde66dc314b3c666a Mon Sep 17 00:00:00 2001 From: Joshua Richardson Date: Mon, 24 Feb 2020 09:33:41 +0000 Subject: [PATCH 7/7] Param ordering Signed-off-by: Joshua Richardson --- .../privacy/methods/priv/PrivGetCodeTest.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java index 141e632421e..c3dec0dc3d8 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/privacy/methods/priv/PrivGetCodeTest.java @@ -25,7 +25,13 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; import org.hyperledger.besu.ethereum.api.query.BlockchainQueries; import org.hyperledger.besu.ethereum.chain.Blockchain; -import org.hyperledger.besu.ethereum.core.*; +import org.hyperledger.besu.ethereum.core.Account; +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.Wei; +import org.hyperledger.besu.ethereum.core.WorldState; import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver; import org.hyperledger.besu.ethereum.privacy.PrivateTransaction; import org.hyperledger.besu.ethereum.privacy.Restriction; @@ -131,9 +137,9 @@ public void returnValidCodeWhenCalledOnValidContract() { "2.0", "priv_getCode", new Object[] { + "Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=", resultantContractAddress.toHexString(), - "latest", - "Ko2bVqD+nNlNYL5EE7y3IdOnviftjiizpjRt+HTuFBs=" + "latest" })); final JsonRpcResponse response = method.response(request);