Skip to content

Commit

Permalink
Merge branch 'master' of github.com:hyperledger/besu into httpservice…
Browse files Browse the repository at this point in the history
…-null-method
  • Loading branch information
Christopher Hare committed Oct 3, 2019
2 parents 709ddc6 + fae2873 commit 5d4f70d
Show file tree
Hide file tree
Showing 23 changed files with 826 additions and 251 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ From v1.2, Besu requires Java 11. Besu on Java 8 is no longer supported.
In v1.2, we removed the entry-point script from our Docker image. Refer to the [migration guide](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/Migration-Docker/)
for information on options that were previously automatically added to the Besu command line.

### 1.3 RC
### 1.3

### Breaking Change

Expand All @@ -26,6 +26,11 @@ for information on options that were previously automatically added to the Besu
- Added [`retesteth`](https://besu.hyperledger.org/en/latest/Reference/CLI/CLI-Subcommands/#retesteth) subcommand
- Added [`debug_accountRange`](https://besu.hyperledger.org/en/latest/Reference/API-Methods/#debug_accountrange) JSON-RPC API method
- Clarified purpose of [static nodes](https://besu.hyperledger.org/en/latest/HowTo/Find-and-Connect/Managing-Peers/#static-nodes)
- Added links [Kubernetes reference implementations](https://besu.hyperledger.org/en/latest/HowTo/Deploy/Kubernetes/)
- Added content about [access between private and public states](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Groups/#access-between-states)
- Added restriction that [account permissioning cannot be used with random key signing](https://besu.hyperledger.org/en/latest/HowTo/Use-Privacy/Sign-Privacy-Marker-Transactions/).
- Added high availability requirement for [private transaction manager](https://besu.hyperledger.org/en/latest/Concepts/Privacy/Privacy-Overview/#availability) (ie, Orion)
- Added [genesis file reference](https://besu.hyperledger.org/en/latest/Reference/Config-Items/)

### Technical Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.hyperledger.besu.tests.acceptance.dsl.privacy.contract.PrivateContractTransactions;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.transaction.PrivacyTransactions;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.contract.ContractTransactions;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.eth.EthTransactions;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.net.NetTransactions;

import org.junit.After;
Expand All @@ -40,8 +41,10 @@ public class PrivacyAcceptanceTestBase {
protected final PrivacyAccountResolver privacyAccountResolver;
protected final ContractTransactions contractTransactions;
protected final NetConditions net;
protected final EthTransactions ethTransactions;

public PrivacyAcceptanceTestBase() {
ethTransactions = new EthTransactions();
net = new NetConditions(new NetTransactions());
privacyTransactions = new PrivacyTransactions();
privateContractVerifier = new PrivateContractVerifier();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.transaction;

import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;

import java.io.IOException;

public class PrivDistributeTransactionTransaction implements Transaction<String> {
private String signedPrivateTransaction;

public PrivDistributeTransactionTransaction(final String signedPrivateTransaction) {
this.signedPrivateTransaction = signedPrivateTransaction;
}

@Override
public String execute(final NodeRequests node) {
try {
return node.privacy()
.privDistributeTransaction(signedPrivateTransaction)
.send()
.getTransactionKey();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ public CreatePrivacyGroupTransaction createPrivacyGroup(
public FindPrivacyGroupTransaction findPrivacyGroup(final List<String> nodes) {
return new FindPrivacyGroupTransaction(nodes);
}

public PrivDistributeTransactionTransaction privDistributeTransaction(
final String signedPrivateTransaction) {
return new PrivDistributeTransactionTransaction(signedPrivateTransaction);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,41 @@
*/
package org.hyperledger.besu.tests.acceptance.dsl.transaction.privacy;

import static java.util.Collections.singletonList;

import org.web3j.protocol.Web3jService;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.Response;
import org.web3j.protocol.pantheon.Pantheon;

public class PrivacyRequestFactory {
private final Pantheon besuClient;
private final Web3jService web3jService;

public PrivacyRequestFactory(final Web3jService web3jService) {
this.web3jService = web3jService;
this.besuClient = Pantheon.build(web3jService);
}

public Pantheon getBesuClient() {
return besuClient;
}

public Request<?, PrivDistributeTransactionResponse> privDistributeTransaction(
final String signedPrivateTransaction) {
return new Request<>(
"priv_distributeRawTransaction",
singletonList(signedPrivateTransaction),
web3jService,
PrivDistributeTransactionResponse.class);
}

public static class PrivDistributeTransactionResponse extends Response<String> {

public PrivDistributeTransactionResponse() {}

public String getTransactionKey() {
return getResult();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,40 @@
*/
package org.hyperledger.besu.tests.web3j.privacy;

import static org.assertj.core.api.Assertions.assertThat;

import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.types.ReceiveRequest;
import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyAcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.privacy.PrivacyNode;
import org.hyperledger.besu.tests.web3j.generated.EventEmitter;
import org.hyperledger.besu.util.bytes.BytesValue;
import org.hyperledger.besu.util.bytes.BytesValues;

import java.math.BigInteger;
import java.util.Collections;

import org.junit.Before;
import org.junit.Test;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.eea.crypto.PrivateTransactionEncoder;
import org.web3j.protocol.eea.crypto.RawPrivateTransaction;
import org.web3j.protocol.pantheon.response.privacy.PrivateTransactionReceipt;
import org.web3j.utils.Base64String;
import org.web3j.utils.Numeric;
import org.web3j.utils.Restriction;

public class PrivacyClusterAcceptanceTest extends PrivacyAcceptanceTestBase {

private static final long POW_CHAIN_ID = 2018;

private static final String eventEmmitterDeployed =
"0x6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029";

private PrivacyNode alice;
private PrivacyNode bob;
private PrivacyNode charlie;
Expand Down Expand Up @@ -81,6 +101,78 @@ public void onlyAliceAndBobCanExecuteContract() {
charlie.verify(privateTransactionVerifier.noPrivateTransactionReceipt(transactionHash));
}

@Test
public void aliceCanUsePrivDistributeTransaction() {
// Contract address is generated from sender address and transaction nonce
final String contractAddress = "0xebf56429e6500e84442467292183d4d621359838";

final RawPrivateTransaction rawPrivateTransaction =
RawPrivateTransaction.createContractTransaction(
BigInteger.ZERO,
BigInteger.ZERO,
BigInteger.ZERO,
Numeric.prependHexPrefix(EventEmitter.BINARY),
Base64String.wrap(alice.getEnclaveKey()),
Collections.singletonList(Base64String.wrap(bob.getEnclaveKey())),
Restriction.RESTRICTED);

final String signedPrivateTransaction =
Numeric.toHexString(
PrivateTransactionEncoder.signMessage(
rawPrivateTransaction,
POW_CHAIN_ID,
Credentials.create(alice.getTransactionSigningKey())));
final String transactionKey =
alice.execute(privacyTransactions.privDistributeTransaction(signedPrivateTransaction));

final Enclave aliceEnclave = new Enclave(alice.getOrion().clientUrl());
final ReceiveResponse aliceRR =
aliceEnclave.receive(
new ReceiveRequest(
BytesValues.asBase64String(BytesValue.fromHexString(transactionKey)),
alice.getEnclaveKey()));

final Enclave bobEnclave = new Enclave(bob.getOrion().clientUrl());
final ReceiveResponse bobRR =
bobEnclave.receive(
new ReceiveRequest(
BytesValues.asBase64String(BytesValue.fromHexString(transactionKey)),
bob.getEnclaveKey()));

assertThat(bobRR).isEqualToComparingFieldByField(aliceRR);

final RawTransaction pmt =
RawTransaction.createTransaction(
BigInteger.ZERO,
BigInteger.valueOf(1000),
BigInteger.valueOf(65000),
Address.DEFAULT_PRIVACY.toString(),
transactionKey);

final String signedPmt =
Numeric.toHexString(
TransactionEncoder.signMessage(
pmt, POW_CHAIN_ID, Credentials.create(alice.getTransactionSigningKey())));

final String transactionHash = alice.execute(ethTransactions.sendRawTransaction(signedPmt));

final PrivateTransactionReceipt expectedReceipt =
new PrivateTransactionReceipt(
contractAddress,
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
null,
eventEmmitterDeployed,
Collections.emptyList());

alice.verify(
privateTransactionVerifier.validPrivateTransactionReceipt(
transactionHash, expectedReceipt));

bob.verify(
privateTransactionVerifier.validPrivateTransactionReceipt(
transactionHash, expectedReceipt));
}

@Test
public void aliceCanDeployMultipleTimesInSingleGroup() {
final String firstDeployedAddress = "0xebf56429e6500e84442467292183d4d621359838";
Expand Down
18 changes: 15 additions & 3 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis;
import org.hyperledger.besu.ethereum.api.jsonrpc.websocket.WebSocketConfiguration;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.core.Wei;
Expand Down Expand Up @@ -130,6 +131,7 @@
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -589,15 +591,15 @@ void setBannedNodeIds(final List<String> values) {
names = {"--pruning-blocks-retained"},
hidden = true,
description =
"Number of recent blocks for which to keep entire world state (default: ${DEFAULT-VALUE})",
"Minimum number of recent blocks for which to keep entire world state (default: ${DEFAULT-VALUE})",
arity = "1")
private final Long pruningBlocksRetained = DEFAULT_PRUNING_BLOCKS_RETAINED;

@Option(
names = {"--pruning-block-confirmations"},
hidden = true,
description =
"Number of confirmations on a block before marking begins (default: ${DEFAULT-VALUE})",
"Minimum number of confirmations on a block before marking begins (default: ${DEFAULT-VALUE})",
arity = "1")
private final Long pruningBlockConfirmations = DEFAULT_PRUNING_BLOCK_CONFIRMATIONS;

Expand Down Expand Up @@ -645,6 +647,14 @@ void setBannedNodeIds(final List<String> values) {
"Enable passing the revert reason back through TransactionReceipts (default: ${DEFAULT-VALUE})")
private final Boolean isRevertReasonEnabled = false;

@Option(
names = {"--required-blocks", "--required-block"},
paramLabel = "BLOCK=HASH",
description = "Block number and hash peers are required to have.",
arity = "*",
split = ",")
private final Map<Long, Hash> requiredBlocks = new HashMap<>();

@Option(
names = {"--privacy-url"},
description = "The URL on which the enclave is running")
Expand Down Expand Up @@ -835,6 +845,7 @@ private BesuCommand registerConverters() {
commandLine.registerConverter(UInt256.class, (arg) -> UInt256.of(new BigInteger(arg)));
commandLine.registerConverter(Wei.class, (arg) -> Wei.of(Long.parseUnsignedLong(arg)));
commandLine.registerConverter(PositiveNumber.class, PositiveNumber::fromString);
commandLine.registerConverter(Hash.class, Hash::fromHexString);

metricCategoryConverter.addCategories(BesuMetricCategory.class);
metricCategoryConverter.addCategories(StandardMetricCategory.class);
Expand Down Expand Up @@ -1085,7 +1096,8 @@ public BesuControllerBuilder<?> getControllerBuilder() {
.isPruningEnabled(isPruningEnabled)
.pruningConfiguration(buildPruningConfiguration())
.genesisConfigOverrides(genesisConfigOverrides)
.targetGasLimit(targetGasLimit == null ? Optional.empty() : Optional.of(targetGasLimit));
.targetGasLimit(targetGasLimit == null ? Optional.empty() : Optional.of(targetGasLimit))
.requiredBlocks(requiredBlocks);
} catch (final IOException e) {
throw new ExecutionException(this.commandLine, "Invalid path", e);
}
Expand Down
Loading

0 comments on commit 5d4f70d

Please sign in to comment.