Skip to content

Commit

Permalink
Introduce TransactionSimulatorService (hyperledger#36)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
fab-10 authored Feb 7, 2024
1 parent 73c3b2a commit b0f872c
Show file tree
Hide file tree
Showing 107 changed files with 1,043 additions and 377 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration;
import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
Expand Down Expand Up @@ -109,6 +110,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
private final WebSocketConfiguration webSocketConfiguration;
private final JsonRpcIpcConfiguration jsonRpcIpcConfiguration;
private final MetricsConfiguration metricsConfiguration;
private final DataStorageConfiguration dataStorageConfiguration;
private Optional<PermissioningConfiguration> permissioningConfiguration;
private final ApiConfiguration apiConfiguration;
private final GenesisConfigurationProvider genesisConfigProvider;
Expand Down Expand Up @@ -145,6 +147,7 @@ public BesuNode(
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
final ApiConfiguration apiConfiguration,
final DataStorageConfiguration dataStorageConfiguration,
final Optional<String> keyfilePath,
final boolean devMode,
final NetworkName network,
Expand Down Expand Up @@ -195,6 +198,7 @@ public BesuNode(
this.metricsConfiguration = metricsConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.apiConfiguration = apiConfiguration;
this.dataStorageConfiguration = dataStorageConfiguration;
this.genesisConfigProvider = genesisConfigProvider;
this.devMode = devMode;
this.network = network;
Expand Down Expand Up @@ -432,6 +436,7 @@ public NodeRequests nodeRequests() {

nodeRequests =
new NodeRequests(
web3jService,
new JsonRpc2_0Web3j(web3jService, 2000, Async.defaultExecutorService()),
new CliqueRequestFactory(web3jService),
new BftRequestFactory(web3jService, bftType),
Expand Down Expand Up @@ -690,6 +695,10 @@ public void setPrivacyParameters(final PrivacyParameters privacyParameters) {
this.privacyParameters = privacyParameters;
}

public DataStorageConfiguration getDataStorageConfiguration() {
return dataStorageConfiguration;
}

public boolean isDevMode() {
return devMode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.hyperledger.besu.cryptoservices.KeyPairSecurityModule;
import org.hyperledger.besu.cryptoservices.NodeKey;
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.eth.EthProtocolConfiguration;
import org.hyperledger.besu.ethereum.eth.sync.SynchronizerConfiguration;
Expand All @@ -36,31 +37,34 @@
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.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.MetricsSystemFactory;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
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.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.PluginTransactionValidatorService;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.SecurityModuleService;
import org.hyperledger.besu.plugin.services.StorageService;
import org.hyperledger.besu.plugin.services.TransactionSelectionService;
import org.hyperledger.besu.plugin.services.TransactionSimulationService;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBPlugin;
import org.hyperledger.besu.plugin.services.txselection.PluginTransactionSelectorFactory;
import org.hyperledger.besu.plugin.services.txvalidator.PluginTransactionValidatorFactory;
import org.hyperledger.besu.services.BesuConfigurationImpl;
import org.hyperledger.besu.services.BesuEventsImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.BlockchainServiceImpl;
import org.hyperledger.besu.services.PermissioningServiceImpl;
import org.hyperledger.besu.services.PicoCLIOptionsImpl;
import org.hyperledger.besu.services.PluginTransactionValidatorServiceImpl;
import org.hyperledger.besu.services.RpcEndpointServiceImpl;
import org.hyperledger.besu.services.SecurityModuleServiceImpl;
import org.hyperledger.besu.services.StorageServiceImpl;
import org.hyperledger.besu.services.TransactionSelectionServiceImpl;
import org.hyperledger.besu.services.TransactionSimulationServiceImpl;

import java.io.File;
import java.nio.file.Path;
Expand All @@ -70,7 +74,6 @@
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;

Expand All @@ -93,17 +96,27 @@ private BesuPluginContextImpl buildPluginContext(
final BesuNode node,
final StorageServiceImpl storageService,
final SecurityModuleServiceImpl securityModuleService,
final TransactionSimulationServiceImpl transactionSimulationServiceImpl,
final PluginTransactionValidatorServiceImpl transactionValidatorServiceImpl,
final TransactionSelectionServiceImpl transactionSelectionServiceImpl,
final BlockchainServiceImpl blockchainServiceImpl,
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final BesuConfiguration commonPluginConfiguration) {
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, new RpcEndpointServiceImpl());
besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl);
besuPluginContext.addService(
TransactionSelectionService.class, new TransactionSelectionServiceImpl());
TransactionSelectionService.class, transactionSelectionServiceImpl);
besuPluginContext.addService(
PluginTransactionValidatorService.class, new PluginTransactionValidatorServiceImpl());
PluginTransactionValidatorService.class, transactionValidatorServiceImpl);
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()) {
Expand All @@ -120,9 +133,6 @@ private BesuPluginContextImpl buildPluginContext(
besuPluginContext.registerPlugins(pluginsPath);

commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0]));

besuPluginContext.addService(BesuConfiguration.class, commonPluginConfiguration);

// register built-in plugins
new RocksDBPlugin().register(besuPluginContext);

Expand All @@ -143,15 +153,35 @@ public void startNode(final BesuNode node) {

final StorageServiceImpl storageService = new StorageServiceImpl();
final SecurityModuleServiceImpl securityModuleService = new SecurityModuleServiceImpl();
final TransactionSimulationServiceImpl transactionSimulationServiceImpl =
new TransactionSimulationServiceImpl();
final TransactionSelectionServiceImpl transactionSelectionServiceImpl =
new TransactionSelectionServiceImpl();
final PluginTransactionValidatorServiceImpl transactionValidatorServiceImpl =
new PluginTransactionValidatorServiceImpl();
final BlockchainServiceImpl blockchainServiceImpl = new BlockchainServiceImpl();
final RpcEndpointServiceImpl rpcEndpointServiceImpl = new RpcEndpointServiceImpl();
final Path dataDir = node.homeDirectory();
final BesuConfiguration commonPluginConfiguration =
new BesuConfigurationImpl(dataDir, dataDir.resolve(DATABASE_PATH));
final BesuConfigurationImpl commonPluginConfiguration = new BesuConfigurationImpl();
commonPluginConfiguration.init(
dataDir,
dataDir.resolve(DATABASE_PATH),
node.getDataStorageConfiguration(),
node.getMiningParameters());
final BesuPluginContextImpl besuPluginContext =
besuPluginContextMap.computeIfAbsent(
node,
n ->
buildPluginContext(
node, storageService, securityModuleService, commonPluginConfiguration));
node,
storageService,
securityModuleService,
transactionSimulationServiceImpl,
transactionValidatorServiceImpl,
transactionSelectionServiceImpl,
blockchainServiceImpl,
rpcEndpointServiceImpl,
commonPluginConfiguration));

