[Privacy] Allow users to provide a private genesis (#2509)

* Refactor: PrivacyBlockProcessor to clarify intent

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Wire up privacy genesis options into PrivacyParameters

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Refactor private state genesis into it's own class

- pass through in privacyParameters

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Refactor: inject PrivateStateGenesis into PrivacyPrecompiles

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Private Genesis initialisation

- set code, balance and storage from private-genesis.json

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Check on-chain with private genesis in acceptance tests

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Remove unused EthGetCodeCall

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Use a plugin based aproach for privacy genesis

- if the plugin is registered it will be used to apply private genesis
state
- if onchain flexible privacy groups is enable that will be applied
after

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* PrivateGenesisAcceptanceTest::createPrivacyGroup can be private

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* PrivateStateGenesis add debug logs

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Warn if genesis account allocation is in reserved precompile range

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Add sender into unsignedPrivateMarkerTransaction for plugin to make descision

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Remove locking solution as may not be needed

- if this is required we should first evaluate actual use cases
and test scenarios

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Rename PrivateStateGenesis -> PrivateStateGenesisAllocator

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Tidy up naming for getPrivateStateGenesisAllocator

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Privacy Plugin javadocs

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>
This commit is contained in:
Antony Denyer
2021-08-10 09:38:57 +01:00
committed by GitHub
parent 047b680ddc
commit 19c34514a1
42 changed files with 1223 additions and 210 deletions

View File

@@ -14,24 +14,17 @@
*/
package org.hyperledger.besu.plugins;
import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.readFrom;
import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.serialize;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.data.PrivateTransaction;
import org.hyperledger.besu.plugin.data.Transaction;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.PrivacyPluginService;
import org.hyperledger.besu.plugin.services.privacy.PrivacyPluginPayloadProvider;
import java.util.Optional;
import org.hyperledger.besu.plugins.privacy.TestPrivacyGroupGenesisProvider;
import org.hyperledger.besu.plugins.privacy.TestPrivacyPluginPayloadProvider;
import org.hyperledger.besu.plugins.privacy.TestSigningPrivateMarkerTransactionFactory;
import com.google.auto.service.AutoService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
import picocli.CommandLine.Option;
@AutoService(BesuPlugin.class)
@@ -41,6 +34,12 @@ public class TestPrivacyServicePlugin implements BesuPlugin {
PrivacyPluginService pluginService;
BesuContext context;
TestPrivacyPluginPayloadProvider payloadProvider = new TestPrivacyPluginPayloadProvider();
TestPrivacyGroupGenesisProvider privacyGroupGenesisProvider =
new TestPrivacyGroupGenesisProvider();
TestSigningPrivateMarkerTransactionFactory privateMarkerTransactionFactory =
new TestSigningPrivateMarkerTransactionFactory();
@Override
public void register(final BesuContext context) {
this.context = context;
@@ -48,39 +47,25 @@ public class TestPrivacyServicePlugin implements BesuPlugin {
context.getService(PicoCLIOptions.class).get().addPicoCLIOptions("privacy-service", this);
pluginService = context.getService(PrivacyPluginService.class).get();
pluginService.setPayloadProvider(
new PrivacyPluginPayloadProvider() {
@Override
public Bytes generateMarkerPayload(
final PrivateTransaction privateTransaction, final String privacyUserId) {
pluginService.setPayloadProvider(payloadProvider);
pluginService.setPrivacyGroupGenesisProvider(privacyGroupGenesisProvider);
return Bytes.wrap(Bytes.fromHexString(prefix), serialize(privateTransaction).encoded());
}
@Override
public Optional<PrivateTransaction> getPrivateTransactionFromPayload(
final Transaction transaction) {
final Bytes prefixBytes = Bytes.fromHexString(prefix);
if (transaction.getPayload().slice(0, prefixBytes.size()).equals(prefixBytes)) {
LOG.info("processing payload for" + prefix);
final BytesValueRLPInput bytesValueRLPInput =
new BytesValueRLPInput(
transaction.getPayload().slice(prefixBytes.size()).copy(), false);
return Optional.of(readFrom(bytesValueRLPInput));
} else {
LOG.info("Can not process payload for" + prefix);
return Optional.empty();
}
}
});
LOG.info("Registering Plugins with options " + this);
}
@Override
public void start() {
LOG.info("Start Plugins with options " + this);
payloadProvider.setPluginPayloadPrefix(prefix);
if (genesisEnabled) {
privacyGroupGenesisProvider.setGenesisEnabled();
}
if (signingEnabled) {
pluginService.setPrivateMarkerTransactionFactory(
new TestSigningPrivateMarkerTransactionFactory(signingKey));
pluginService.setPrivateMarkerTransactionFactory(privateMarkerTransactionFactory);
privateMarkerTransactionFactory.setSigningKeyEnbaled(signingKey);
}
}
@@ -90,9 +75,28 @@ public class TestPrivacyServicePlugin implements BesuPlugin {
@Option(names = "--plugin-privacy-service-encryption-prefix")
String prefix;
@Option(names = "--plugin-privacy-service-genesis-enabled")
boolean genesisEnabled = false;
@Option(names = "--plugin-privacy-service-signing-enabled")
boolean signingEnabled = false;
@Option(names = "--plugin-privacy-service-signing-key")
String signingKey;
@Override
public String toString() {
return "TestPrivacyServicePlugin{"
+ "prefix='"
+ prefix
+ '\''
+ ", signingEnabled="
+ signingEnabled
+ ", genesisEnabled="
+ genesisEnabled
+ ", signingKey='"
+ signingKey
+ '\''
+ '}';
}
}

View File

@@ -0,0 +1,87 @@
/*
* 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.plugins.privacy;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.plugin.data.Address;
import org.hyperledger.besu.plugin.data.PrivacyGenesis;
import org.hyperledger.besu.plugin.data.PrivacyGenesisAccount;
import org.hyperledger.besu.plugin.data.Quantity;
import org.hyperledger.besu.plugin.services.privacy.PrivacyGroupGenesisProvider;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
public class TestPrivacyGroupGenesisProvider implements PrivacyGroupGenesisProvider {
private boolean genesisEnabled = false;
public void setGenesisEnabled() {
this.genesisEnabled = true;
}
@Override
public PrivacyGenesis getPrivacyGenesis(final Bytes privacyGroupId, final long blockNumber) {
if (!genesisEnabled) return Collections::emptyList;
return () ->
List.of(
new PrivacyGenesisAccount() {
@Override
public Address getAddress() {
return org.hyperledger.besu.ethereum.core.Address.fromHexString(
"0x1000000000000000000000000000000000000001");
}
@Override
public Map<UInt256, UInt256> getStorage() {
return Collections.emptyMap();
}
@Override
public int getVersion() {
return 0;
}
@Override
public Long getNonce() {
return 0L;
}
@Override
public Quantity getBalance() {
return Wei.of(1000);
}
// The code in the genesis file needs to be the deployed contract code, not the code
// to deploy
// the contract
// you can generate it using the solc --bin-runtime flag
// cd ./acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/web3j/
// docker run -v $PWD:/sources ethereum/solc:0.5.0 -o /sources/output --bin-runtime
// /sources/EventEmitter.sol --overwrite
@Override
public Bytes getCode() {
return Bytes.fromHexString(
"0x608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633fa4f2451461005c5780636057361d1461008757806367e404ce146100c2575b600080fd5b34801561006857600080fd5b50610071610119565b6040518082815260200191505060405180910390f35b34801561009357600080fd5b506100c0600480360360208110156100aa57600080fd5b8101908080359060200190929190505050610123565b005b3480156100ce57600080fd5b506100d76101d9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600254905090565b7fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f53382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a18060028190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690509056fea165627a7a72305820e74360c3d08936cb1747ad641729261ff5e83b6fc0d303d136e171f15f07d7740029");
}
});
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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.plugins.privacy;
import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.readFrom;
import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.serialize;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.plugin.data.PrivateTransaction;
import org.hyperledger.besu.plugin.data.Transaction;
import org.hyperledger.besu.plugin.services.privacy.PrivacyPluginPayloadProvider;
import java.util.Optional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
public class TestPrivacyPluginPayloadProvider implements PrivacyPluginPayloadProvider {
private static final Logger LOG = LogManager.getLogger();
private String prefix;
public void setPluginPayloadPrefix(final String prefix) {
this.prefix = prefix;
}
@Override
public Bytes generateMarkerPayload(
final PrivateTransaction privateTransaction, final String privacyUserId) {
return Bytes.wrap(Bytes.fromHexString(prefix), serialize(privateTransaction).encoded());
}
@Override
public Optional<PrivateTransaction> getPrivateTransactionFromPayload(
final Transaction transaction) {
final Bytes prefixBytes = Bytes.fromHexString(prefix);
if (transaction.getPayload().slice(0, prefixBytes.size()).equals(prefixBytes)) {
LOG.info("processing payload for " + prefix);
final BytesValueRLPInput bytesValueRLPInput =
new BytesValueRLPInput(transaction.getPayload().slice(prefixBytes.size()).copy(), false);
return Optional.of(readFrom(bytesValueRLPInput));
} else {
LOG.info("Can not process payload for " + prefix);
return Optional.empty();
}
}
}

View File

@@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.plugins;
package org.hyperledger.besu.plugins.privacy;
import static org.apache.logging.log4j.LogManager.getLogger;
import static org.hyperledger.besu.ethereum.core.Address.extract;
@@ -39,11 +39,10 @@ public class TestSigningPrivateMarkerTransactionFactory implements PrivateMarker
private static final Logger LOG = getLogger();
final KeyPair aliceFixedSigningKey;
final Address sender;
KeyPair aliceFixedSigningKey;
Address sender;
public TestSigningPrivateMarkerTransactionFactory(
final String privateMarkerTransactionSigningKey) {
public void setSigningKeyEnbaled(final String privateMarkerTransactionSigningKey) {
final SignatureAlgorithm algorithm = SignatureAlgorithmFactory.getInstance();
final SECPPrivateKey privateKey =
algorithm.createPrivateKey(Bytes32.fromHexString(privateMarkerTransactionSigningKey));