Dagger controller tests (#7567)

Separate out flex group privacy test since it requires differently configured dependencies.
test specific, inline module/component definitions
reusable module for providing mockable enclaves, besu commands, and genesis
dagger support for transaction simulation
dagger support for plugin setup

---------

Signed-off-by: jflo <justin+github@florentine.us>
Signed-off-by: Justin Florentine <justin+github@florentine.us>
pull/7574/head
Justin Florentine 2 months ago committed by GitHub
parent 65240fdf46
commit d5c10e2b4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/condition/perm/AllowListContainsKeyAndValue.java
  2. 553
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java
  3. 2
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/privacy/PrivacyNode.java
  4. 2
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/bootstrap/ClusterThreadNodeRunnerAcceptanceTest.java
  5. 2
      besu/build.gradle
  6. 1
      besu/src/main/java/org/hyperledger/besu/controller/BesuControllerBuilder.java
  7. 2
      besu/src/main/java/org/hyperledger/besu/services/PermissioningServiceImpl.java
  8. 7
      besu/src/main/java/org/hyperledger/besu/services/SecurityModuleServiceImpl.java
  9. 2
      besu/src/main/java/org/hyperledger/besu/services/StorageServiceImpl.java
  10. 4
      besu/src/main/java/org/hyperledger/besu/services/TransactionSelectionServiceImpl.java
  11. 168
      besu/src/test/java/org/hyperledger/besu/FlexGroupPrivacyTest.java
  12. 151
      besu/src/test/java/org/hyperledger/besu/PrivacyReorgTest.java
  13. 171
      besu/src/test/java/org/hyperledger/besu/PrivacyTest.java
  14. 3
      besu/src/test/java/org/hyperledger/besu/RunnerTest.java
  15. 3
      besu/src/test/java/org/hyperledger/besu/chainexport/RlpBlockExporterTest.java
  16. 3
      besu/src/test/java/org/hyperledger/besu/chainimport/JsonBlockImporterTest.java
  17. 5
      besu/src/test/java/org/hyperledger/besu/chainimport/RlpBlockImporterTest.java
  18. 98
      besu/src/test/java/org/hyperledger/besu/components/EnclaveModule.java
  19. 38
      besu/src/test/java/org/hyperledger/besu/components/GenesisConfigModule.java
  20. 50
      besu/src/test/java/org/hyperledger/besu/components/MockBesuCommandModule.java
  21. 40
      besu/src/test/java/org/hyperledger/besu/components/NoOpMetricsSystemModule.java
  22. 47
      besu/src/test/java/org/hyperledger/besu/components/PrivacyParametersModule.java
  23. 111
      besu/src/test/java/org/hyperledger/besu/components/PrivacyTestModule.java
  24. 2
      besu/src/test/java/org/hyperledger/besu/controller/AbstractBftBesuControllerBuilderTest.java
  25. 2
      besu/src/test/java/org/hyperledger/besu/controller/CliqueBesuControllerBuilderTest.java
  26. 2
      besu/src/test/java/org/hyperledger/besu/controller/MergeBesuControllerBuilderTest.java
  27. 13
      ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/peers/EnodeURLImpl.java

@ -24,11 +24,16 @@ import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
import java.nio.file.Path;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AllowListContainsKeyAndValue implements Condition {
private final ALLOWLIST_TYPE allowlistType;
private final Collection<String> allowlistValues;
private final Path configFilePath;
private static final Logger LOG = LoggerFactory.getLogger(AllowListContainsKeyAndValue.class);
public AllowListContainsKeyAndValue(
final ALLOWLIST_TYPE allowlistType,
final Collection<String> allowlistValues,
@ -47,6 +52,7 @@ public class AllowListContainsKeyAndValue implements Condition {
allowlistType, allowlistValues, configFilePath);
} catch (final Exception e) {
result = false;
LOG.error("Error verifying allowlist contains key and value", e);
}
assertThat(result).isTrue();
}

@ -1,5 +1,5 @@
/*
* Copyright ConsenSys AG.
* Copyright contributors to Hyperledger Besu.
*
* 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
@ -18,8 +18,13 @@ import static org.hyperledger.besu.controller.BesuController.DATABASE_PATH;
import org.hyperledger.besu.Runner;
import org.hyperledger.besu.RunnerBuilder;
import org.hyperledger.besu.chainexport.RlpBlockExporter;
import org.hyperledger.besu.chainimport.JsonBlockImporter;
import org.hyperledger.besu.chainimport.RlpBlockImporter;
import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.controller.BesuControllerBuilder;
@ -30,23 +35,32 @@ import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.api.ApiConfiguration;
import org.hyperledger.besu.ethereum.api.graphql.GraphQLConfiguration;
import org.hyperledger.besu.ethereum.api.jsonrpc.InProcessRpcConfiguration;
import org.hyperledger.besu.ethereum.chain.Blockchain;
import org.hyperledger.besu.ethereum.core.ImmutableMiningParameters;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.plugins.PluginConfiguration;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule;
import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStorageProviderBuilder;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.MetricsSystemFactory;
import org.hyperledger.besu.metrics.MetricsSystemModule;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.plugin.data.EnodeURL;
import org.hyperledger.besu.plugin.services.BesuConfiguration;
import org.hyperledger.besu.plugin.services.BesuEvents;
import org.hyperledger.besu.plugin.services.BlockchainService;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.PermissioningService;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.PrivacyPluginService;
@ -70,6 +84,7 @@ import org.hyperledger.besu.services.StorageServiceImpl;
import org.hyperledger.besu.services.TransactionPoolValidatorServiceImpl;
import org.hyperledger.besu.services.TransactionSelectionServiceImpl;
import org.hyperledger.besu.services.TransactionSimulationServiceImpl;
import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin;
import java.io.File;
import java.nio.file.Path;
@ -78,9 +93,15 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Component;
import dagger.Module;
import dagger.Provides;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.vertx.core.Vertx;
import org.slf4j.Logger;
@ -96,60 +117,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
private final Map<Node, BesuPluginContextImpl> besuPluginContextMap = new ConcurrentHashMap<>();
private BesuPluginContextImpl buildPluginContext(
final BesuNode node,
final StorageServiceImpl storageService,
final SecurityModuleServiceImpl securityModuleService,
final TransactionSimulationServiceImpl transactionSimulationServiceImpl,
final TransactionSelectionServiceImpl transactionSelectionServiceImpl,
final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl,
final BlockchainServiceImpl blockchainServiceImpl,
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final BesuConfiguration commonPluginConfiguration,
final PermissioningServiceImpl permissioningService) {
final CommandLine commandLine = new CommandLine(CommandSpec.create());
final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl();
besuPluginContext.addService(StorageService.class, storageService);
besuPluginContext.addService(SecurityModuleService.class, securityModuleService);
besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl);
besuPluginContext.addService(
TransactionSelectionService.class, transactionSelectionServiceImpl);
besuPluginContext.addService(
TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl);
besuPluginContext.addService(
TransactionSimulationService.class, transactionSimulationServiceImpl);
besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl);
besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);
final Path pluginsPath;
final String pluginDir = System.getProperty("besu.plugins.dir");
if (pluginDir == null || pluginDir.isEmpty()) {
pluginsPath = node.homeDirectory().resolve("plugins");
final File pluginsDirFile = pluginsPath.toFile();
if (!pluginsDirFile.isDirectory()) {
pluginsDirFile.mkdirs();
pluginsDirFile.deleteOnExit();
}
System.setProperty("besu.plugins.dir", pluginsPath.toString());
} else {
pluginsPath = Path.of(pluginDir);
}
besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);
besuPluginContext.addService(PermissioningService.class, permissioningService);
besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl());
besuPluginContext.registerPlugins(
new PluginConfiguration.Builder().pluginsDir(pluginsPath).build());
commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0]));
// register built-in plugins
new RocksDBPlugin().register(besuPluginContext);
return besuPluginContext;
}
@Override
public void startNode(final BesuNode node) {
@ -162,114 +129,45 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
throw new UnsupportedOperationException("commands are not supported with thread runner");
}
final StorageServiceImpl storageService = new StorageServiceImpl();
final SecurityModuleServiceImpl securityModuleService = new SecurityModuleServiceImpl();
final TransactionSimulationServiceImpl transactionSimulationServiceImpl =
new TransactionSimulationServiceImpl();
final TransactionSelectionServiceImpl transactionSelectionServiceImpl =
new TransactionSelectionServiceImpl();
final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl =
new TransactionPoolValidatorServiceImpl();
final BlockchainServiceImpl blockchainServiceImpl = new BlockchainServiceImpl();
final RpcEndpointServiceImpl rpcEndpointServiceImpl = new RpcEndpointServiceImpl();
final Path dataDir = node.homeDirectory();
final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl();
final PermissioningServiceImpl permissioningService = new PermissioningServiceImpl();
final var miningParameters =
ImmutableMiningParameters.builder()
.from(node.getMiningParameters())
.transactionSelectionService(transactionSelectionServiceImpl)
BesuNodeProviderModule module = new BesuNodeProviderModule(node);
AcceptanceTestBesuComponent component =
DaggerThreadBesuNodeRunner_AcceptanceTestBesuComponent.builder()
.besuNodeProviderModule(module)
.build();
commonPluginConfiguration
.init(dataDir, dataDir.resolve(DATABASE_PATH), node.getDataStorageConfiguration())
.withMiningParameters(miningParameters);
final BesuPluginContextImpl besuPluginContext =
besuPluginContextMap.computeIfAbsent(
node,
n ->
buildPluginContext(
node,
storageService,
securityModuleService,
transactionSimulationServiceImpl,
transactionSelectionServiceImpl,
transactionPoolValidatorServiceImpl,
blockchainServiceImpl,
rpcEndpointServiceImpl,
commonPluginConfiguration,
permissioningService));
final Path dataDir = node.homeDirectory();
final PermissioningServiceImpl permissioningService = new PermissioningServiceImpl();
GlobalOpenTelemetry.resetForTest();
final ObservableMetricsSystem metricsSystem =
MetricsSystemFactory.create(node.getMetricsConfiguration());
final ObservableMetricsSystem metricsSystem = component.getObservableMetricsSystem();
final List<EnodeURL> bootnodes =
node.getConfiguration().getBootnodes().stream()
.map(EnodeURLImpl::fromURI)
.collect(Collectors.toList());
final NetworkName network = node.getNetwork() == null ? NetworkName.DEV : node.getNetwork();
final EthNetworkConfig.Builder networkConfigBuilder =
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(network))
.setBootNodes(bootnodes);
node.getConfiguration().getBootnodes().stream().map(EnodeURLImpl::fromURI).toList();
final EthNetworkConfig.Builder networkConfigBuilder = component.ethNetworkConfigBuilder();
networkConfigBuilder.setBootNodes(bootnodes);
node.getConfiguration()
.getGenesisConfig()
.map(GenesisConfigFile::fromConfig)
.ifPresent(networkConfigBuilder::setGenesisConfigFile);
final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build();
final SynchronizerConfiguration synchronizerConfiguration =
new SynchronizerConfiguration.Builder().build();
final BesuControllerBuilder builder =
new BesuController.Builder()
.fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode());
final KeyValueStorageProvider storageProvider =
new KeyValueStorageProviderBuilder()
.withStorageFactory(storageService.getByName("rocksdb").get())
.withCommonConfiguration(commonPluginConfiguration)
.withMetricsSystem(metricsSystem)
.build();
final BesuControllerBuilder builder = component.besuControllerBuilder();
builder.isRevertReasonEnabled(node.isRevertReasonEnabled());
builder.networkConfiguration(node.getNetworkingConfiguration());
final TransactionPoolConfiguration txPoolConfig =
ImmutableTransactionPoolConfiguration.builder()
.from(node.getTransactionPoolConfiguration())
.strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled())
.transactionPoolValidatorService(transactionPoolValidatorServiceImpl)
.build();
final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration();
final int maxPeers = 25;
builder
.synchronizerConfiguration(new SynchronizerConfiguration.Builder().build())
.dataDirectory(node.homeDirectory())
.miningParameters(miningParameters)
.privacyParameters(node.getPrivacyParameters())
.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir))))
.metricsSystem(metricsSystem)
.transactionPoolConfiguration(txPoolConfig)
.dataStorageConfiguration(node.getDataStorageConfiguration())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.clock(Clock.systemUTC())
.isRevertReasonEnabled(node.isRevertReasonEnabled())
.storageProvider(storageProvider)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.maxPeers(maxPeers)
.maxRemotelyInitiatedPeers(15)
.networkConfiguration(node.getNetworkingConfiguration())
.randomPeerPriority(false);
builder.dataDirectory(dataDir);
builder.nodeKey(new NodeKey(new KeyPairSecurityModule(KeyPairUtil.loadKeyPair(dataDir))));
builder.privacyParameters(node.getPrivacyParameters());
node.getGenesisConfig()
.map(GenesisConfigFile::fromConfig)
.ifPresent(builder::genesisConfigFile);
final BesuController besuController = builder.build();
final BesuController besuController = component.besuController();
InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration();
initTransactionSimulationService(
transactionSimulationServiceImpl, besuController, node.getApiConfiguration());
initBlockchainService(blockchainServiceImpl, besuController);
final BesuPluginContextImpl besuPluginContext =
besuPluginContextMap.computeIfAbsent(node, n -> component.getBesuPluginContext());
final RunnerBuilder runnerBuilder = new RunnerBuilder();
runnerBuilder.permissioningConfiguration(node.getPermissioningConfiguration());
@ -293,17 +191,13 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
.p2pEnabled(node.isP2pEnabled())
.p2pTLSConfiguration(node.getTLSConfiguration())
.graphQLConfiguration(GraphQLConfiguration.createDefault())
.staticNodes(
node.getStaticNodes().stream()
.map(EnodeURLImpl::fromString)
.collect(Collectors.toList()))
.staticNodes(node.getStaticNodes().stream().map(EnodeURLImpl::fromString).toList())
.besuPluginContext(besuPluginContext)
.autoLogBloomCaching(false)
.storageProvider(storageProvider)
.rpcEndpointService(rpcEndpointServiceImpl)
.storageProvider(besuController.getStorageProvider())
.rpcEndpointService(component.rpcEndpointService())
.inProcessRpcConfiguration(inProcessRpcConfiguration);
node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration);
besuPluginContext.beforeExternalServices();
final Runner runner = runnerBuilder.build();
@ -318,7 +212,7 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
besuController.getSyncState(),
besuController.getProtocolContext().getBadBlockManager()));
rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods());
component.rpcEndpointService().init(runner.getInProcessRpcMethods());
besuPluginContext.startPlugins();
@ -328,25 +222,6 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
MDC.remove("node");
}
private void initBlockchainService(
final BlockchainServiceImpl blockchainServiceImpl, final BesuController besuController) {
blockchainServiceImpl.init(
besuController.getProtocolContext(), besuController.getProtocolSchedule());
}
private void initTransactionSimulationService(
final TransactionSimulationServiceImpl transactionSimulationService,
final BesuController besuController,
final ApiConfiguration apiConfiguration) {
transactionSimulationService.init(
besuController.getProtocolContext().getBlockchain(),
new TransactionSimulator(
besuController.getProtocolContext().getBlockchain(),
besuController.getProtocolContext().getWorldStateArchive(),
besuController.getProtocolSchedule(),
apiConfiguration.getGasCap()));
}
@Override
public void stopNode(final BesuNode node) {
final BesuPluginContextImpl pluginContext = besuPluginContextMap.remove(node);
@ -396,4 +271,332 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
public String getConsoleContents() {
throw new RuntimeException("Console contents can only be captured in process execution");
}
@Module
static class BesuNodeProviderModule {
private final BesuNode toProvide;
public BesuNodeProviderModule(final BesuNode toProvide) {
this.toProvide = toProvide;
}
@Provides
public BesuNode provideBesuNodeRunner() {
return toProvide;
}
@Provides
@Named("ExtraCLIOptions")
public List<String> provideExtraCLIOptions() {
return toProvide.getExtraCLIOptions();
}
@Provides
Path provideDataDir() {
return toProvide.homeDirectory();
}
@Provides
@Singleton
RpcEndpointServiceImpl provideRpcEndpointService() {
return new RpcEndpointServiceImpl();
}
@Provides
@Singleton
BlockchainServiceImpl provideBlockchainService(final BesuController besuController) {
BlockchainServiceImpl retval = new BlockchainServiceImpl();
retval.init(besuController.getProtocolContext(), besuController.getProtocolSchedule());
return retval;
}
@Provides
@Singleton
Blockchain provideBlockchain(final BesuController besuController) {
return besuController.getProtocolContext().getBlockchain();
}
@Provides
@SuppressWarnings("CloseableProvides")
WorldStateArchive provideWorldStateArchive(final BesuController besuController) {
return besuController.getProtocolContext().getWorldStateArchive();
}
@Provides
ProtocolSchedule provideProtocolSchedule(final BesuController besuController) {
return besuController.getProtocolSchedule();
}
@Provides
ApiConfiguration provideApiConfiguration(final BesuNode node) {
return node.getApiConfiguration();
}
@Provides
@Singleton
TransactionPoolValidatorServiceImpl provideTransactionPoolValidatorService() {
return new TransactionPoolValidatorServiceImpl();
}
@Provides
@Singleton
TransactionSelectionServiceImpl provideTransactionSelectionService() {
return new TransactionSelectionServiceImpl();
}
@Provides
@Singleton
TransactionPoolConfiguration provideTransactionPoolConfiguration(
final BesuNode node,
final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl) {
TransactionPoolConfiguration txPoolConfig =
ImmutableTransactionPoolConfiguration.builder()
.from(node.getTransactionPoolConfiguration())
.strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled())
.transactionPoolValidatorService(transactionPoolValidatorServiceImpl)
.build();
return txPoolConfig;
}
@Provides
@Singleton
TransactionSimulator provideTransactionSimulator(
final Blockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final ApiConfiguration apiConfiguration) {
return new TransactionSimulator(
blockchain, worldStateArchive, protocolSchedule, apiConfiguration.getGasCap());
}
@Provides
@Singleton
TransactionSimulationServiceImpl provideTransactionSimulationService(
final Blockchain blockchain, final TransactionSimulator transactionSimulator) {
TransactionSimulationServiceImpl retval = new TransactionSimulationServiceImpl();
retval.init(blockchain, transactionSimulator);
return retval;
}
}
@Module
@SuppressWarnings("CloseableProvides")
static class BesuControllerModule {
@Provides
@Singleton
public SynchronizerConfiguration provideSynchronizationConfiguration() {
final SynchronizerConfiguration synchronizerConfiguration =
SynchronizerConfiguration.builder().build();
return synchronizerConfiguration;
}
@Singleton
@Provides
public BesuControllerBuilder provideBesuControllerBuilder(
final EthNetworkConfig ethNetworkConfig,
final SynchronizerConfiguration synchronizerConfiguration,
final TransactionPoolConfiguration transactionPoolConfiguration) {
final BesuControllerBuilder builder =
new BesuController.Builder()
.fromEthNetworkConfig(ethNetworkConfig, synchronizerConfiguration.getSyncMode());
builder.transactionPoolConfiguration(transactionPoolConfiguration);
return builder;
}
@Provides
@Singleton
public BesuController provideBesuController(
final SynchronizerConfiguration synchronizerConfiguration,
final BesuControllerBuilder builder,
final ObservableMetricsSystem metricsSystem,
final KeyValueStorageProvider storageProvider,
final MiningParameters miningParameters) {
builder
.synchronizerConfiguration(synchronizerConfiguration)
.metricsSystem(metricsSystem)
.dataStorageConfiguration(DataStorageConfiguration.DEFAULT_FOREST_CONFIG)
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.clock(Clock.systemUTC())
.storageProvider(storageProvider)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.maxPeers(25)
.maxRemotelyInitiatedPeers(15)
.miningParameters(miningParameters)
.randomPeerPriority(false)
.besuComponent(null);
return builder.build();
}
@Provides
@Singleton
public EthNetworkConfig.Builder provideEthNetworkConfigBuilder() {
final EthNetworkConfig.Builder networkConfigBuilder =
new EthNetworkConfig.Builder(EthNetworkConfig.getNetworkConfig(NetworkName.DEV));
return networkConfigBuilder;
}
@Provides
public EthNetworkConfig provideEthNetworkConfig(
final EthNetworkConfig.Builder networkConfigBuilder) {
final EthNetworkConfig ethNetworkConfig = networkConfigBuilder.build();
return ethNetworkConfig;
}
@Provides
@Named("besuPluginContext")
public BesuPluginContextImpl providePluginContext(
final StorageServiceImpl storageService,
final SecurityModuleServiceImpl securityModuleService,
final TransactionSimulationServiceImpl transactionSimulationServiceImpl,
final TransactionSelectionServiceImpl transactionSelectionServiceImpl,
final TransactionPoolValidatorServiceImpl transactionPoolValidatorServiceImpl,
final BlockchainServiceImpl blockchainServiceImpl,
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final BesuConfiguration commonPluginConfiguration,
final PermissioningServiceImpl permissioningService,
final @Named("ExtraCLIOptions") List<String> extraCLIOptions) {
final CommandLine commandLine = new CommandLine(CommandSpec.create());
final BesuPluginContextImpl besuPluginContext = new BesuPluginContextImpl();
besuPluginContext.addService(StorageService.class, storageService);
besuPluginContext.addService(SecurityModuleService.class, securityModuleService);
besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl);
besuPluginContext.addService(
TransactionSelectionService.class, transactionSelectionServiceImpl);
besuPluginContext.addService(
TransactionPoolValidatorService.class, transactionPoolValidatorServiceImpl);
besuPluginContext.addService(
TransactionSimulationService.class, transactionSimulationServiceImpl);
besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl);
besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);
final Path pluginsPath;
final String pluginDir = System.getProperty("besu.plugins.dir");
if (pluginDir == null || pluginDir.isEmpty()) {
pluginsPath = commonPluginConfiguration.getDataPath().resolve("plugins");
final File pluginsDirFile = pluginsPath.toFile();
if (!pluginsDirFile.isDirectory()) {
pluginsDirFile.mkdirs();
pluginsDirFile.deleteOnExit();
}
System.setProperty("besu.plugins.dir", pluginsPath.toString());
} else {
pluginsPath = Path.of(pluginDir);
}
besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);
besuPluginContext.addService(PermissioningService.class, permissioningService);
besuPluginContext.addService(PrivacyPluginService.class, new PrivacyPluginServiceImpl());
besuPluginContext.registerPlugins(
new PluginConfiguration.Builder().pluginsDir(pluginsPath).build());
commandLine.parseArgs(extraCLIOptions.toArray(new String[0]));
// register built-in plugins
new RocksDBPlugin().register(besuPluginContext);
return besuPluginContext;
}
@Provides
public KeyValueStorageProvider provideKeyValueStorageProvider(
final BesuConfiguration commonPluginConfiguration, final MetricsSystem metricsSystem) {
final StorageServiceImpl storageService = new StorageServiceImpl();
storageService.registerKeyValueStorage(
new InMemoryStoragePlugin.InMemoryKeyValueStorageFactory("memory"));
final KeyValueStorageProvider storageProvider =
new KeyValueStorageProviderBuilder()
.withStorageFactory(storageService.getByName("memory").get())
.withCommonConfiguration(commonPluginConfiguration)
.withMetricsSystem(metricsSystem)
.build();
return storageProvider;
}
@Provides
public MiningParameters provideMiningParameters(
final TransactionSelectionServiceImpl transactionSelectionServiceImpl,
final BesuNode node) {
final var miningParameters =
ImmutableMiningParameters.builder()
.from(node.getMiningParameters())
.transactionSelectionService(transactionSelectionServiceImpl)
.build();
return miningParameters;
}
@Provides
@Inject
BesuConfiguration provideBesuConfiguration(
final Path dataDir, final MiningParameters miningParameters, final BesuNode node) {
final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl();
commonPluginConfiguration.init(
dataDir, dataDir.resolve(DATABASE_PATH), node.getDataStorageConfiguration());
commonPluginConfiguration.withMiningParameters(miningParameters);
return commonPluginConfiguration;
}
}
@Module
static class MockBesuCommandModule {
@Provides
BesuCommand provideBesuCommand(final AcceptanceTestBesuComponent component) {
final BesuCommand besuCommand =
new BesuCommand(
component,
RlpBlockImporter::new,
JsonBlockImporter::new,
RlpBlockExporter::new,
new RunnerBuilder(),
new BesuController.Builder(),
Optional.ofNullable(component.getBesuPluginContext()).orElse(null),
System.getenv());
besuCommand.toCommandLine();
return besuCommand;
}
@Provides
@Singleton
MetricsConfiguration provideMetricsConfiguration() {
return MetricsConfiguration.builder().build();
}
@Provides
@Named("besuCommandLogger")
@Singleton
Logger provideBesuCommandLogger() {
return LoggerFactory.getLogger(MockBesuCommandModule.class);
}
}
@Singleton
@Component(
modules = {
ThreadBesuNodeRunner.BesuControllerModule.class,
ThreadBesuNodeRunner.MockBesuCommandModule.class,
BonsaiCachedMerkleTrieLoaderModule.class,
MetricsSystemModule.class,
ThreadBesuNodeRunner.BesuNodeProviderModule.class,
BlobCacheModule.class
})
public interface AcceptanceTestBesuComponent extends BesuComponent {
BesuController besuController();
BesuControllerBuilder besuControllerBuilder(); // TODO: needing this sucks
EthNetworkConfig.Builder ethNetworkConfigBuilder();
RpcEndpointServiceImpl rpcEndpointService();
BlockchainServiceImpl blockchainService();
}
}

@ -276,7 +276,7 @@ public class PrivacyNode implements AutoCloseable {
final Path dataLocation, final Path dbLocation) {
final var besuConfiguration = new BesuConfigurationImpl();
besuConfiguration
.init(dataLocation, dbLocation, null)
.init(dataLocation, dbLocation, besuConfig.getDataStorageConfiguration())
.withMiningParameters(besuConfig.getMiningParameters());
return new PrivacyKeyValueStorageProviderBuilder()
.withStorageFactory(

@ -38,7 +38,7 @@ public class ClusterThreadNodeRunnerAcceptanceTest extends AcceptanceTestBase {
final BesuNodeRunner besuNodeRunner = new ThreadBesuNodeRunner();
noDiscoveryCluster = new Cluster(clusterConfiguration, net, besuNodeRunner);
final BesuNode noDiscoveryNode = besu.createNodeWithNoDiscovery("noDiscovery");
fullNode = besu.createArchiveNode("node2");
fullNode = besu.createArchiveNode("archive");
noDiscoveryCluster.start(noDiscoveryNode, fullNode);
}

@ -105,6 +105,8 @@ dependencies {
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'tech.pegasys.discovery:discovery'
testImplementation 'com.google.dagger:dagger'
annotationProcessor 'com.google.dagger:dagger-compiler'
testAnnotationProcessor 'com.google.dagger:dagger-compiler'
}

@ -552,6 +552,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
checkNotNull(evmConfiguration, "Missing evm config");
checkNotNull(networkingConfiguration, "Missing network configuration");
checkNotNull(dataStorageConfiguration, "Missing data storage configuration");
prepForBuild();
final ProtocolSchedule protocolSchedule = createProtocolSchedule();

@ -19,6 +19,7 @@ import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissi
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import java.util.List;
import javax.inject.Inject;
import com.google.common.collect.Lists;
@ -29,6 +30,7 @@ public class PermissioningServiceImpl implements PermissioningService {
Lists.newArrayList();
/** Default Constructor. */
@Inject
public PermissioningServiceImpl() {}
@Override

@ -21,15 +21,18 @@ import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import javax.inject.Inject;
/** The Security module service implementation. */
public class SecurityModuleServiceImpl implements SecurityModuleService {
private final Map<String, Supplier<SecurityModule>> securityModuleSuppliers =
new ConcurrentHashMap<>();
/** Default Constructor. */
@Inject
public SecurityModuleServiceImpl() {}
private final Map<String, Supplier<SecurityModule>> securityModuleSuppliers =
new ConcurrentHashMap<>();
@Override
public void register(final String name, final Supplier<SecurityModule> securityModuleSupplier) {
securityModuleSuppliers.put(name, securityModuleSupplier);

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
/** The Storage service implementation. */
public class StorageServiceImpl implements StorageService {
@ -31,6 +32,7 @@ public class StorageServiceImpl implements StorageService {
private final Map<String, KeyValueStorageFactory> factories;
/** Instantiates a new Storage service. */
@Inject
public StorageServiceImpl() {
this.segments = List.of(KeyValueSegmentIdentifier.values());
this.factories = new ConcurrentHashMap<>();

@ -23,11 +23,11 @@ import java.util.Optional;
/** The Transaction Selection service implementation. */
public class TransactionSelectionServiceImpl implements TransactionSelectionService {
private Optional<PluginTransactionSelectorFactory> factory = Optional.empty();
/** Default Constructor. */
public TransactionSelectionServiceImpl() {}
private Optional<PluginTransactionSelectorFactory> factory = Optional.empty();
@Override
public PluginTransactionSelector createPluginTransactionSelector() {
return factory

@ -0,0 +1,168 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.components.BesuPluginContextModule;
import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyTestModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.precompile.PrecompiledContract;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.testutil.TestClock;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Component;
import dagger.Module;
import dagger.Provides;
import io.vertx.core.Vertx;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
class FlexGroupPrivacyTest {
private final Vertx vertx = Vertx.vertx();
@AfterEach
public void cleanUp() {
vertx.close();
}
@Test
void flexibleEnabledPrivacy() {
final BesuController besuController =
DaggerFlexGroupPrivacyTest_FlexGroupPrivacyTestComponent.builder()
.build()
.getBesuController();
final PrecompiledContract flexiblePrecompiledContract =
getPrecompile(besuController, FLEXIBLE_PRIVACY);
assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy");
}
private PrecompiledContract getPrecompile(
final BesuController besuController, final Address defaultPrivacy) {
return besuController
.getProtocolSchedule()
.getByBlockHeader(blockHeader(0))
.getPrecompileContractRegistry()
.get(defaultPrivacy);
}
private BlockHeader blockHeader(final long number) {
return new BlockHeaderTestFixture().number(number).buildHeader();
}
@Singleton
@Component(
modules = {
FlexGroupPrivacyParametersModule.class,
FlexGroupPrivacyTest.PrivacyTestBesuControllerModule.class,
PrivacyTestModule.class,
MockBesuCommandModule.class,
BonsaiCachedMerkleTrieLoaderModule.class,
NoOpMetricsSystemModule.class,
BesuPluginContextModule.class,
BlobCacheModule.class
})
interface FlexGroupPrivacyTestComponent extends BesuComponent {
BesuController getBesuController();
}
@Module
static class FlexGroupPrivacyParametersModule {
@Provides
PrivacyParameters providePrivacyParameters(
final PrivacyStorageProvider storageProvider, final Vertx vertx) {
try {
return new PrivacyParameters.Builder()
.setEnabled(true)
.setEnclaveUrl(new URI("http://127.0.0.1:8000"))
.setStorageProvider(storageProvider)
.setEnclaveFactory(new EnclaveFactory(vertx))
.setFlexiblePrivacyGroupsEnabled(true)
.build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
@Module
static class PrivacyTestBesuControllerModule {
@Provides
@Singleton
@SuppressWarnings("CloseableProvides")
BesuController provideBesuController(
final PrivacyParameters privacyParameters,
final DataStorageConfiguration dataStorageConfiguration,
final FlexGroupPrivacyTestComponent context,
@Named("dataDir") final Path dataDir) {
return new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())
.networkId(BigInteger.ONE)
.miningParameters(MiningParameters.newDefault())
.dataStorageConfiguration(dataStorageConfiguration)
.nodeKey(NodeKeyUtils.generate())
.metricsSystem(new NoOpMetricsSystem())
.dataDirectory(dataDir)
.clock(TestClock.fixed())
.privacyParameters(privacyParameters)
.transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(context)
.build();
}
}
}

@ -21,6 +21,12 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.components.BesuPluginContextModule;
import org.hyperledger.besu.components.EnclaveModule;
import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyTestModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.crypto.KeyPair;
@ -47,7 +53,9 @@ import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.mainnet.BlockImportResult;
import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode;
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver;
@ -56,6 +64,7 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.log.LogsBloomFilter;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
@ -70,19 +79,21 @@ import java.nio.file.Path;
import java.util.Collections;
import java.util.Optional;
import java.util.function.Supplier;
import javax.inject.Named;
import javax.inject.Singleton;
import com.google.common.base.Suppliers;
import dagger.Component;
import dagger.Module;
import dagger.Provides;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@SuppressWarnings("rawtypes")
public class PrivacyReorgTest {
@TempDir private Path folder;
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
@ -130,11 +141,15 @@ public class PrivacyReorgTest {
.signAndBuild(KEY_PAIR);
private final BlockDataGenerator gen = new BlockDataGenerator();
private BesuController besuController;
private PrivateStateRootResolver privateStateRootResolver;
private PrivacyParameters privacyParameters;
private Enclave mockEnclave;
private Transaction privacyMarkerTransaction;
private final PrivacyReorgTestComponent component =
DaggerPrivacyReorgTest_PrivacyReorgTestComponent.create();
private final BesuController besuController = component.getBesuController();
private final PrivateStateRootResolver privateStateRootResolver =
component.getPrivacyParameters().getPrivateStateRootResolver();
@BeforeEach
public void setUp() throws IOException {
@ -174,29 +189,6 @@ public class PrivacyReorgTest {
.build();
privacyParameters.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String());
privateStateRootResolver =
new PrivateStateRootResolver(privacyParameters.getPrivateStateStorage());
besuController =
new BesuController.Builder()
.fromGenesisFile(
GenesisConfigFile.fromResource("/privacy_reorg_genesis.json"), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())
.networkId(BigInteger.ONE)
.miningParameters(MiningParameters.newDefault())
.nodeKey(NodeKeyUtils.generate())
.metricsSystem(new NoOpMetricsSystem())
.dataDirectory(folder)
.clock(TestClock.fixed())
.privacyParameters(privacyParameters)
.transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.build();
}
@Test
@ -204,7 +196,8 @@ public class PrivacyReorgTest {
// Setup an initial blockchain with one private transaction
final ProtocolContext protocolContext = besuController.getProtocolContext();
final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain();
final PrivateStateStorage privateStateStorage = privacyParameters.getPrivateStateStorage();
final PrivateStateStorage privateStateStorage =
component.getPrivacyParameters().getPrivateStateStorage();
final Block firstBlock =
gen.block(
@ -244,7 +237,7 @@ public class PrivacyReorgTest {
// Setup an initial blockchain with one private transaction
final ProtocolContext protocolContext = besuController.getProtocolContext();
final DefaultBlockchain blockchain = (DefaultBlockchain) protocolContext.getBlockchain();
assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(0);
final Block firstBlock =
gen.block(
getBlockOptionsWithTransaction(
@ -252,8 +245,9 @@ public class PrivacyReorgTest {
privacyMarkerTransaction,
FIRST_BLOCK_WITH_SINGLE_TRANSACTION_STATE_ROOT));
appendBlock(besuController, blockchain, protocolContext, firstBlock);
var importResult = appendBlock(besuController, blockchain, protocolContext, firstBlock);
assertThat(importResult.isImported()).isTrue();
assertThat(blockchain.getChainHeadBlockNumber()).isEqualTo(1);
// Check that the private state root is not the empty state
assertPrivateStateRoot(
privateStateRootResolver, blockchain, STATE_ROOT_AFTER_TRANSACTION_APPENDED_TO_EMPTY_STATE);
@ -394,12 +388,12 @@ public class PrivacyReorgTest {
}
@SuppressWarnings("unchecked")
private void appendBlock(
private BlockImportResult appendBlock(
final BesuController besuController,
final DefaultBlockchain blockchain,
final ProtocolContext protocolContext,
final Block block) {
besuController
return besuController
.getProtocolSchedule()
.getByBlockHeader(blockchain.getChainHeadHeader())
.getBlockImporter()
@ -487,4 +481,93 @@ public class PrivacyReorgTest {
.hasOmmers(false)
.setLogsBloom(LogsBloomFilter.empty());
}
@Singleton
@Component(
modules = {
PrivacyReorgTest.PrivacyReorgParametersModule.class,
PrivacyReorgTest.PrivacyReorgTestBesuControllerModule.class,
PrivacyReorgTest.PrivacyReorgTestGenesisConfigModule.class,
EnclaveModule.class,
PrivacyTestModule.class,
MockBesuCommandModule.class,
NoOpMetricsSystemModule.class,
BonsaiCachedMerkleTrieLoaderModule.class,
BlobCacheModule.class,
BesuPluginContextModule.class
})
interface PrivacyReorgTestComponent extends BesuComponent {
BesuController getBesuController();
PrivacyParameters getPrivacyParameters();
}
@Module
static class PrivacyReorgParametersModule {
// TODO: copypasta, get this from the enclave factory
private static final Bytes ENCLAVE_PUBLIC_KEY =
Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=");
@Provides
PrivacyParameters providePrivacyReorgParameters(
final PrivacyStorageProvider storageProvider, final EnclaveFactory enclaveFactory) {
PrivacyParameters retval =
new PrivacyParameters.Builder()
.setEnabled(true)
.setStorageProvider(storageProvider)
.setEnclaveUrl(URI.create("http//1.1.1.1:1234"))
.setEnclaveFactory(enclaveFactory)
.build();
retval.setPrivacyUserId(ENCLAVE_PUBLIC_KEY.toBase64String());
return retval;
}
}
@Module
static class PrivacyReorgTestBesuControllerModule {
@Provides
@Singleton
@SuppressWarnings("CloseableProvides")
BesuController provideBesuController(
final PrivacyParameters privacyParameters,
final GenesisConfigFile genesisConfigFile,
final PrivacyReorgTestComponent context,
final @Named("dataDir") Path dataDir) {
// dataStorageConfiguration default
// named privacyReorgParams
BesuController retval =
new BesuController.Builder()
.fromGenesisFile(genesisConfigFile, SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())
.networkId(BigInteger.ONE)
.miningParameters(MiningParameters.newDefault())
.nodeKey(NodeKeyUtils.generate())
.metricsSystem(new NoOpMetricsSystem())
.dataDirectory(dataDir)
.clock(TestClock.fixed())
.privacyParameters(privacyParameters)
.transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(context)
.build();
return retval;
}
}
@Module
static class PrivacyReorgTestGenesisConfigModule {
@Provides
GenesisConfigFile providePrivacyReorgGenesisConfigFile() {
return GenesisConfigFile.fromResource("/privacy_reorg_genesis.json");
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright ConsenSys AG.
* Copyright contributors to Hyperledger Besu.
*
* 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
@ -16,18 +16,17 @@ package org.hyperledger.besu;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.core.PrivacyParameters.DEFAULT_PRIVACY;
import static org.hyperledger.besu.ethereum.core.PrivacyParameters.FLEXIBLE_PRIVACY;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.components.BesuPluginContextModule;
import org.hyperledger.besu.components.MockBesuCommandModule;
import org.hyperledger.besu.components.NoOpMetricsSystemModule;
import org.hyperledger.besu.components.PrivacyParametersModule;
import org.hyperledger.besu.components.PrivacyTestModule;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
@ -37,126 +36,47 @@ import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SyncMode;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule;
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider;
import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.evm.precompile.PrecompiledContract;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration;
import org.hyperledger.besu.services.BesuConfigurationImpl;
import org.hyperledger.besu.testutil.TestClock;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Component;
import dagger.Module;
import dagger.Provides;
import io.vertx.core.Vertx;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
public class PrivacyTest {
class PrivacyTest {
private final Vertx vertx = Vertx.vertx();
@TempDir private Path dataDir;
@AfterEach
public void cleanUp() {
vertx.close();
}
@Test
public void defaultPrivacy() throws IOException, URISyntaxException {
final BesuController besuController = setUpControllerWithPrivacyEnabled(false);
void defaultPrivacy() {
final BesuController besuController =
DaggerPrivacyTest_PrivacyTestComponent.builder().build().getBesuController();
final PrecompiledContract precompiledContract = getPrecompile(besuController, DEFAULT_PRIVACY);
assertThat(precompiledContract.getName()).isEqualTo("Privacy");
}
@Test
public void flexibleEnabledPrivacy() throws IOException, URISyntaxException {
final BesuController besuController = setUpControllerWithPrivacyEnabled(true);
final PrecompiledContract flexiblePrecompiledContract =
getPrecompile(besuController, FLEXIBLE_PRIVACY);
assertThat(flexiblePrecompiledContract.getName()).isEqualTo("FlexiblePrivacy");
}
private BesuController setUpControllerWithPrivacyEnabled(final boolean flexibleEnabled)
throws IOException, URISyntaxException {
final Path dbDir = Files.createTempDirectory(dataDir, "database");
final var miningParameters = MiningParameters.newDefault();
final var dataStorageConfiguration = DataStorageConfiguration.DEFAULT_FOREST_CONFIG;
final PrivacyParameters privacyParameters =
new PrivacyParameters.Builder()
.setEnabled(true)
.setEnclaveUrl(new URI("http://127.0.0.1:8000"))
.setStorageProvider(
createKeyValueStorageProvider(
dataDir, dbDir, dataStorageConfiguration, miningParameters))
.setEnclaveFactory(new EnclaveFactory(vertx))
.setFlexiblePrivacyGroupsEnabled(flexibleEnabled)
.build();
return new BesuController.Builder()
.fromEthNetworkConfig(EthNetworkConfig.getNetworkConfig(NetworkName.MAINNET), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())
.networkId(BigInteger.ONE)
.miningParameters(miningParameters)
.dataStorageConfiguration(dataStorageConfiguration)
.nodeKey(NodeKeyUtils.generate())
.metricsSystem(new NoOpMetricsSystem())
.dataDirectory(dataDir)
.clock(TestClock.fixed())
.privacyParameters(privacyParameters)
.transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.build();
}
private PrivacyStorageProvider createKeyValueStorageProvider(
final Path dataDir,
final Path dbDir,
final DataStorageConfiguration dataStorageConfiguration,
final MiningParameters miningParameters) {
final var besuConfiguration = new BesuConfigurationImpl();
besuConfiguration
.init(dataDir, dbDir, dataStorageConfiguration)
.withMiningParameters(miningParameters);
return new PrivacyKeyValueStorageProviderBuilder()
.withStorageFactory(
new RocksDBKeyValuePrivacyStorageFactory(
new RocksDBKeyValueStorageFactory(
() ->
new RocksDBFactoryConfiguration(
DEFAULT_MAX_OPEN_FILES,
DEFAULT_BACKGROUND_THREAD_COUNT,
DEFAULT_CACHE_CAPACITY,
DEFAULT_IS_HIGH_SPEC),
Arrays.asList(KeyValueSegmentIdentifier.values()),
RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS)))
.withCommonConfiguration(besuConfiguration)
.withMetricsSystem(new NoOpMetricsSystem())
.build();
}
private PrecompiledContract getPrecompile(
final BesuController besuController, final Address defaultPrivacy) {
return besuController
@ -169,4 +89,55 @@ public class PrivacyTest {
private BlockHeader blockHeader(final long number) {
return new BlockHeaderTestFixture().number(number).buildHeader();
}
@Singleton
@Component(
modules = {
PrivacyParametersModule.class,
PrivacyTest.PrivacyTestBesuControllerModule.class,
PrivacyTestModule.class,
MockBesuCommandModule.class,
BonsaiCachedMerkleTrieLoaderModule.class,
NoOpMetricsSystemModule.class,
BesuPluginContextModule.class,
BlobCacheModule.class
})
interface PrivacyTestComponent extends BesuComponent {
BesuController getBesuController();
}
@Module
static class PrivacyTestBesuControllerModule {
@Provides
@Singleton
@SuppressWarnings("CloseableProvides")
BesuController provideBesuController(
final PrivacyParameters privacyParameters,
final DataStorageConfiguration dataStorageConfiguration,
final PrivacyTestComponent context,
@Named("dataDir") final Path dataDir) {
return new BesuController.Builder()
.fromGenesisFile(GenesisConfigFile.mainnet(), SyncMode.FULL)
.synchronizerConfiguration(SynchronizerConfiguration.builder().build())
.ethProtocolConfiguration(EthProtocolConfiguration.defaultConfig())
.storageProvider(new InMemoryKeyValueStorageProvider())
.networkId(BigInteger.ONE)
.miningParameters(MiningParameters.newDefault())
.dataStorageConfiguration(dataStorageConfiguration)
.nodeKey(NodeKeyUtils.generate())
.metricsSystem(new NoOpMetricsSystem())
.dataDirectory(dataDir)
.clock(TestClock.fixed())
.privacyParameters(privacyParameters)
.transactionPoolConfiguration(TransactionPoolConfiguration.DEFAULT)
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(context)
.build();
}
}
}

@ -22,8 +22,10 @@ import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.config.MergeConfigOptions;
@ -483,6 +485,7 @@ public final class RunnerTest {
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.randomPeerPriority(Boolean.FALSE)
.besuComponent(mock(BesuComponent.class))
.maxPeers(25)
.maxRemotelyInitiatedPeers(15)
.build();

@ -16,10 +16,12 @@ package org.hyperledger.besu.chainexport;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.chainimport.RlpBlockImporter;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
import org.hyperledger.besu.ethereum.GasLimitCalculator;
@ -102,6 +104,7 @@ public final class RlpBlockExporterTest {
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(mock(BesuComponent.class))
.build();
}

@ -17,7 +17,9 @@ package org.hyperledger.besu.chainimport;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.controller.BesuController;
@ -463,6 +465,7 @@ public abstract class JsonBlockImporterTest {
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(mock(BesuComponent.class))
.build();
}
}

@ -16,9 +16,11 @@ package org.hyperledger.besu.chainimport;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.cli.config.EthNetworkConfig;
import org.hyperledger.besu.cli.config.NetworkName;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.MergeConfigOptions;
import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.cryptoservices.NodeKeyUtils;
@ -77,6 +79,7 @@ public final class RlpBlockImporterTest {
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(mock(BesuComponent.class))
.build();
final RlpBlockImporter.ImportResult result =
rlpBlockImporter.importBlockchain(source, targetController, false);
@ -110,6 +113,7 @@ public final class RlpBlockImporterTest {
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(mock(BesuComponent.class))
.build();
assertThatThrownBy(
@ -140,6 +144,7 @@ public final class RlpBlockImporterTest {
.gasLimitCalculator(GasLimitCalculator.constant())
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(mock(BesuComponent.class))
.build();
final RlpBlockImporter.ImportResult result =

@ -0,0 +1,98 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.components;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.plugin.data.Restriction;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.function.Supplier;
import com.google.common.base.Suppliers;
import dagger.Module;
import dagger.Provides;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
@Module
public class EnclaveModule {
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
private static final Bytes ENCLAVE_PUBLIC_KEY =
Bytes.fromBase64String("A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=");
private static final Bytes32 PRIVACY_GROUP_BYTES32 =
Bytes32.fromHexString("0xf250d523ae9164722b06ca25cfa2a7f3c45df96b09e215236f886c876f715bfa");
private static final Bytes MOCK_PAYLOAD =
Bytes.fromHexString(
"0x608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610199806100326000396000f3fe6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633fa4f245811461005b5780636057361d1461008257806367e404ce146100ae575b600080fd5b34801561006757600080fd5b506100706100ec565b60408051918252519081900360200190f35b34801561008e57600080fd5b506100ac600480360360208110156100a557600080fd5b50356100f2565b005b3480156100ba57600080fd5b506100c3610151565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60025490565b604080513381526020810183905281517fc9db20adedc6cf2b5d25252b101ab03e124902a73fcb12b753f3d1aaa2d8f9f5929181900390910190a16002556001805473ffffffffffffffffffffffffffffffffffffffff191633179055565b60015473ffffffffffffffffffffffffffffffffffffffff169056fea165627a7a72305820c7f729cb24e05c221f5aa913700793994656f233fe2ce3b9fd9a505ea17e8d8a0029");
private static final KeyPair KEY_PAIR =
SIGNATURE_ALGORITHM
.get()
.createKeyPair(
SIGNATURE_ALGORITHM
.get()
.createPrivateKey(
new BigInteger(
"8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 16)));
private static final PrivateTransaction PRIVATE_TRANSACTION =
PrivateTransaction.builder()
.chainId(BigInteger.valueOf(1337))
.gasLimit(1000)
.gasPrice(Wei.ZERO)
.nonce(0)
.payload(MOCK_PAYLOAD)
.to(null)
.privateFrom(ENCLAVE_PUBLIC_KEY)
.privateFor(Collections.singletonList(ENCLAVE_PUBLIC_KEY))
.restriction(Restriction.RESTRICTED)
.value(Wei.ZERO)
.signAndBuild(KEY_PAIR);
@Provides
EnclaveFactory provideMockableEnclaveFactory() {
Enclave mockEnclave = mock(Enclave.class);
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
PRIVATE_TRANSACTION.writeTo(rlpOutput);
when(mockEnclave.receive(any()))
.thenReturn(
new ReceiveResponse(
rlpOutput.encoded().toBase64String().getBytes(StandardCharsets.UTF_8),
PRIVACY_GROUP_BYTES32.toBase64String(),
ENCLAVE_PUBLIC_KEY.toBase64String()));
EnclaveFactory enclaveFactory = mock(EnclaveFactory.class);
when(enclaveFactory.createVertxEnclave(any())).thenReturn(mockEnclave);
return enclaveFactory;
}
}

@ -0,0 +1,38 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.components;
import org.hyperledger.besu.config.GenesisConfigFile;
import javax.inject.Named;
import dagger.Module;
import dagger.Provides;
@Module
public class GenesisConfigModule {
@Named("default")
@Provides
GenesisConfigFile provideDefaultGenesisConfigFile() {
return GenesisConfigFile.DEFAULT;
}
@Named("mainnet")
@Provides
GenesisConfigFile provideMainnetGenesisConfigFile() {
return GenesisConfigFile.mainnet();
}
}

@ -0,0 +1,50 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.components;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Module
public class MockBesuCommandModule {
@Provides
BesuCommand provideBesuCommand() {
return mock(BesuCommand.class);
}
@Provides
@Singleton
MetricsConfiguration provideMetricsConfiguration() {
return MetricsConfiguration.builder().build();
}
@Provides
@Named("besuCommandLogger")
@Singleton
Logger provideBesuCommandLogger() {
return LoggerFactory.getLogger(MockBesuCommandModule.class);
}
}

@ -0,0 +1,40 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.components;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class NoOpMetricsSystemModule {
@Provides
@Singleton
MetricsSystem provideMetricsSystem() {
return new NoOpMetricsSystem();
}
@Provides
@Singleton
ObservableMetricsSystem provideObservableMetricsSystem() {
return new NoOpMetricsSystem();
}
}

@ -0,0 +1,47 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.components;
import org.hyperledger.besu.enclave.EnclaveFactory;
import org.hyperledger.besu.ethereum.core.PrivacyParameters;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider;
import java.net.URI;
import java.net.URISyntaxException;
import dagger.Module;
import dagger.Provides;
import io.vertx.core.Vertx;
/** Provides a general use PrivacyParameters instance for testing. */
@Module
public class PrivacyParametersModule {
@Provides
PrivacyParameters providePrivacyParameters(
final PrivacyStorageProvider storageProvider, final Vertx vertx) {
try {
return new PrivacyParameters.Builder()
.setEnabled(true)
.setEnclaveUrl(new URI("http://127.0.0.1:8000"))
.setStorageProvider(storageProvider)
.setEnclaveFactory(new EnclaveFactory(vertx))
.setFlexiblePrivacyGroupsEnabled(false)
.build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}

@ -0,0 +1,111 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.components;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_BACKGROUND_THREAD_COUNT;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_CACHE_CAPACITY;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_IS_HIGH_SPEC;
import static org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBCLIOptions.DEFAULT_MAX_OPEN_FILES;
import org.hyperledger.besu.ethereum.privacy.storage.PrivacyStorageProvider;
import org.hyperledger.besu.ethereum.privacy.storage.keyvalue.PrivacyKeyValueStorageProviderBuilder;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValuePrivacyStorageFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBKeyValueStorageFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBMetricsFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.configuration.RocksDBFactoryConfiguration;
import org.hyperledger.besu.services.BesuConfigurationImpl;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import io.vertx.core.Vertx;
@Module
public class PrivacyTestModule {
@Provides
@Named("dataDir")
Path provideDataDir() {
try {
return Files.createTempDirectory("PrivacyTestDatadir");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Provides
Vertx provideVertx() {
return Vertx.vertx();
}
@Provides
DataStorageConfiguration provideDataStorageConfiguration() {
return DataStorageConfiguration.DEFAULT_FOREST_CONFIG;
}
@Provides
@Singleton
@Named("dbDir")
Path provideDbDir(@Named("dataDir") final Path dataDir) {
try {
final Path dbDir = Files.createTempDirectory(dataDir, "database");
return dbDir;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Provides
@Singleton
@Named("flexibleEnabled")
Boolean provideFlexibleEnabled() {
return true;
}
@Provides
@Singleton
@SuppressWarnings("CloseableProvides")
PrivacyStorageProvider provideKeyValueStorageProvider(
@Named("dbDir") final Path dbDir,
final DataStorageConfiguration dataStorageConfiguration,
@Named("dataDir") final Path dataDir) {
final var besuConfiguration = new BesuConfigurationImpl();
besuConfiguration.init(dataDir, dbDir, dataStorageConfiguration);
return new PrivacyKeyValueStorageProviderBuilder()
.withStorageFactory(
new RocksDBKeyValuePrivacyStorageFactory(
new RocksDBKeyValueStorageFactory(
() ->
new RocksDBFactoryConfiguration(
DEFAULT_MAX_OPEN_FILES,
DEFAULT_BACKGROUND_THREAD_COUNT,
DEFAULT_CACHE_CAPACITY,
DEFAULT_IS_HIGH_SPEC),
Arrays.asList(KeyValueSegmentIdentifier.values()),
RocksDBMetricsFactory.PRIVATE_ROCKS_DB_METRICS)))
.withCommonConfiguration(besuConfiguration)
.withMetricsSystem(new NoOpMetricsSystem())
.build();
}
}

@ -19,6 +19,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
@ -156,6 +157,7 @@ public abstract class AbstractBftBesuControllerBuilderTest {
.storageProvider(storageProvider)
.gasLimitCalculator(gasLimitCalculator)
.evmConfiguration(EvmConfiguration.DEFAULT)
.besuComponent(mock(BesuComponent.class))
.networkConfiguration(NetworkingConfiguration.create());
}

@ -20,6 +20,7 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
@ -189,6 +190,7 @@ public class CliqueBesuControllerBuilderTest {
.storageProvider(storageProvider)
.gasLimitCalculator(gasLimitCalculator)
.evmConfiguration(EvmConfiguration.DEFAULT)
.besuComponent(mock(BesuComponent.class))
.networkConfiguration(NetworkingConfiguration.create());
}

@ -23,6 +23,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.components.BesuComponent;
import org.hyperledger.besu.config.CheckpointConfigOptions;
import org.hyperledger.besu.config.GenesisConfigFile;
import org.hyperledger.besu.config.GenesisConfigOptions;
@ -189,6 +190,7 @@ public class MergeBesuControllerBuilderTest {
.storageProvider(storageProvider)
.evmConfiguration(EvmConfiguration.DEFAULT)
.networkConfiguration(NetworkingConfiguration.create())
.besuComponent(mock(BesuComponent.class))
.networkId(networkId);
}

@ -381,10 +381,11 @@ public class EnodeURLImpl implements EnodeURL {
return ipAddress(ip, EnodeDnsConfiguration.dnsDisabled());
}
public Builder ipAddress(final String ip, final EnodeDnsConfiguration enodeDnsConfiguration) {
public Builder ipAddress(
final String hostField, final EnodeDnsConfiguration enodeDnsConfiguration) {
if (enodeDnsConfiguration.dnsEnabled()) {
try {
this.ip = InetAddress.getByName(ip);
this.ip = InetAddress.getByName(hostField);
if (enodeDnsConfiguration.updateEnabled()) {
if (this.ip.isLoopbackAddress()) {
this.ip = InetAddress.getLocalHost();
@ -398,10 +399,10 @@ public class EnodeURLImpl implements EnodeURL {
this.ip = InetAddresses.forString("127.0.0.1");
}
}
} else if (InetAddresses.isUriInetAddress(ip)) {
this.ip = InetAddresses.forUriString(ip);
} else if (InetAddresses.isInetAddress(ip)) {
this.ip = InetAddresses.forString(ip);
} else if (InetAddresses.isUriInetAddress(hostField)) {
this.ip = InetAddresses.forUriString(hostField);
} else if (InetAddresses.isInetAddress(hostField)) {
this.ip = InetAddresses.forString(hostField);
} else {
throw new IllegalArgumentException("Invalid ip address.");
}

Loading…
Cancel
Save