Skip to content

Commit

Permalink
Transaction simulation service
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 committed Mar 6, 2024
1 parent 244c814 commit 61b49ab
Show file tree
Hide file tree
Showing 37 changed files with 406 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -436,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
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.core.ImmutableMiningParameters;
import org.hyperledger.besu.ethereum.eth.EthProtocolConfiguration;
Expand All @@ -37,30 +38,35 @@
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.worldstate.DataStorageConfiguration;
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.RpcEndpointService;
import org.hyperledger.besu.plugin.services.SecurityModuleService;
import org.hyperledger.besu.plugin.services.StorageService;
import org.hyperledger.besu.plugin.services.TransactionPoolValidatorService;
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.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.RpcEndpointServiceImpl;
import org.hyperledger.besu.services.SecurityModuleServiceImpl;
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 java.io.File;
import java.nio.file.Path;
Expand Down Expand Up @@ -92,18 +98,27 @@ 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 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, transactionSelectionServiceImpl);
besuPluginContext.addService(
TransactionPoolValidatorService.class, new TransactionPoolValidatorServiceImpl());
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()) {
Expand All @@ -120,9 +135,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,8 +155,14 @@ 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 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 var miningParameters =
Expand All @@ -165,7 +183,11 @@ public void startNode(final BesuNode node) {
node,
storageService,
securityModuleService,
transactionSimulationServiceImpl,
transactionSelectionServiceImpl,
transactionPoolValidatorServiceImpl,
blockchainServiceImpl,
rpcEndpointServiceImpl,
commonPluginConfiguration));

