Skip to content

Commit

Permalink
Add plugin API to select Transactions (hyperledger#5396)
Browse files Browse the repository at this point in the history
This API fulfils the basic requirements, but will probably be extended in the near future. 

Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
  • Loading branch information
pinges and macfarla authored May 23, 2023
1 parent f121f12 commit 65bcc55
Show file tree
Hide file tree
Showing 68 changed files with 534 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ public String getHostName() {
return LOCALHOST;
}

private NodeRequests nodeRequests() {
public NodeRequests nodeRequests() {
Optional<WebSocketService> websocketService = Optional.empty();
if (nodeRequests == null) {
final Web3jService web3jService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
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.storage.rocksdb.RocksDBPlugin;
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
import org.hyperledger.besu.services.BesuConfigurationImpl;
import org.hyperledger.besu.services.BesuEventsImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl;
Expand All @@ -54,6 +56,7 @@
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 java.io.File;
import java.nio.file.Path;
Expand All @@ -63,6 +66,7 @@
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 Down Expand Up @@ -91,14 +95,22 @@ private BesuPluginContextImpl buildPluginContext(
besuPluginContext.addService(StorageService.class, storageService);
besuPluginContext.addService(SecurityModuleService.class, securityModuleService);
besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));

final Path pluginsPath = node.homeDirectory().resolve("plugins");
final File pluginsDirFile = pluginsPath.toFile();
if (!pluginsDirFile.isDirectory()) {
pluginsDirFile.mkdirs();
pluginsDirFile.deleteOnExit();
besuPluginContext.addService(
TransactionSelectionService.class, new TransactionSelectionServiceImpl());

final Path pluginsPath;
final String pluginDirEnv = System.getenv("besu.plugins.dir");
if (pluginDirEnv == null || pluginDirEnv.isEmpty()) {
pluginsPath = node.homeDirectory().resolve("plugins");
final File pluginsDirFile = pluginsPath.toFile();
if (!pluginsDirFile.isDirectory()) {
pluginsDirFile.mkdirs();
pluginsDirFile.deleteOnExit();
}
} else {
pluginsPath = Path.of(pluginDirEnv);
System.setProperty("besu.plugins.dir", pluginsPath.toString());
}
System.setProperty("besu.plugins.dir", pluginsPath.toString());
besuPluginContext.registerPlugins(pluginsPath);

commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0]));
Expand Down Expand Up @@ -169,6 +181,9 @@ public void startNode(final BesuNode node) {

final int maxPeers = 25;

final Optional<TransactionSelectorFactory> transactionSelectorFactory =
getTransactionSelectorFactory(besuPluginContext);

builder
.synchronizerConfiguration(new SynchronizerConfiguration.Builder().build())
.dataDirectory(node.homeDirectory())
Expand All @@ -190,7 +205,8 @@ public void startNode(final BesuNode node) {
.lowerBoundPeers(maxPeers)
.maxRemotelyInitiatedPeers(15)
.networkConfiguration(node.getNetworkingConfiguration())
.randomPeerPriority(false);
.randomPeerPriority(false)
.transactionSelectorFactory(transactionSelectorFactory);

node.getGenesisConfig()
.map(GenesisConfigFile::fromConfig)
Expand Down Expand Up @@ -299,4 +315,11 @@ public void startConsoleCapture() {
public String getConsoleContents() {
throw new RuntimeException("Console contents can only be captured in process execution");
}

private Optional<TransactionSelectorFactory> getTransactionSelectorFactory(
final BesuPluginContextImpl besuPluginContext) {
final Optional<TransactionSelectionService> txSelectionService =
besuPluginContext.getService(TransactionSelectionService.class);
return txSelectionService.isPresent() ? txSelectionService.get().get() : Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,33 @@ public BesuNode createMinerNode(
return create(config);
}

public BesuNode createMinerNodeWithExtraCliOptions(
final String name,
final UnaryOperator<BesuNodeConfigurationBuilder> configModifier,
final List<String> extraCliOptions)
throws IOException {
BesuNodeConfigurationBuilder builder =
new BesuNodeConfigurationBuilder()
.name(name)
.miningEnabled()
.jsonRpcEnabled()
.webSocketEnabled()
.extraCLIOptions(extraCliOptions);
builder = configModifier.apply(builder);
final BesuNodeConfiguration config = builder.build();

return create(config);
}

public BesuNode createMinerNode(final String name) throws IOException {
return createMinerNode(name, UnaryOperator.identity());
}

public BesuNode createMinerNodeWithExtraCliOptions(
final String name, final List<String> extraCliOptions) throws IOException {
return createMinerNodeWithExtraCliOptions(name, UnaryOperator.identity(), extraCliOptions);
}

public BesuNode createMinerNodeWithRevertReasonEnabled(final String name) throws IOException {
return createMinerNode(name, BesuNodeConfigurationBuilder::revertReasonEnabled);
}
Expand Down
29 changes: 27 additions & 2 deletions besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,14 @@
import org.hyperledger.besu.plugin.services.SecurityModuleService;
import org.hyperledger.besu.plugin.services.StorageService;
import org.hyperledger.besu.plugin.services.TraceService;
import org.hyperledger.besu.plugin.services.TransactionSelectionService;
import org.hyperledger.besu.plugin.services.exception.StorageException;
import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;
import org.hyperledger.besu.plugin.services.securitymodule.SecurityModule;
import org.hyperledger.besu.plugin.services.storage.PrivacyKeyValueStorageFactory;
import org.hyperledger.besu.plugin.services.storage.rocksdb.RocksDBPlugin;
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
import org.hyperledger.besu.services.BesuEventsImpl;
import org.hyperledger.besu.services.BesuPluginContextImpl;
import org.hyperledger.besu.services.BlockchainServiceImpl;
Expand All @@ -183,6 +185,7 @@
import org.hyperledger.besu.services.SecurityModuleServiceImpl;
import org.hyperledger.besu.services.StorageServiceImpl;
import org.hyperledger.besu.services.TraceServiceImpl;
import org.hyperledger.besu.services.TransactionSelectionServiceImpl;
import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin;
import org.hyperledger.besu.util.InvalidConfigurationException;
import org.hyperledger.besu.util.LogConfigurator;
Expand Down Expand Up @@ -234,6 +237,7 @@
import io.vertx.core.metrics.MetricsOptions;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import picocli.AutoComplete;
import picocli.CommandLine;
Expand Down Expand Up @@ -360,6 +364,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
@CommandLine.ArgGroup(validate = false, heading = "@|bold P2P Discovery Options|@%n")
P2PDiscoveryOptionGroup p2PDiscoveryOptionGroup = new P2PDiscoveryOptionGroup();

private final TransactionSelectionServiceImpl transactionSelectionServiceImpl;

static class P2PDiscoveryOptionGroup {

// Public IP stored to prevent having to research it each time we need it.
Expand Down Expand Up @@ -1380,7 +1386,8 @@ public BesuCommand(
new PermissioningServiceImpl(),
new PrivacyPluginServiceImpl(),
new PkiBlockCreationConfigurationProvider(),
new RpcEndpointServiceImpl());
new RpcEndpointServiceImpl(),
new TransactionSelectionServiceImpl());
}

/**
Expand All @@ -1400,6 +1407,7 @@ public BesuCommand(
* @param privacyPluginService instance of PrivacyPluginServiceImpl
* @param pkiBlockCreationConfigProvider instance of PkiBlockCreationConfigurationProvider
* @param rpcEndpointServiceImpl instance of RpcEndpointServiceImpl
* @param transactionSelectionServiceImpl instance of TransactionSelectionServiceImpl
*/
@VisibleForTesting
protected BesuCommand(
Expand All @@ -1416,7 +1424,8 @@ protected BesuCommand(
final PermissioningServiceImpl permissioningService,
final PrivacyPluginServiceImpl privacyPluginService,
final PkiBlockCreationConfigurationProvider pkiBlockCreationConfigProvider,
final RpcEndpointServiceImpl rpcEndpointServiceImpl) {
final RpcEndpointServiceImpl rpcEndpointServiceImpl,
final TransactionSelectionServiceImpl transactionSelectionServiceImpl) {
this.besuComponent = besuComponent;
this.logger = besuComponent.getBesuCommandLogger();
this.rlpBlockImporter = rlpBlockImporter;
Expand All @@ -1434,6 +1443,7 @@ protected BesuCommand(
besuPluginContext.addService(BesuConfiguration.class, pluginCommonConfiguration);
this.pkiBlockCreationConfigProvider = pkiBlockCreationConfigProvider;
this.rpcEndpointServiceImpl = rpcEndpointServiceImpl;
this.transactionSelectionServiceImpl = transactionSelectionServiceImpl;
}

/**
Expand Down Expand Up @@ -1614,6 +1624,8 @@ private void preparePlugins() {
besuPluginContext.addService(PermissioningService.class, permissioningService);
besuPluginContext.addService(PrivacyPluginService.class, privacyPluginService);
besuPluginContext.addService(RpcEndpointService.class, rpcEndpointServiceImpl);
besuPluginContext.addService(
TransactionSelectionService.class, transactionSelectionServiceImpl);

// register built-in plugins
rocksDBPlugin = new RocksDBPlugin();
Expand Down Expand Up @@ -1715,6 +1727,9 @@ private void startPlugins() {
besuController.getProtocolContext().getWorldStateArchive()),
besuController.getProtocolSchedule()));

besuPluginContext.addService(
TransactionSelectionService.class, new TransactionSelectionServiceImpl());

besuController.getAdditionalPluginServices().appendPluginServices(besuPluginContext);
besuPluginContext.startPlugins();
}
Expand Down Expand Up @@ -2241,12 +2256,15 @@ public BesuController buildController() {
*/
public BesuControllerBuilder getControllerBuilder() {
final KeyValueStorageProvider storageProvider = keyValueStorageProvider(keyValueStorageName);
final Optional<TransactionSelectorFactory> transactionSelectorFactory =
getTransactionSelectorFactory();
return controllerBuilderFactory
.fromEthNetworkConfig(
updateNetworkConfig(network), genesisConfigOverrides, getDefaultSyncModeIfNotSet())
.synchronizerConfiguration(buildSyncConfig())
.ethProtocolConfiguration(unstableEthProtocolOptions.toDomainObject())
.networkConfiguration(unstableNetworkingOptions.toDomainObject())
.transactionSelectorFactory(transactionSelectorFactory)
.dataDirectory(dataDir())
.miningParameters(
new MiningParameters.Builder()
Expand Down Expand Up @@ -2296,6 +2314,13 @@ public BesuControllerBuilder getControllerBuilder() {
.chainPruningConfiguration(unstableChainPruningOptions.toDomainObject());
}

@NotNull
private Optional<TransactionSelectorFactory> getTransactionSelectorFactory() {
final Optional<TransactionSelectionService> txSelectionService =
besuPluginContext.getService(TransactionSelectionService.class);
return txSelectionService.isPresent() ? txSelectionService.get().get() : Optional.empty();
}

private GraphQLConfiguration graphQLConfiguration() {

CommandLineUtils.checkOptionDependencies(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;

import java.io.Closeable;
import java.math.BigInteger;
Expand Down Expand Up @@ -179,6 +180,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides

private NetworkingConfiguration networkingConfiguration;
private Boolean randomPeerPriority;
private Optional<TransactionSelectorFactory> transactionSelectorFactory = Optional.empty();
/** the Dagger configured context that can provide dependencies */
protected Optional<BesuComponent> besuComponent = Optional.empty();

Expand Down Expand Up @@ -522,6 +524,18 @@ public BesuControllerBuilder randomPeerPriority(final Boolean randomPeerPriority
return this;
}

/**
* sets the transactionSelectorFactory in the builder
*
* @param transactionSelectorFactory the optional transaction selector factory
* @return the besu controller builder
*/
public BesuControllerBuilder transactionSelectorFactory(
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
this.transactionSelectorFactory = transactionSelectorFactory;
return this;
}

/**
* Build besu controller.
*
Expand Down Expand Up @@ -575,7 +589,11 @@ public BesuController build() {

final ProtocolContext protocolContext =
createProtocolContext(
blockchain, worldStateArchive, protocolSchedule, this::createConsensusContext);
blockchain,
worldStateArchive,
protocolSchedule,
this::createConsensusContext,
transactionSelectorFactory);
validateContext(protocolContext);

if (chainPrunerConfiguration.getChainPruningEnabled()) {
Expand Down Expand Up @@ -991,15 +1009,21 @@ protected EthProtocolManager createEthProtocolManager(
* @param worldStateArchive the world state archive
* @param protocolSchedule the protocol schedule
* @param consensusContextFactory the consensus context factory
* @param transactionSelectorFactory optional transaction selector factory
* @return the protocol context
*/
protected ProtocolContext createProtocolContext(
final MutableBlockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final ConsensusContextFactory consensusContextFactory) {
final ConsensusContextFactory consensusContextFactory,
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
return ProtocolContext.init(
blockchain, worldStateArchive, protocolSchedule, consensusContextFactory);
blockchain,
worldStateArchive,
protocolSchedule,
consensusContextFactory,
transactionSelectorFactory);
}

private Optional<SnapProtocolManager> createSnapProtocolManager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;

import java.math.BigInteger;
import java.nio.file.Path;
Expand Down Expand Up @@ -174,9 +175,14 @@ protected ProtocolContext createProtocolContext(
final MutableBlockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final ConsensusContextFactory consensusContextFactory) {
final ConsensusContextFactory consensusContextFactory,
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
return MigratingProtocolContext.init(
blockchain, worldStateArchive, protocolSchedule, consensusContextFactory);
blockchain,
worldStateArchive,
protocolSchedule,
consensusContextFactory,
transactionSelectorFactory);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;

import java.math.BigInteger;
import java.nio.file.Path;
Expand Down Expand Up @@ -188,10 +189,15 @@ protected ProtocolContext createProtocolContext(
final MutableBlockchain blockchain,
final WorldStateArchive worldStateArchive,
final ProtocolSchedule protocolSchedule,
final ConsensusContextFactory consensusContextFactory) {
final ConsensusContextFactory consensusContextFactory,
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
final ProtocolContext protocolContext =
super.createProtocolContext(
blockchain, worldStateArchive, protocolSchedule, consensusContextFactory);
blockchain,
worldStateArchive,
protocolSchedule,
consensusContextFactory,
transactionSelectorFactory);
transitionProtocolSchedule.setProtocolContext(protocolContext);
return protocolContext;
}
Expand Down
Loading

0 comments on commit 65bcc55

Please sign in to comment.