GlobalOpenTelemetry.resetForTest();
final ObservableMetricsSystem metricsSystem =
Expand Down Expand Up @@ -188,11 +218,11 @@ public void startNode(final BesuNode node) {

final int maxPeers = 25;

final Optional<PluginTransactionSelectorFactory> transactionSelectorFactory =
getTransactionSelectorFactory(besuPluginContext);
final TransactionSelectionService transactionSelectorService =
getTransactionSelectorService(besuPluginContext);

final PluginTransactionValidatorFactory pluginTransactionValidatorFactory =
getPluginTransactionValidatorFactory(besuPluginContext);
final PluginTransactionValidatorService pluginTransactionValidatorService =
getPluginTransactionValidatorService(besuPluginContext);
builder
.synchronizerConfiguration(new SynchronizerConfiguration.Builder().build())
.dataDirectory(node.homeDirectory())
Expand All @@ -214,15 +244,19 @@ public void startNode(final BesuNode node) {
.maxRemotelyInitiatedPeers(15)
.networkConfiguration(node.getNetworkingConfiguration())
.randomPeerPriority(false)
.transactionSelectorFactory(transactionSelectorFactory)
.pluginTransactionValidatorFactory(pluginTransactionValidatorFactory);
.transactionSelectorService(transactionSelectorService)
.pluginTransactionValidatorService(pluginTransactionValidatorService);

node.getGenesisConfig()
.map(GenesisConfigFile::fromConfig)
.ifPresent(builder::genesisConfigFile);

final BesuController besuController = builder.build();

initTransactionSimulationService(
transactionSimulationServiceImpl, besuController, node.getApiConfiguration());
initBlockchainService(blockchainServiceImpl, besuController);

final RunnerBuilder runnerBuilder = new RunnerBuilder();
runnerBuilder.permissioningConfiguration(node.getPermissioningConfiguration());
runnerBuilder.apiConfiguration(node.getApiConfiguration());
Expand Down Expand Up @@ -252,7 +286,7 @@ public void startNode(final BesuNode node) {
.besuPluginContext(new BesuPluginContextImpl())
.autoLogBloomCaching(false)
.storageProvider(storageProvider)
.rpcEndpointService(new RpcEndpointServiceImpl());
.rpcEndpointService(rpcEndpointServiceImpl);
node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration);

final Runner runner = runnerBuilder.build();
Expand All @@ -276,6 +310,25 @@ public void startNode(final BesuNode node) {
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);
Expand Down Expand Up @@ -326,17 +379,15 @@ public String getConsoleContents() {
throw new RuntimeException("Console contents can only be captured in process execution");
}

private Optional<PluginTransactionSelectorFactory> getTransactionSelectorFactory(
private TransactionSelectionService getTransactionSelectorService(
final BesuPluginContextImpl besuPluginContext) {
final Optional<TransactionSelectionService> txSelectionService =
besuPluginContext.getService(TransactionSelectionService.class);
return txSelectionService.isPresent() ? txSelectionService.get().get() : Optional.empty();
return besuPluginContext.getService(TransactionSelectionService.class).orElseThrow();
}

private PluginTransactionValidatorFactory getPluginTransactionValidatorFactory(
private PluginTransactionValidatorService getPluginTransactionValidatorService(
final BesuPluginContextImpl besuPluginContext) {
final Optional<PluginTransactionValidatorService> txValidatorService =
besuPluginContext.getService(PluginTransactionValidatorService.class);
return txValidatorService.map(PluginTransactionValidatorService::get).orElse(null);
return besuPluginContext
.getService(org.hyperledger.besu.plugin.services.PluginTransactionValidatorService.class)
.orElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration;
import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider;
Expand All @@ -48,6 +49,7 @@ public class BesuNodeConfiguration {
private final MetricsConfiguration metricsConfiguration;
private final Optional<PermissioningConfiguration> permissioningConfiguration;
private final ApiConfiguration apiConfiguration;
private final DataStorageConfiguration dataStorageConfiguration;
private final Optional<String> keyFilePath;
private final boolean devMode;
private final GenesisConfigurationProvider genesisConfigProvider;
Expand Down Expand Up @@ -84,6 +86,7 @@ public class BesuNodeConfiguration {
final MetricsConfiguration metricsConfiguration,
final Optional<PermissioningConfiguration> permissioningConfiguration,
final ApiConfiguration apiConfiguration,
final DataStorageConfiguration dataStorageConfiguration,
final Optional<String> keyFilePath,
final boolean devMode,
final NetworkName network,
Expand Down Expand Up @@ -117,6 +120,7 @@ public class BesuNodeConfiguration {
this.metricsConfiguration = metricsConfiguration;
this.permissioningConfiguration = permissioningConfiguration;
this.apiConfiguration = apiConfiguration;
this.dataStorageConfiguration = dataStorageConfiguration;
this.keyFilePath = keyFilePath;
this.dataPath = dataPath;
this.devMode = devMode;
Expand Down Expand Up @@ -183,6 +187,10 @@ public ApiConfiguration getApiConfiguration() {
return apiConfiguration;
}

public DataStorageConfiguration getDataStorageConfiguration() {
return dataStorageConfiguration;
}

public Optional<String> getKeyFilePath() {
return keyFilePath;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.netty.TLSConfiguration;
import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.metrics.prometheus.MetricsConfiguration;
import org.hyperledger.besu.pki.config.PkiKeyStoreConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.genesis.GenesisConfigurationProvider;
Expand Down Expand Up @@ -73,6 +74,8 @@ public class BesuNodeConfigurationBuilder {
private MetricsConfiguration metricsConfiguration = MetricsConfiguration.builder().build();
private Optional<PermissioningConfiguration> permissioningConfiguration = Optional.empty();
private ApiConfiguration apiConfiguration = ImmutableApiConfiguration.builder().build();
private DataStorageConfiguration dataStorageConfiguration =
DataStorageConfiguration.DEFAULT_CONFIG;
private String keyFilePath = null;
private boolean devMode = true;
private GenesisConfigurationProvider genesisConfigProvider = ignore -> Optional.empty();
Expand Down Expand Up @@ -506,6 +509,12 @@ public BesuNodeConfigurationBuilder apiConfiguration(final ApiConfiguration apiC
return this;
}

public BesuNodeConfigurationBuilder dataStorageConfiguration(
final DataStorageConfiguration dataStorageConfiguration) {
this.dataStorageConfiguration = dataStorageConfiguration;
return this;
}

public BesuNodeConfiguration build() {
return new BesuNodeConfiguration(
name,
Expand All @@ -519,6 +528,7 @@ public BesuNodeConfiguration build() {
metricsConfiguration,
permissioningConfiguration,
apiConfiguration,
dataStorageConfiguration,
Optional.ofNullable(keyFilePath),
devMode,
network,
Expand Down
Loading

0 comments on commit b0f872c

Please sign in to comment.