GlobalOpenTelemetry.resetForTest();
Expand Down Expand Up @@ -199,6 +221,7 @@ public void startNode(final BesuNode node) {
ImmutableTransactionPoolConfiguration.builder()
.from(node.getTransactionPoolConfiguration())
.strictTransactionReplayProtectionEnabled(node.isStrictTxReplayProtectionEnabled())
.transactionPoolValidatorService(transactionPoolValidatorServiceImpl)
.build();

final int maxPeers = 25;
Expand Down Expand Up @@ -232,6 +255,10 @@ public void startNode(final BesuNode node) {

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 @@ -261,7 +288,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 @@ -285,6 +312,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
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.UnaryOperator;

import io.vertx.core.Vertx;
Expand Down Expand Up @@ -376,17 +377,27 @@ public BesuNode createCliqueNode(final String name) throws IOException {

public BesuNode createCliqueNode(final String name, final CliqueOptions cliqueOptions)
throws IOException {
return createCliqueNodeWithExtraCliOptions(name, cliqueOptions, List.of());
return createCliqueNodeWithExtraCliOptionsAndRpcApis(name, cliqueOptions, List.of());
}

public BesuNode createCliqueNodeWithExtraCliOptions(
public BesuNode createCliqueNodeWithExtraCliOptionsAndRpcApis(
final String name, final CliqueOptions cliqueOptions, final List<String> extraCliOptions)
throws IOException {
return createCliqueNodeWithExtraCliOptionsAndRpcApis(
name, cliqueOptions, extraCliOptions, Set.of());
}

public BesuNode createCliqueNodeWithExtraCliOptionsAndRpcApis(
final String name,
final CliqueOptions cliqueOptions,
final List<String> extraCliOptions,
final Set<String> extraRpcApis)
throws IOException {
return create(
new BesuNodeConfigurationBuilder()
.name(name)
.miningEnabled()
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig())
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig(extraRpcApis))
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.devMode(false)
.jsonRpcTxPool()
Expand Down Expand Up @@ -584,7 +595,7 @@ public BesuNode createCliqueNodeWithValidators(final String name, final String..
new BesuNodeConfigurationBuilder()
.name(name)
.miningEnabled()
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig())
.jsonRpcConfiguration(node.createJsonRpcWithCliqueEnabledConfig(Set.of()))
.webSocketConfiguration(node.createWebSocketEnabledConfig())
.jsonRpcTxPool()
.devMode(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

public class NodeConfigurationFactory {

Expand All @@ -44,8 +46,10 @@ public Optional<String> createGenesisConfigForValidators(
return genesisConfigProvider.create(nodes);
}

public JsonRpcConfiguration createJsonRpcWithCliqueEnabledConfig() {
return createJsonRpcWithRpcApiEnabledConfig(CLIQUE.name());
public JsonRpcConfiguration createJsonRpcWithCliqueEnabledConfig(final Set<String> extraRpcApis) {
final var enabledApis = new HashSet<>(extraRpcApis);
enabledApis.add(CLIQUE.name());
return createJsonRpcWithRpcApiEnabledConfig(enabledApis.toArray(String[]::new));
}

public JsonRpcConfiguration createJsonRpcWithIbft2EnabledConfig(final boolean minerEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
import java.util.Optional;

import org.web3j.protocol.Web3j;
import org.web3j.protocol.Web3jService;
import org.web3j.protocol.websocket.WebSocketService;

public class NodeRequests {

private final Web3jService web3jService;
private final Web3j netEth;
private final CliqueRequestFactory clique;
private final BftRequestFactory bft;
Expand All @@ -44,6 +45,7 @@ public class NodeRequests {
private final TxPoolRequestFactory txPool;

public NodeRequests(
final Web3jService web3jService,
final Web3j netEth,
final CliqueRequestFactory clique,
final BftRequestFactory bft,
Expand All @@ -55,6 +57,7 @@ public NodeRequests(
final TxPoolRequestFactory txPool,
final Optional<WebSocketService> websocketService,
final LoginRequestFactory login) {
this.web3jService = web3jService;
this.netEth = netEth;
this.clique = clique;
this.bft = bft;
Expand Down Expand Up @@ -116,4 +119,8 @@ public void shutdown() {
netEth.shutdown();
websocketService.ifPresent(WebSocketService::close);
}

public Web3jService getWeb3jService() {
return web3jService;
}
}
2 changes: 2 additions & 0 deletions besu/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jar {
}

dependencies {
api project(':datatypes')

api 'org.slf4j:slf4j-api'

implementation project(':config')
Expand Down
17 changes: 17 additions & 0 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
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.forest.pruner.PrunerConfiguration;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.evm.precompile.AbstractAltBnPrecompiledContract;
Expand Down Expand Up @@ -167,6 +168,7 @@
import org.hyperledger.besu.plugin.services.TraceService;
import org.hyperledger.besu.plugin.services.TransactionPoolValidatorService;
import org.hyperledger.besu.plugin.services.TransactionSelectionService;
import org.hyperledger.besu.plugin.services.TransactionSimulationService;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
Expand All @@ -187,6 +189,7 @@
import org.hyperledger.besu.services.TraceServiceImpl;
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 org.hyperledger.besu.util.InvalidConfigurationException;
import org.hyperledger.besu.util.LogConfigurator;
Expand Down Expand Up @@ -370,6 +373,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {

private final TransactionSelectionServiceImpl transactionSelectionServiceImpl;
private final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl;
private final TransactionSimulationServiceImpl transactionSimulationServiceImpl;
private final BlockchainServiceImpl blockchainServiceImpl;

static class P2PDiscoveryOptionGroup {
Expand Down Expand Up @@ -956,6 +960,7 @@ public BesuCommand(
new RpcEndpointServiceImpl(),
new TransactionSelectionServiceImpl(),
new TransactionPoolValidatorServiceImpl(),
new TransactionSimulationServiceImpl(),
new BlockchainServiceImpl());
}

Expand All @@ -978,6 +983,7 @@ public BesuCommand(
* @param rpcEndpointServiceImpl instance of RpcEndpointServiceImpl
* @param transactionSelectionServiceImpl instance of TransactionSelectionServiceImpl
* @param transactionValidatorServiceImpl instance of TransactionValidatorServiceImpl
* @param transactionSimulationServiceImpl instance of TransactionSimulationServiceImpl
* @param blockchainServiceImpl instance of BlockchainServiceImpl
*/
@VisibleForTesting
Expand All @@ -998,6 +1004,7 @@ protected BesuCommand(
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final TransactionSelectionServiceImpl transactionSelectionServiceImpl,
final TransactionPoolValidatorServiceImpl transactionValidatorServiceImpl,
final TransactionSimulationServiceImpl transactionSimulationServiceImpl,
final BlockchainServiceImpl blockchainServiceImpl) {
this.besuComponent = besuComponent;
this.logger = besuComponent.getBesuCommandLogger();
Expand All @@ -1018,6 +1025,7 @@ protected BesuCommand(
this.rpcEndpointServiceImpl = rpcEndpointServiceImpl;
this.transactionSelectionServiceImpl = transactionSelectionServiceImpl;
this.transactionValidatorServiceImpl = transactionValidatorServiceImpl;
this.transactionSimulationServiceImpl = transactionSimulationServiceImpl;
this.blockchainServiceImpl = blockchainServiceImpl;
}

Expand Down Expand Up @@ -1210,6 +1218,8 @@ private void preparePlugins() {
TransactionSelectionService.class, transactionSelectionServiceImpl);
besuPluginContext.addService(
TransactionPoolValidatorService.class, transactionValidatorServiceImpl);
besuPluginContext.addService(
TransactionSimulationService.class, transactionSimulationServiceImpl);
besuPluginContext.addService(BlockchainService.class, blockchainServiceImpl);

// register built-in plugins
Expand Down Expand Up @@ -1293,6 +1303,13 @@ private Runner buildRunner() {
private void startPlugins() {
blockchainServiceImpl.init(
besuController.getProtocolContext(), besuController.getProtocolSchedule());
transactionSimulationServiceImpl.init(
besuController.getProtocolContext().getBlockchain(),
new TransactionSimulator(
besuController.getProtocolContext().getBlockchain(),
besuController.getProtocolContext().getWorldStateArchive(),
besuController.getProtocolSchedule(),
apiConfiguration.getGasCap()));

besuPluginContext.addService(
BesuEvents.class,
Expand Down
Loading

0 comments on commit 61b49ab

Please sign in to comment.