mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 15:37:54 -05:00
Revert the revert of the tx selection commit (#5507)
* Revert "Revert "Add plugin API to select Transactions (#5396)" (#5499)"
This reverts commit a0c6052778.
* fix receipt root bug
Signed-off-by: Stefan <stefan.pingel@consensys.net>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: Usman Saleem <usman@usmans.info>
Signed-off-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
Co-authored-by: Simon Dudley <simon.dudley@consensys.net>
Co-authored-by: Usman Saleem <usman@usmans.info>
This commit is contained in:
@@ -386,7 +386,7 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
|
||||
return LOCALHOST;
|
||||
}
|
||||
|
||||
private NodeRequests nodeRequests() {
|
||||
public NodeRequests nodeRequests() {
|
||||
Optional<WebSocketService> websocketService = Optional.empty();
|
||||
if (nodeRequests == null) {
|
||||
final Web3jService web3jService;
|
||||
|
||||
@@ -45,7 +45,9 @@ import org.hyperledger.besu.plugin.services.BesuEvents;
|
||||
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;
|
||||
@@ -54,6 +56,7 @@ 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.TransactionSelectionServiceImpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
@@ -63,6 +66,7 @@ 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;
|
||||
|
||||
@@ -91,14 +95,22 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
besuPluginContext.addService(StorageService.class, storageService);
|
||||
besuPluginContext.addService(SecurityModuleService.class, securityModuleService);
|
||||
besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
|
||||
besuPluginContext.addService(
|
||||
TransactionSelectionService.class, new TransactionSelectionServiceImpl());
|
||||
|
||||
final Path pluginsPath = node.homeDirectory().resolve("plugins");
|
||||
final File pluginsDirFile = pluginsPath.toFile();
|
||||
if (!pluginsDirFile.isDirectory()) {
|
||||
pluginsDirFile.mkdirs();
|
||||
pluginsDirFile.deleteOnExit();
|
||||
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);
|
||||
}
|
||||
System.setProperty("besu.plugins.dir", pluginsPath.toString());
|
||||
besuPluginContext.registerPlugins(pluginsPath);
|
||||
|
||||
commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0]));
|
||||
@@ -169,6 +181,9 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
|
||||
final int maxPeers = 25;
|
||||
|
||||
final Optional<TransactionSelectorFactory> transactionSelectorFactory =
|
||||
getTransactionSelectorFactory(besuPluginContext);
|
||||
|
||||
builder
|
||||
.synchronizerConfiguration(new SynchronizerConfiguration.Builder().build())
|
||||
.dataDirectory(node.homeDirectory())
|
||||
@@ -190,7 +205,8 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
.lowerBoundPeers(maxPeers)
|
||||
.maxRemotelyInitiatedPeers(15)
|
||||
.networkConfiguration(node.getNetworkingConfiguration())
|
||||
.randomPeerPriority(false);
|
||||
.randomPeerPriority(false)
|
||||
.transactionSelectorFactory(transactionSelectorFactory);
|
||||
|
||||
node.getGenesisConfig()
|
||||
.map(GenesisConfigFile::fromConfig)
|
||||
@@ -299,4 +315,11 @@ public class ThreadBesuNodeRunner implements BesuNodeRunner {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,10 +107,33 @@ public class BesuNodeFactory {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -168,12 +168,14 @@ 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.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;
|
||||
@@ -184,6 +186,7 @@ import org.hyperledger.besu.services.RpcEndpointServiceImpl;
|
||||
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;
|
||||
@@ -235,6 +238,7 @@ import io.vertx.core.json.DecodeException;
|
||||
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;
|
||||
@@ -361,6 +365,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.
|
||||
@@ -1417,7 +1423,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
new PermissioningServiceImpl(),
|
||||
new PrivacyPluginServiceImpl(),
|
||||
new PkiBlockCreationConfigurationProvider(),
|
||||
new RpcEndpointServiceImpl());
|
||||
new RpcEndpointServiceImpl(),
|
||||
new TransactionSelectionServiceImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1437,6 +1444,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
* @param privacyPluginService instance of PrivacyPluginServiceImpl
|
||||
* @param pkiBlockCreationConfigProvider instance of PkiBlockCreationConfigurationProvider
|
||||
* @param rpcEndpointServiceImpl instance of RpcEndpointServiceImpl
|
||||
* @param transactionSelectionServiceImpl instance of TransactionSelectionServiceImpl
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected BesuCommand(
|
||||
@@ -1453,7 +1461,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
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;
|
||||
@@ -1471,6 +1480,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
besuPluginContext.addService(BesuConfiguration.class, pluginCommonConfiguration);
|
||||
this.pkiBlockCreationConfigProvider = pkiBlockCreationConfigProvider;
|
||||
this.rpcEndpointServiceImpl = rpcEndpointServiceImpl;
|
||||
this.transactionSelectionServiceImpl = transactionSelectionServiceImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1651,6 +1661,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
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();
|
||||
@@ -2278,12 +2290,15 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
*/
|
||||
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()
|
||||
@@ -2333,6 +2348,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
|
||||
.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(
|
||||
|
||||
@@ -94,6 +94,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
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;
|
||||
@@ -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();
|
||||
|
||||
@@ -522,6 +524,18 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
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.
|
||||
*
|
||||
@@ -575,7 +589,11 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
|
||||
final ProtocolContext protocolContext =
|
||||
createProtocolContext(
|
||||
blockchain, worldStateArchive, protocolSchedule, this::createConsensusContext);
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
protocolSchedule,
|
||||
this::createConsensusContext,
|
||||
transactionSelectorFactory);
|
||||
validateContext(protocolContext);
|
||||
|
||||
if (chainPrunerConfiguration.getChainPruningEnabled()) {
|
||||
@@ -991,15 +1009,21 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
|
||||
* @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(
|
||||
|
||||
@@ -62,6 +62,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
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;
|
||||
@@ -174,9 +175,14 @@ public class ConsensusScheduleBesuControllerBuilder extends BesuControllerBuilde
|
||||
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
|
||||
|
||||
@@ -60,6 +60,7 @@ import org.hyperledger.besu.ethereum.worldstate.WorldStateStorage;
|
||||
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;
|
||||
@@ -188,10 +189,15 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.services;
|
||||
|
||||
import org.hyperledger.besu.plugin.services.TransactionSelectionService;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** The Transaction Selection service implementation. */
|
||||
public class TransactionSelectionServiceImpl implements TransactionSelectionService {
|
||||
|
||||
private Optional<TransactionSelectorFactory> factory = Optional.empty();
|
||||
|
||||
@Override
|
||||
public Optional<TransactionSelectorFactory> get() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTransactionSelectorFactory(
|
||||
final TransactionSelectorFactory transactionSelectorFactory) {
|
||||
factory = Optional.ofNullable(transactionSelectorFactory);
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ import org.hyperledger.besu.services.PrivacyPluginServiceImpl;
|
||||
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.kvstore.InMemoryKeyValueStorage;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -237,6 +238,7 @@ public abstract class CommandTestAbstract {
|
||||
when(mockControllerBuilder.lowerBoundPeers(anyInt())).thenReturn(mockControllerBuilder);
|
||||
when(mockControllerBuilder.maxRemotelyInitiatedPeers(anyInt()))
|
||||
.thenReturn(mockControllerBuilder);
|
||||
when(mockControllerBuilder.transactionSelectorFactory(any())).thenReturn(mockControllerBuilder);
|
||||
when(mockControllerBuilder.besuComponent(any(BesuComponent.class)))
|
||||
.thenReturn(mockControllerBuilder);
|
||||
// doReturn used because of generic BesuController
|
||||
@@ -484,7 +486,8 @@ public abstract class CommandTestAbstract {
|
||||
new PermissioningServiceImpl(),
|
||||
privacyPluginService,
|
||||
pkiBlockCreationConfigProvider,
|
||||
rpcEndpointServiceImpl);
|
||||
rpcEndpointServiceImpl,
|
||||
new TransactionSelectionServiceImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -57,7 +58,7 @@ public class CliqueDifficultyCalculatorTest {
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext, Optional.empty());
|
||||
blockHeaderBuilder = new BlockHeaderTestFixture();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -79,7 +80,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.number(1).parentHash(genesisBlock.getHash());
|
||||
final Block block_1 = createEmptyBlock(proposerKeyPair);
|
||||
@@ -103,7 +104,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.number(1).parentHash(genesisBlock.getHash());
|
||||
final Block block_1 = createEmptyBlock(proposerKeyPair);
|
||||
@@ -136,7 +137,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.parentHash(genesisBlock.getHash()).number(1);
|
||||
final Block block_1 = createEmptyBlock(proposerKeyPair);
|
||||
@@ -165,7 +166,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.parentHash(genesisBlock.getHash()).number(1);
|
||||
final Block block_1 = createEmptyBlock(proposerKeyPair);
|
||||
@@ -209,7 +210,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.parentHash(genesisBlock.getHash()).number(1);
|
||||
final Block block_1 = createEmptyBlock(otherNodeKeyPair);
|
||||
@@ -237,7 +238,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.parentHash(Hash.ZERO).number(3);
|
||||
final BlockHeader parentHeader =
|
||||
@@ -260,7 +261,7 @@ public class NodeCanProduceNextBlockTest {
|
||||
final ValidatorProvider validatorProvider = mock(ValidatorProvider.class);
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(blockChain, null, cliqueContext, Optional.empty());
|
||||
|
||||
headerBuilder.parentHash(Hash.ZERO).number(3);
|
||||
final BlockHeader parentHeader = headerBuilder.buildHeader();
|
||||
|
||||
@@ -105,7 +105,8 @@ public class CliqueBlockCreatorTest {
|
||||
final Block genesis =
|
||||
GenesisState.fromConfig(GenesisConfigFile.mainnet(), protocolSchedule).getBlock();
|
||||
blockchain = createInMemoryBlockchain(genesis);
|
||||
protocolContext = new ProtocolContext(blockchain, stateArchive, cliqueContext);
|
||||
protocolContext =
|
||||
new ProtocolContext(blockchain, stateArchive, cliqueContext, Optional.empty());
|
||||
epochManager = new EpochManager(10);
|
||||
|
||||
// Add a block above the genesis
|
||||
|
||||
@@ -81,7 +81,7 @@ public class CliqueMinerExecutorTest {
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext, Optional.empty());
|
||||
blockHeaderBuilder = new BlockHeaderTestFixture();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.core.Difficulty;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -57,7 +58,7 @@ public class CliqueDifficultyValidationRuleTest {
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext, Optional.empty());
|
||||
blockHeaderBuilder = new BlockHeaderTestFixture();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
@@ -61,7 +62,7 @@ public class CliqueExtraDataValidationRuleTest {
|
||||
when(validatorProvider.getValidatorsAfterBlock(any())).thenReturn(validatorList);
|
||||
|
||||
final CliqueContext cliqueContext = new CliqueContext(validatorProvider, null, blockInterface);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext);
|
||||
cliqueProtocolContext = new ProtocolContext(null, null, cliqueContext, Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,6 +20,9 @@ import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** The Migrating protocol context. */
|
||||
public class MigratingProtocolContext extends ProtocolContext {
|
||||
@@ -32,12 +35,14 @@ public class MigratingProtocolContext extends ProtocolContext {
|
||||
* @param blockchain the blockchain
|
||||
* @param worldStateArchive the world state archive
|
||||
* @param consensusContextSchedule the consensus context schedule
|
||||
* @param transactionSelectorFactory the optional transaction selector factory
|
||||
*/
|
||||
public MigratingProtocolContext(
|
||||
final MutableBlockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final ForksSchedule<ConsensusContext> consensusContextSchedule) {
|
||||
super(blockchain, worldStateArchive, null);
|
||||
final ForksSchedule<ConsensusContext> consensusContextSchedule,
|
||||
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
|
||||
super(blockchain, worldStateArchive, null, transactionSelectorFactory);
|
||||
this.consensusContextSchedule = consensusContextSchedule;
|
||||
}
|
||||
|
||||
@@ -48,18 +53,23 @@ public class MigratingProtocolContext extends ProtocolContext {
|
||||
* @param worldStateArchive the world state archive
|
||||
* @param protocolSchedule the protocol schedule
|
||||
* @param consensusContextFactory the consensus context factory
|
||||
* @param transactionSelectorFactory the optional transaction selector factory
|
||||
* @return the protocol context
|
||||
*/
|
||||
public static ProtocolContext init(
|
||||
final MutableBlockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final ConsensusContextFactory consensusContextFactory) {
|
||||
final ConsensusContextFactory consensusContextFactory,
|
||||
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
|
||||
final ConsensusContext consensusContext =
|
||||
consensusContextFactory.create(blockchain, worldStateArchive, protocolSchedule);
|
||||
final MigratingContext migratingContext = consensusContext.as(MigratingContext.class);
|
||||
return new MigratingProtocolContext(
|
||||
blockchain, worldStateArchive, migratingContext.getConsensusContextSchedule());
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
migratingContext.getConsensusContextSchedule(),
|
||||
transactionSelectorFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
@@ -43,7 +44,8 @@ public class MigratingProtocolContextTest {
|
||||
final ForksSchedule<ConsensusContext> contextSchedule =
|
||||
new ForksSchedule<>(List.of(new ForkSpec<>(0L, context1), new ForkSpec<>(10L, context2)));
|
||||
final MigratingProtocolContext migratingProtocolContext =
|
||||
new MigratingProtocolContext(blockchain, worldStateArchive, contextSchedule);
|
||||
new MigratingProtocolContext(
|
||||
blockchain, worldStateArchive, contextSchedule, Optional.empty());
|
||||
|
||||
assertThat(migratingProtocolContext.getConsensusContext(ConsensusContext.class))
|
||||
.isSameAs(context1);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
|
||||
import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Test;
|
||||
@@ -50,7 +51,7 @@ public class BftCoinbaseValidationRuleTest {
|
||||
final List<Address> validators = Lists.newArrayList(proposerAddress);
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(null, null, setupContextWithValidators(validators));
|
||||
new ProtocolContext(null, null, setupContextWithValidators(validators), Optional.empty());
|
||||
|
||||
final BftCoinbaseValidationRule coinbaseValidationRule = new BftCoinbaseValidationRule();
|
||||
|
||||
@@ -70,7 +71,7 @@ public class BftCoinbaseValidationRuleTest {
|
||||
final List<Address> validators = Lists.newArrayList(otherValidatorNodeAddress);
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(null, null, setupContextWithValidators(validators));
|
||||
new ProtocolContext(null, null, setupContextWithValidators(validators), Optional.empty());
|
||||
|
||||
final BftCoinbaseValidationRule coinbaseValidationRule = new BftCoinbaseValidationRule();
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.core.Util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@@ -57,7 +58,7 @@ public class BftCommitSealsValidationRuleTest {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final BftContext bftContext = setupContextWithValidators(committerAddresses);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext, Optional.empty());
|
||||
when(bftContext.getBlockInterface().getCommitters(any())).thenReturn(committerAddresses);
|
||||
|
||||
assertThat(commitSealsValidationRule.validate(blockHeader, null, context)).isTrue();
|
||||
@@ -71,7 +72,7 @@ public class BftCommitSealsValidationRuleTest {
|
||||
|
||||
final List<Address> validators = singletonList(committerAddress);
|
||||
final BftContext bftContext = setupContextWithValidators(validators);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext, Optional.empty());
|
||||
when(bftContext.getBlockInterface().getCommitters(any())).thenReturn(emptyList());
|
||||
|
||||
assertThat(commitSealsValidationRule.validate(blockHeader, null, context)).isFalse();
|
||||
@@ -88,7 +89,7 @@ public class BftCommitSealsValidationRuleTest {
|
||||
final NodeKey nonValidatorNodeKey = NodeKeyUtils.generate();
|
||||
|
||||
final BftContext bftContext = setupContextWithValidators(validators);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext, Optional.empty());
|
||||
when(bftContext.getBlockInterface().getCommitters(any()))
|
||||
.thenReturn(singletonList(Util.publicKeyToAddress(nonValidatorNodeKey.getPublicKey())));
|
||||
|
||||
@@ -135,7 +136,7 @@ public class BftCommitSealsValidationRuleTest {
|
||||
final List<Address> validators = singletonList(committerAddress);
|
||||
|
||||
final BftContext bftContext = setupContextWithValidators(validators);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext, Optional.empty());
|
||||
when(bftContext.getBlockInterface().getCommitters(any()))
|
||||
.thenReturn(List.of(committerAddress, committerAddress));
|
||||
|
||||
@@ -154,7 +155,7 @@ public class BftCommitSealsValidationRuleTest {
|
||||
Collections.sort(validators);
|
||||
|
||||
final BftContext bftContext = setupContextWithValidators(validators);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext);
|
||||
final ProtocolContext context = new ProtocolContext(null, null, bftContext, Optional.empty());
|
||||
when(bftContext.getBlockInterface().getCommitters(any()))
|
||||
.thenReturn(validators.subList(0, committerCount));
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.hyperledger.besu.ethereum.core.AddressHelpers;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Test;
|
||||
@@ -44,7 +45,8 @@ public class BftValidatorsValidationRuleTest {
|
||||
AddressHelpers.ofValue(1), AddressHelpers.ofValue(2), AddressHelpers.ofValue(3));
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(null, null, setupContextWithBftExtraData(validators, bftExtraData));
|
||||
new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraData(validators, bftExtraData), Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(validators);
|
||||
|
||||
assertThat(validatorsValidationRule.validate(blockHeader, null, context)).isTrue();
|
||||
@@ -58,7 +60,8 @@ public class BftValidatorsValidationRuleTest {
|
||||
AddressHelpers.ofValue(1), AddressHelpers.ofValue(2), AddressHelpers.ofValue(3));
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(null, null, setupContextWithBftExtraData(validators, bftExtraData));
|
||||
new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraData(validators, bftExtraData), Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(Lists.reverse(validators));
|
||||
|
||||
assertThat(validatorsValidationRule.validate(blockHeader, null, context)).isFalse();
|
||||
@@ -76,7 +79,10 @@ public class BftValidatorsValidationRuleTest {
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraData(storedValidators, bftExtraData));
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraData(storedValidators, bftExtraData),
|
||||
Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(Lists.reverse(reportedValidators));
|
||||
|
||||
assertThat(validatorsValidationRule.validate(blockHeader, null, context)).isFalse();
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.hyperledger.besu.consensus.common.bft.BftExtraData;
|
||||
import org.hyperledger.besu.ethereum.ProtocolContext;
|
||||
import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -44,7 +46,8 @@ public class BftVanityDataValidationRuleTest {
|
||||
new BftExtraData(Bytes.wrap(new byte[extraDataSize]), emptyList(), empty(), 0, emptyList());
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(null, null, setupContextWithBftExtraData(emptyList(), extraData));
|
||||
new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraData(emptyList(), extraData), Optional.empty());
|
||||
return validationRule.validate(blockHeader, null, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,8 @@ public class TestContextBuilder {
|
||||
new ProtocolContext(
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
new BftContext(validatorProvider, epochManager, blockInterface));
|
||||
new BftContext(validatorProvider, epochManager, blockInterface),
|
||||
Optional.empty());
|
||||
|
||||
final GasPricePendingTransactionsSorter pendingTransactions =
|
||||
new GasPricePendingTransactionsSorter(
|
||||
|
||||
@@ -118,7 +118,8 @@ public class IbftRoundIntegrationTest {
|
||||
new ProtocolContext(
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(emptyList(), bftExtraDataEncoder));
|
||||
setupContextWithBftExtraDataEncoder(emptyList(), bftExtraDataEncoder),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -48,7 +48,10 @@ public class IbftBlockHeaderValidationRulesetFactoryTest {
|
||||
|
||||
private ProtocolContext protocolContext(final Collection<Address> validators) {
|
||||
return new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraDataEncoder(validators, new IbftExtraDataCodec()));
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraDataEncoder(validators, new IbftExtraDataCodec()),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -119,6 +120,7 @@ public class IbftProtocolScheduleTest {
|
||||
return new ProtocolContext(
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraDataEncoder(BftContext.class, validators, bftExtraDataCodec));
|
||||
setupContextWithBftExtraDataEncoder(BftContext.class, validators, bftExtraDataCodec),
|
||||
Optional.empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,8 @@ public class BftBlockCreatorTest {
|
||||
new ProtocolContext(
|
||||
blockchain,
|
||||
createInMemoryWorldStateArchive(),
|
||||
setupContextWithBftExtraDataEncoder(initialValidatorList, bftExtraDataEncoder));
|
||||
setupContextWithBftExtraDataEncoder(initialValidatorList, bftExtraDataEncoder),
|
||||
Optional.empty());
|
||||
|
||||
final GasPricePendingTransactionsSorter pendingTransactions =
|
||||
new GasPricePendingTransactionsSorter(
|
||||
|
||||
@@ -151,7 +151,8 @@ public class IbftBlockHeightManagerTest {
|
||||
.thenReturn(futureRoundProposalMessageValidator);
|
||||
when(messageValidatorFactory.createMessageValidator(any(), any())).thenReturn(messageValidator);
|
||||
|
||||
protocolContext = new ProtocolContext(null, null, setupContextWithValidators(validators));
|
||||
protocolContext =
|
||||
new ProtocolContext(null, null, setupContextWithValidators(validators), Optional.empty());
|
||||
|
||||
// Ensure the created IbftRound has the valid ConsensusRoundIdentifier;
|
||||
when(roundFactory.createNewRound(any(), anyInt()))
|
||||
|
||||
@@ -106,7 +106,8 @@ public class IbftRoundTest {
|
||||
new ProtocolContext(
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(emptyList(), new IbftExtraDataCodec()));
|
||||
setupContextWithBftExtraDataEncoder(emptyList(), new IbftExtraDataCodec()),
|
||||
Optional.empty());
|
||||
|
||||
when(messageValidator.validateProposal(any())).thenReturn(true);
|
||||
when(messageValidator.validatePrepare(any())).thenReturn(true);
|
||||
|
||||
@@ -95,7 +95,10 @@ public class MessageValidatorTest {
|
||||
|
||||
protocolContext =
|
||||
new ProtocolContext(
|
||||
mock(MutableBlockchain.class), mock(WorldStateArchive.class), mockBftCtx);
|
||||
mock(MutableBlockchain.class),
|
||||
mock(WorldStateArchive.class),
|
||||
mockBftCtx,
|
||||
Optional.empty());
|
||||
|
||||
when(blockValidator.validateAndProcessBlock(any(), any(), any(), any()))
|
||||
.thenReturn(new BlockProcessingResult(Optional.empty()));
|
||||
|
||||
@@ -183,7 +183,8 @@ public class MergeCoordinatorTest implements MergeGenesisConfigHelper {
|
||||
.when(protocolSchedule)
|
||||
.getByBlockHeader(any(BlockHeader.class));
|
||||
|
||||
protocolContext = new ProtocolContext(blockchain, worldStateArchive, mergeContext);
|
||||
protocolContext =
|
||||
new ProtocolContext(blockchain, worldStateArchive, mergeContext, Optional.empty());
|
||||
var mutable = worldStateArchive.getMutable();
|
||||
genesisState.writeStateTo(mutable);
|
||||
mutable.persist(null);
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.hyperledger.besu.util.LogConfigurator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -69,7 +70,7 @@ public class MergeReorgTest implements MergeGenesisConfigHelper {
|
||||
private final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
|
||||
private final ProtocolContext protocolContext =
|
||||
new ProtocolContext(blockchain, worldStateArchive, mergeContext);
|
||||
new ProtocolContext(blockchain, worldStateArchive, mergeContext, Optional.empty());
|
||||
|
||||
private final Address coinbase = genesisAllocations(getPowGenesisConfigFile()).findFirst().get();
|
||||
private final BlockHeaderTestFixture headerGenerator = new BlockHeaderTestFixture();
|
||||
|
||||
@@ -456,7 +456,8 @@ public class TestContextBuilder {
|
||||
new ProtocolContext(
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
new QbftContext(validatorProvider, epochManager, blockInterface, Optional.empty()));
|
||||
new QbftContext(validatorProvider, epochManager, blockInterface, Optional.empty()),
|
||||
Optional.empty());
|
||||
|
||||
final GasPricePendingTransactionsSorter pendingTransactions =
|
||||
new GasPricePendingTransactionsSorter(
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.hyperledger.besu.plugin.services.securitymodule.SecurityModuleExcepti
|
||||
import org.hyperledger.besu.util.Subscribers;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -121,7 +122,8 @@ public class QbftRoundIntegrationTest {
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, emptyList(), qbftExtraDataEncoder));
|
||||
QbftContext.class, emptyList(), qbftExtraDataEncoder),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -45,7 +45,8 @@ public class QbftBlockHeaderValidationRulesetFactoryTest {
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, validators, new QbftExtraDataCodec()));
|
||||
QbftContext.class, validators, new QbftExtraDataCodec()),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -57,7 +57,8 @@ public class QbftProtocolScheduleTest {
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, validators, new QbftExtraDataCodec()));
|
||||
QbftContext.class, validators, new QbftExtraDataCodec()),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -46,7 +46,8 @@ public class QbftValidatorsValidationRuleTest {
|
||||
new ProtocolContext(
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraData(QbftContext.class, Collections.emptyList(), bftExtraData));
|
||||
setupContextWithBftExtraData(QbftContext.class, Collections.emptyList(), bftExtraData),
|
||||
Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(Collections.emptyList());
|
||||
when(bftExtraData.getVote()).thenReturn(Optional.empty());
|
||||
assertThat(qbftValidatorsValidationRule.validate(blockHeader, null, context)).isTrue();
|
||||
@@ -62,7 +63,10 @@ public class QbftValidatorsValidationRuleTest {
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraData(QbftContext.class, validators, bftExtraData));
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraData(QbftContext.class, validators, bftExtraData),
|
||||
Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(validators);
|
||||
assertThat(qbftValidatorsValidationRule.validate(blockHeader, null, context)).isTrue();
|
||||
}
|
||||
@@ -77,7 +81,10 @@ public class QbftValidatorsValidationRuleTest {
|
||||
|
||||
final ProtocolContext context =
|
||||
new ProtocolContext(
|
||||
null, null, setupContextWithBftExtraData(QbftContext.class, validators, bftExtraData));
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraData(QbftContext.class, validators, bftExtraData),
|
||||
Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(validators);
|
||||
assertThat(qbftValidatorsValidationRule.validate(blockHeader, null, context)).isFalse();
|
||||
}
|
||||
@@ -90,7 +97,8 @@ public class QbftValidatorsValidationRuleTest {
|
||||
new ProtocolContext(
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraData(QbftContext.class, Collections.emptyList(), bftExtraData));
|
||||
setupContextWithBftExtraData(QbftContext.class, Collections.emptyList(), bftExtraData),
|
||||
Optional.empty());
|
||||
when(bftExtraData.getValidators()).thenReturn(Collections.emptyList());
|
||||
when(bftExtraData.getVote()).thenReturn(Optional.of(mock(Vote.class)));
|
||||
assertThat(qbftValidatorsValidationRule.validate(blockHeader, null, context)).isFalse();
|
||||
|
||||
@@ -160,7 +160,8 @@ public class QbftBlockHeightManagerTest {
|
||||
null,
|
||||
null,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, validators, new QbftExtraDataCodec()));
|
||||
QbftContext.class, validators, new QbftExtraDataCodec()),
|
||||
Optional.empty());
|
||||
|
||||
// Ensure the created QbftRound has the valid ConsensusRoundIdentifier;
|
||||
when(roundFactory.createNewRound(any(), anyInt()))
|
||||
|
||||
@@ -117,7 +117,8 @@ public class QbftRoundTest {
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, emptyList(), new QbftExtraDataCodec()));
|
||||
QbftContext.class, emptyList(), new QbftExtraDataCodec()),
|
||||
Optional.empty());
|
||||
|
||||
when(messageValidator.validateProposal(any())).thenReturn(true);
|
||||
when(messageValidator.validatePrepare(any())).thenReturn(true);
|
||||
|
||||
@@ -86,7 +86,8 @@ public class ProposalPayloadValidatorTest {
|
||||
new ProtocolContext(
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), bftExtraDataCodec));
|
||||
setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), bftExtraDataCodec),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -239,7 +240,7 @@ public class ProposalPayloadValidatorTest {
|
||||
setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), pkiQbftExtraDataCodec);
|
||||
final Bytes cms = Bytes.fromHexStringLenient("0x1");
|
||||
final ProtocolContext protocolContext =
|
||||
new ProtocolContext(blockChain, worldStateArchive, qbftContext);
|
||||
new ProtocolContext(blockChain, worldStateArchive, qbftContext, Optional.empty());
|
||||
|
||||
final ProposalPayloadValidator payloadValidator =
|
||||
new ProposalPayloadValidator(
|
||||
@@ -274,7 +275,7 @@ public class ProposalPayloadValidatorTest {
|
||||
setupContextWithBftExtraDataEncoder(QbftContext.class, emptyList(), pkiQbftExtraDataCodec);
|
||||
final Bytes cms = Bytes.fromHexStringLenient("0x1");
|
||||
final ProtocolContext protocolContext =
|
||||
new ProtocolContext(blockChain, worldStateArchive, qbftContext);
|
||||
new ProtocolContext(blockChain, worldStateArchive, qbftContext, Optional.empty());
|
||||
|
||||
final ProposalPayloadValidator payloadValidator =
|
||||
new ProposalPayloadValidator(
|
||||
|
||||
@@ -98,7 +98,8 @@ public class ProposalValidatorTest {
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, emptyList(), bftExtraDataEncoder));
|
||||
QbftContext.class, emptyList(), bftExtraDataEncoder),
|
||||
Optional.empty());
|
||||
|
||||
// typically tests require the blockValidation to be successful
|
||||
when(blockValidator.validateAndProcessBlock(
|
||||
|
||||
@@ -81,7 +81,8 @@ public class RoundChangeMessageValidatorTest {
|
||||
blockChain,
|
||||
worldStateArchive,
|
||||
setupContextWithBftExtraDataEncoder(
|
||||
QbftContext.class, emptyList(), bftExtraDataEncoder));
|
||||
QbftContext.class, emptyList(), bftExtraDataEncoder),
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -76,7 +76,7 @@ public class JsonRpcTestMethodsFactory {
|
||||
this.blockchain = createInMemoryBlockchain(importer.getGenesisBlock());
|
||||
this.stateArchive = createInMemoryWorldStateArchive();
|
||||
this.importer.getGenesisState().writeStateTo(stateArchive.getMutable());
|
||||
this.context = new ProtocolContext(blockchain, stateArchive, null);
|
||||
this.context = new ProtocolContext(blockchain, stateArchive, null, Optional.empty());
|
||||
|
||||
final ProtocolSchedule protocolSchedule = importer.getProtocolSchedule();
|
||||
this.synchronizer = mock(Synchronizer.class);
|
||||
|
||||
@@ -67,7 +67,7 @@ public class EthGetBlockByNumberLatestDesyncIntegrationTest {
|
||||
InMemoryKeyValueStorageProvider.createInMemoryBlockchain(importer.getGenesisBlock());
|
||||
WorldStateArchive state = InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive();
|
||||
importer.getGenesisState().writeStateTo(state.getMutable());
|
||||
ProtocolContext context = new ProtocolContext(chain, state, null);
|
||||
ProtocolContext context = new ProtocolContext(chain, state, null, Optional.empty());
|
||||
|
||||
for (final Block block : importer.getBlocks()) {
|
||||
final ProtocolSchedule protocolSchedule = importer.getProtocolSchedule();
|
||||
|
||||
@@ -112,7 +112,8 @@ public abstract class AbstractEthGraphQLHttpServiceTest {
|
||||
|
||||
final MutableBlockchain blockchain = blockchainSetupUtil.getBlockchain();
|
||||
ProtocolContext context =
|
||||
new ProtocolContext(blockchain, blockchainSetupUtil.getWorldArchive(), null);
|
||||
new ProtocolContext(
|
||||
blockchain, blockchainSetupUtil.getWorldArchive(), null, Optional.empty());
|
||||
final BlockchainQueries blockchainQueries =
|
||||
new BlockchainQueries(
|
||||
context.getBlockchain(),
|
||||
|
||||
@@ -306,7 +306,8 @@ public abstract class AbstractBlockCreator implements AsyncBlockCreator {
|
||||
dataGasPrice,
|
||||
protocolSpec.getFeeMarket(),
|
||||
protocolSpec.getGasCalculator(),
|
||||
protocolSpec.getGasLimitCalculator());
|
||||
protocolSpec.getGasLimitCalculator(),
|
||||
protocolContext.getTransactionSelectorFactory());
|
||||
|
||||
if (transactions.isPresent()) {
|
||||
return selector.evaluateTransactions(transactions.get());
|
||||
|
||||
@@ -18,12 +18,12 @@ import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.ethereum.GasLimitCalculator;
|
||||
import org.hyperledger.besu.ethereum.chain.Blockchain;
|
||||
import org.hyperledger.besu.ethereum.core.LogsWrapper;
|
||||
import org.hyperledger.besu.ethereum.core.MutableWorldState;
|
||||
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.AbstractBlockProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams;
|
||||
@@ -34,14 +34,19 @@ import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||||
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
|
||||
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
|
||||
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.plugin.data.TransactionType;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelector;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -221,8 +226,9 @@ public class BlockTransactionSelector {
|
||||
private final FeeMarket feeMarket;
|
||||
private final GasCalculator gasCalculator;
|
||||
private final GasLimitCalculator gasLimitCalculator;
|
||||
private final TransactionSelector transactionSelector;
|
||||
|
||||
private final TransactionSelectionResults transactionSelectionResult =
|
||||
private final TransactionSelectionResults transactionSelectionResults =
|
||||
new TransactionSelectionResults();
|
||||
|
||||
public BlockTransactionSelector(
|
||||
@@ -239,7 +245,8 @@ public class BlockTransactionSelector {
|
||||
final Wei dataGasPrice,
|
||||
final FeeMarket feeMarket,
|
||||
final GasCalculator gasCalculator,
|
||||
final GasLimitCalculator gasLimitCalculator) {
|
||||
final GasLimitCalculator gasLimitCalculator,
|
||||
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
|
||||
this.transactionProcessor = transactionProcessor;
|
||||
this.blockchain = blockchain;
|
||||
this.worldState = worldState;
|
||||
@@ -254,6 +261,8 @@ public class BlockTransactionSelector {
|
||||
this.feeMarket = feeMarket;
|
||||
this.gasCalculator = gasCalculator;
|
||||
this.gasLimitCalculator = gasLimitCalculator;
|
||||
this.transactionSelector =
|
||||
transactionSelectorFactory.map(TransactionSelectorFactory::create).orElse(null);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,14 +279,14 @@ public class BlockTransactionSelector {
|
||||
pendingTransactions.selectTransactions(
|
||||
pendingTransaction -> {
|
||||
final var res = evaluateTransaction(pendingTransaction, false);
|
||||
transactionSelectionResult.addSelectionResult(res);
|
||||
transactionSelectionResults.addSelectionResult(res);
|
||||
return res;
|
||||
});
|
||||
LOG.atTrace()
|
||||
.setMessage("Transaction selection result {}")
|
||||
.addArgument(transactionSelectionResult::toTraceLog)
|
||||
.setMessage("Transaction selection result result {}")
|
||||
.addArgument(transactionSelectionResults::toTraceLog)
|
||||
.log();
|
||||
return transactionSelectionResult;
|
||||
return transactionSelectionResults;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,8 +298,8 @@ public class BlockTransactionSelector {
|
||||
public TransactionSelectionResults evaluateTransactions(final List<Transaction> transactions) {
|
||||
transactions.forEach(
|
||||
transaction ->
|
||||
transactionSelectionResult.addSelectionResult(evaluateTransaction(transaction, true)));
|
||||
return transactionSelectionResult;
|
||||
transactionSelectionResults.addSelectionResult(evaluateTransaction(transaction, true)));
|
||||
return transactionSelectionResults;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -348,22 +357,55 @@ public class BlockTransactionSelector {
|
||||
dataGasPrice);
|
||||
|
||||
if (!effectiveResult.isInvalid()) {
|
||||
worldStateUpdater.commit();
|
||||
LOG.atTrace()
|
||||
.setMessage("Selected {} for block creation")
|
||||
.addArgument(transaction::toTraceLog)
|
||||
.log();
|
||||
updateTransactionResultTracking(transaction, effectiveResult);
|
||||
|
||||
final long gasUsedByTransaction =
|
||||
transaction.getGasLimit() - effectiveResult.getGasRemaining();
|
||||
|
||||
final long cumulativeGasUsed =
|
||||
transactionSelectionResults.getCumulativeGasUsed() + gasUsedByTransaction;
|
||||
|
||||
TransactionSelectionResult txSelectionResult = TransactionSelectionResult.SELECTED;
|
||||
|
||||
if (transactionSelector != null) {
|
||||
txSelectionResult =
|
||||
transactionSelector.selectTransaction(
|
||||
transaction,
|
||||
effectiveResult.getStatus() == TransactionProcessingResult.Status.SUCCESSFUL,
|
||||
getLogs(effectiveResult.getLogs()),
|
||||
cumulativeGasUsed);
|
||||
}
|
||||
|
||||
if (txSelectionResult.equals(TransactionSelectionResult.SELECTED)) {
|
||||
|
||||
worldStateUpdater.commit();
|
||||
final TransactionReceipt receipt =
|
||||
transactionReceiptFactory.create(
|
||||
transaction.getType(), effectiveResult, worldState, cumulativeGasUsed);
|
||||
|
||||
final long dataGasUsed = gasCalculator.dataGasCost(transaction.getBlobCount());
|
||||
|
||||
transactionSelectionResults.update(transaction, receipt, gasUsedByTransaction, dataGasUsed);
|
||||
|
||||
LOG.atTrace()
|
||||
.setMessage("Selected {} for block creation")
|
||||
.addArgument(transaction::toTraceLog)
|
||||
.log();
|
||||
}
|
||||
return txSelectionResult;
|
||||
} else {
|
||||
|
||||
final boolean isIncorrectNonce = isIncorrectNonce(effectiveResult.getValidationResult());
|
||||
if (!isIncorrectNonce || reportFutureNonceTransactionsAsInvalid) {
|
||||
transactionSelectionResult.updateWithInvalidTransaction(
|
||||
transactionSelectionResults.updateWithInvalidTransaction(
|
||||
transaction, effectiveResult.getValidationResult());
|
||||
}
|
||||
return transactionSelectionResultForInvalidResult(
|
||||
transaction, effectiveResult.getValidationResult());
|
||||
}
|
||||
return TransactionSelectionResult.SELECTED;
|
||||
}
|
||||
|
||||
private List<org.hyperledger.besu.plugin.data.Log> getLogs(final List<Log> logs) {
|
||||
return logs.stream().map(LogsWrapper::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean transactionDataPriceBelowMin(final Transaction transaction) {
|
||||
@@ -430,28 +472,6 @@ public class BlockTransactionSelector {
|
||||
|| invalidReason.equals(TransactionInvalidReason.NONCE_TOO_HIGH);
|
||||
}
|
||||
|
||||
/*
|
||||
Responsible for updating the state maintained between transaction validation (i.e. receipts,
|
||||
cumulative gas, world state root hash.).
|
||||
*/
|
||||
private void updateTransactionResultTracking(
|
||||
final Transaction transaction, final TransactionProcessingResult result) {
|
||||
|
||||
final long gasUsedByTransaction = transaction.getGasLimit() - result.getGasRemaining();
|
||||
|
||||
final long cumulativeGasUsed =
|
||||
transactionSelectionResult.getCumulativeGasUsed() + gasUsedByTransaction;
|
||||
|
||||
final long dataGasUsed = gasCalculator.dataGasCost(transaction.getBlobCount());
|
||||
|
||||
transactionSelectionResult.update(
|
||||
transaction,
|
||||
transactionReceiptFactory.create(
|
||||
transaction.getType(), result, worldState, cumulativeGasUsed),
|
||||
gasUsedByTransaction,
|
||||
dataGasUsed);
|
||||
}
|
||||
|
||||
private boolean isIncorrectNonce(final ValidationResult<TransactionInvalidReason> result) {
|
||||
return result.getInvalidReason().equals(TransactionInvalidReason.NONCE_TOO_HIGH);
|
||||
}
|
||||
@@ -461,20 +481,21 @@ public class BlockTransactionSelector {
|
||||
|
||||
if (dataGasUsed
|
||||
> gasLimitCalculator.currentDataGasLimit()
|
||||
- transactionSelectionResult.getCumulativeDataGasUsed()) {
|
||||
- transactionSelectionResults.getCumulativeDataGasUsed()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return transaction.getGasLimit() + dataGasUsed
|
||||
> processableBlockHeader.getGasLimit() - transactionSelectionResult.getCumulativeGasUsed();
|
||||
> processableBlockHeader.getGasLimit() - transactionSelectionResults.getCumulativeGasUsed();
|
||||
}
|
||||
|
||||
private boolean blockOccupancyAboveThreshold() {
|
||||
final long gasAvailable = processableBlockHeader.getGasLimit();
|
||||
final long gasUsed = transactionSelectionResult.getCumulativeGasUsed();
|
||||
final long gasRemaining = gasAvailable - gasUsed;
|
||||
|
||||
final long gasUsed = transactionSelectionResults.getCumulativeGasUsed();
|
||||
final long gasRemaining = gasAvailable - gasUsed;
|
||||
final double occupancyRatio = (double) gasUsed / (double) gasAvailable;
|
||||
|
||||
LOG.trace(
|
||||
"Min block occupancy ratio {}, gas used {}, available {}, remaining {}, used/available {}",
|
||||
minBlockOccupancyRatio,
|
||||
@@ -488,7 +509,8 @@ public class BlockTransactionSelector {
|
||||
|
||||
private boolean blockFull() {
|
||||
final long gasAvailable = processableBlockHeader.getGasLimit();
|
||||
final long gasUsed = transactionSelectionResult.getCumulativeGasUsed();
|
||||
final long gasUsed = transactionSelectionResults.getCumulativeGasUsed();
|
||||
|
||||
final long gasRemaining = gasAvailable - gasUsed;
|
||||
|
||||
if (gasRemaining < gasCalculator.getMinimumTransactionCost()) {
|
||||
|
||||
@@ -45,7 +45,6 @@ import org.hyperledger.besu.ethereum.eth.transactions.ImmutableTransactionPoolCo
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.sorter.BaseFeePendingTransactionsSorter;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
@@ -57,8 +56,10 @@ import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator;
|
||||
import org.hyperledger.besu.evm.internal.EvmConfiguration;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.plugin.data.TransactionType;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
|
||||
import org.hyperledger.besu.testutil.TestClock;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -90,7 +91,6 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
protected PendingTransactions pendingTransactions;
|
||||
protected MutableWorldState worldState;
|
||||
@Mock protected MainnetTransactionProcessor transactionProcessor;
|
||||
@Mock protected MainnetTransactionValidator transactionValidator;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -286,7 +286,8 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
Wei.ZERO,
|
||||
FeeMarket.london(0L),
|
||||
new LondonGasCalculator(),
|
||||
GasLimitCalculator.constant());
|
||||
GasLimitCalculator.constant(),
|
||||
Optional.empty());
|
||||
|
||||
// this should fill up all the block space
|
||||
final Transaction fillingLegacyTx =
|
||||
@@ -561,6 +562,74 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
.isNotPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transactionSelectionPluginShouldWork() {
|
||||
final ProcessableBlockHeader blockHeader = createBlock(300);
|
||||
|
||||
final TransactionTestFixture txTestFixture = new TransactionTestFixture();
|
||||
final Transaction selected =
|
||||
txTestFixture
|
||||
.nonce(1)
|
||||
.gasLimit(1)
|
||||
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||||
ensureTransactionIsValid(selected, 2000, 10000);
|
||||
|
||||
final Transaction notSelectedTransient =
|
||||
txTestFixture
|
||||
.nonce(1)
|
||||
.gasLimit(1)
|
||||
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||||
ensureTransactionIsValid(notSelectedTransient, 2000, 10000);
|
||||
|
||||
final Transaction notSelectedInvalid =
|
||||
txTestFixture
|
||||
.nonce(1)
|
||||
.gasLimit(1)
|
||||
.createTransaction(SignatureAlgorithmFactory.getInstance().generateKeyPair());
|
||||
ensureTransactionIsValid(notSelectedInvalid, 2000, 10000);
|
||||
|
||||
final TransactionSelectorFactory transactionSelectorFactory =
|
||||
(TransactionSelectorFactory)
|
||||
() ->
|
||||
(tx, s, logs, cg) -> {
|
||||
if (tx.equals(notSelectedTransient))
|
||||
return TransactionSelectionResult.invalidTransient("transient");
|
||||
if (tx.equals(notSelectedInvalid))
|
||||
return TransactionSelectionResult.invalid("invalid");
|
||||
return TransactionSelectionResult.SELECTED;
|
||||
};
|
||||
|
||||
final Address miningBeneficiary = AddressHelpers.ofValue(1);
|
||||
final BlockTransactionSelector selector =
|
||||
createBlockSelectorWithTxSelPlugin(
|
||||
transactionProcessor,
|
||||
blockHeader,
|
||||
Wei.ZERO,
|
||||
miningBeneficiary,
|
||||
Wei.ZERO,
|
||||
MIN_OCCUPANCY_80_PERCENT,
|
||||
transactionSelectorFactory);
|
||||
|
||||
pendingTransactions.addRemoteTransaction(selected, Optional.empty());
|
||||
pendingTransactions.addRemoteTransaction(notSelectedTransient, Optional.empty());
|
||||
pendingTransactions.addRemoteTransaction(notSelectedInvalid, Optional.empty());
|
||||
|
||||
final BlockTransactionSelector.TransactionSelectionResults transactionSelectionResults =
|
||||
selector.buildTransactionListForBlock();
|
||||
|
||||
Assertions.assertThat(pendingTransactions.getTransactionByHash(notSelectedTransient.getHash()))
|
||||
.isPresent();
|
||||
Assertions.assertThat(pendingTransactions.getTransactionByHash(notSelectedInvalid.getHash()))
|
||||
.isNotPresent();
|
||||
// Assertions.assertThat(pendingTransactions.getTransactionByHash(selected.getHash()))
|
||||
// .isNotPresent(); // TODO check with Fabio what should happen with selected txs
|
||||
Assertions.assertThat(transactionSelectionResults.getTransactions()).contains(selected);
|
||||
Assertions.assertThat(transactionSelectionResults.getTransactions())
|
||||
.doesNotContain(notSelectedTransient);
|
||||
Assertions.assertThat(transactionSelectionResults.getTransactions())
|
||||
.doesNotContain(notSelectedInvalid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transactionWithIncorrectNonceRemainsInPoolAndNotSelected() {
|
||||
final ProcessableBlockHeader blockHeader = createBlock(5000);
|
||||
@@ -611,8 +680,39 @@ public abstract class AbstractBlockTransactionSelectorTest {
|
||||
miningBeneficiary,
|
||||
dataGasPrice,
|
||||
getFeeMarket(),
|
||||
getGasCalculator(),
|
||||
GasLimitCalculator.constant());
|
||||
new LondonGasCalculator(),
|
||||
GasLimitCalculator.constant(),
|
||||
Optional.empty());
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
protected BlockTransactionSelector createBlockSelectorWithTxSelPlugin(
|
||||
final MainnetTransactionProcessor transactionProcessor,
|
||||
final ProcessableBlockHeader blockHeader,
|
||||
final Wei minGasPrice,
|
||||
final Address miningBeneficiary,
|
||||
final Wei dataGasPrice,
|
||||
final double minBlockOccupancyRatio,
|
||||
final TransactionSelectorFactory transactionSelectorFactory) {
|
||||
final BlockTransactionSelector selector =
|
||||
new BlockTransactionSelector(
|
||||
transactionProcessor,
|
||||
blockchain,
|
||||
worldState,
|
||||
pendingTransactions,
|
||||
blockHeader,
|
||||
this::createReceipt,
|
||||
minGasPrice,
|
||||
minBlockOccupancyRatio,
|
||||
this::isCancelled,
|
||||
miningBeneficiary,
|
||||
dataGasPrice,
|
||||
getFeeMarket(),
|
||||
new LondonGasCalculator(),
|
||||
GasLimitCalculator.constant(),
|
||||
Optional.of(transactionSelectorFactory));
|
||||
|
||||
return selector;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class BlockMinerTest {
|
||||
new Block(
|
||||
headerBuilder.buildHeader(), new BlockBody(Lists.newArrayList(), Lists.newArrayList()));
|
||||
|
||||
final ProtocolContext protocolContext = new ProtocolContext(null, null, null);
|
||||
final ProtocolContext protocolContext = new ProtocolContext(null, null, null, Optional.empty());
|
||||
|
||||
final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class);
|
||||
final Function<BlockHeader, PoWBlockCreator> blockCreatorSupplier =
|
||||
@@ -95,7 +95,7 @@ public class BlockMinerTest {
|
||||
new Block(
|
||||
headerBuilder.buildHeader(), new BlockBody(Lists.newArrayList(), Lists.newArrayList()));
|
||||
|
||||
final ProtocolContext protocolContext = new ProtocolContext(null, null, null);
|
||||
final ProtocolContext protocolContext = new ProtocolContext(null, null, null, Optional.empty());
|
||||
|
||||
final PoWBlockCreator blockCreator = mock(PoWBlockCreator.class);
|
||||
final Function<BlockHeader, PoWBlockCreator> blockCreatorSupplier =
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
||||
import org.hyperledger.besu.ethereum.core.Synchronizer;
|
||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -30,6 +31,7 @@ public class ProtocolContext {
|
||||
private final MutableBlockchain blockchain;
|
||||
private final WorldStateArchive worldStateArchive;
|
||||
private final ConsensusContext consensusContext;
|
||||
private final Optional<TransactionSelectorFactory> transactionSelectorFactory;
|
||||
|
||||
private Optional<Synchronizer> synchronizer;
|
||||
|
||||
@@ -37,21 +39,32 @@ public class ProtocolContext {
|
||||
final MutableBlockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final ConsensusContext consensusContext) {
|
||||
this(blockchain, worldStateArchive, consensusContext, Optional.empty());
|
||||
}
|
||||
|
||||
public ProtocolContext(
|
||||
final MutableBlockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final ConsensusContext consensusContext,
|
||||
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
|
||||
this.blockchain = blockchain;
|
||||
this.worldStateArchive = worldStateArchive;
|
||||
this.consensusContext = consensusContext;
|
||||
this.synchronizer = Optional.empty();
|
||||
this.transactionSelectorFactory = transactionSelectorFactory;
|
||||
}
|
||||
|
||||
public static ProtocolContext init(
|
||||
final MutableBlockchain blockchain,
|
||||
final WorldStateArchive worldStateArchive,
|
||||
final ProtocolSchedule protocolSchedule,
|
||||
final ConsensusContextFactory consensusContextFactory) {
|
||||
final ConsensusContextFactory consensusContextFactory,
|
||||
final Optional<TransactionSelectorFactory> transactionSelectorFactory) {
|
||||
return new ProtocolContext(
|
||||
blockchain,
|
||||
worldStateArchive,
|
||||
consensusContextFactory.create(blockchain, worldStateArchive, protocolSchedule));
|
||||
consensusContextFactory.create(blockchain, worldStateArchive, protocolSchedule),
|
||||
transactionSelectorFactory);
|
||||
}
|
||||
|
||||
public Optional<Synchronizer> getSynchronizer() {
|
||||
@@ -79,4 +92,8 @@ public class ProtocolContext {
|
||||
.filter(c -> klass.isAssignableFrom(c.getClass()))
|
||||
.map(klass::cast);
|
||||
}
|
||||
|
||||
public Optional<TransactionSelectorFactory> getTransactionSelectorFactory() {
|
||||
return transactionSelectorFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright Hyperledger Besu Contributors.
|
||||
*
|
||||
* 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.ethereum.core;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.evm.log.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
public class LogsWrapper implements org.hyperledger.besu.plugin.data.Log {
|
||||
|
||||
final Log delegate;
|
||||
|
||||
public LogsWrapper(final Log delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getLogger() {
|
||||
return delegate.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Bytes32> getTopics() {
|
||||
return delegate.getTopics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bytes getData() {
|
||||
return delegate.getData();
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.core;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Hash;
|
||||
import org.hyperledger.besu.ethereum.mainnet.TransactionReceiptType;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
|
||||
@@ -33,7 +32,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
|
||||
/**
|
||||
* A transaction receipt, containing information pertaining a transaction execution.
|
||||
@@ -370,27 +368,3 @@ public class TransactionReceipt implements org.hyperledger.besu.plugin.data.Tran
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class LogsWrapper implements org.hyperledger.besu.plugin.data.Log {
|
||||
|
||||
final Log delegate;
|
||||
|
||||
LogsWrapper(final Log delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getLogger() {
|
||||
return delegate.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Bytes32> getTopics() {
|
||||
return delegate.getTopics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bytes getData() {
|
||||
return delegate.getData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Resources;
|
||||
@@ -151,7 +152,8 @@ public class BlockchainSetupUtil {
|
||||
public <C extends ConsensusContext> C as(final Class<C> klass) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
},
|
||||
Optional.empty());
|
||||
}
|
||||
|
||||
private static BlockchainSetupUtil create(
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.hyperledger.besu.plugin.services.storage.KeyValueStorage;
|
||||
import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ExecutionContextTestFixture {
|
||||
@@ -61,7 +62,7 @@ public class ExecutionContextTestFixture {
|
||||
0);
|
||||
this.stateArchive = createInMemoryWorldStateArchive();
|
||||
this.protocolSchedule = protocolSchedule;
|
||||
this.protocolContext = new ProtocolContext(blockchain, stateArchive, null);
|
||||
this.protocolContext = new ProtocolContext(blockchain, stateArchive, null, Optional.empty());
|
||||
genesisState.writeStateTo(stateArchive.getMutable());
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ public abstract class AbstractIsolationTests {
|
||||
null);
|
||||
var ws = archive.getMutable();
|
||||
genesisState.writeStateTo(ws);
|
||||
protocolContext = new ProtocolContext(blockchain, archive, null);
|
||||
protocolContext = new ProtocolContext(blockchain, archive, null, Optional.empty());
|
||||
}
|
||||
|
||||
// storage provider which uses a temporary directory based rocksdb
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
|
||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,11 +32,11 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolReplacementHandler;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.account.AccountState;
|
||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
||||
import org.hyperledger.besu.plugin.services.metrics.LabelledMetric;
|
||||
|
||||
@@ -65,6 +65,7 @@ import org.hyperledger.besu.testutil.TestClock;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -104,7 +105,8 @@ public abstract class AbstractBlockPropagationManagerTest {
|
||||
new ProtocolContext(
|
||||
blockchain,
|
||||
tempProtocolContext.getWorldStateArchive(),
|
||||
tempProtocolContext.getConsensusContext(ConsensusContext.class));
|
||||
tempProtocolContext.getConsensusContext(ConsensusContext.class),
|
||||
Optional.empty());
|
||||
ethProtocolManager =
|
||||
EthProtocolManagerTestUtil.create(
|
||||
protocolSchedule,
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -80,7 +81,7 @@ public class FullSyncTargetManagerTest {
|
||||
|
||||
final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET;
|
||||
final ProtocolContext protocolContext =
|
||||
new ProtocolContext(localBlockchain, localWorldState, null);
|
||||
new ProtocolContext(localBlockchain, localWorldState, null, Optional.empty());
|
||||
ethProtocolManager =
|
||||
EthProtocolManagerTestUtil.create(
|
||||
protocolSchedule,
|
||||
|
||||
@@ -45,6 +45,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -160,7 +161,7 @@ public class DetermineCommonAncestorTaskParameterizedTest {
|
||||
|
||||
final EthContext ethContext = ethProtocolManager.ethContext();
|
||||
final ProtocolContext protocolContext =
|
||||
new ProtocolContext(localBlockchain, worldStateArchive, null);
|
||||
new ProtocolContext(localBlockchain, worldStateArchive, null, Optional.empty());
|
||||
|
||||
final EthTask<BlockHeader> task =
|
||||
DetermineCommonAncestorTask.create(
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.hyperledger.besu.plugin.services.MetricsSystem;
|
||||
import org.hyperledger.besu.util.ExceptionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -86,7 +87,8 @@ public class DetermineCommonAncestorTaskTest {
|
||||
mock(TransactionPool.class),
|
||||
EthProtocolConfiguration.defaultConfig());
|
||||
ethContext = ethProtocolManager.ethContext();
|
||||
protocolContext = new ProtocolContext(localBlockchain, worldStateArchive, null);
|
||||
protocolContext =
|
||||
new ProtocolContext(localBlockchain, worldStateArchive, null, Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -123,7 +123,7 @@ public class TestNode implements Closeable {
|
||||
final WorldStateArchive worldStateArchive = createInMemoryWorldStateArchive();
|
||||
genesisState.writeStateTo(worldStateArchive.getMutable());
|
||||
final ProtocolContext protocolContext =
|
||||
new ProtocolContext(blockchain, worldStateArchive, null);
|
||||
new ProtocolContext(blockchain, worldStateArchive, null, Optional.empty());
|
||||
|
||||
final SyncState syncState = mock(SyncState.class);
|
||||
final SynchronizerConfiguration syncConfig = mock(SynchronizerConfiguration.class);
|
||||
|
||||
@@ -19,16 +19,16 @@ import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedRes
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ALREADY_KNOWN;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.NONCE_TOO_FAR_IN_FUTURE_FOR_SENDER;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.REJECTED_UNDERPRICED_REPLACEMENT;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.BLOCK_FULL;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.BLOCK_OCCUPANCY_ABOVE_THRESHOLD;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.CURRENT_TX_PRICE_BELOW_MIN;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.DATA_PRICE_BELOW_CURRENT_MIN;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.SELECTED;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.TX_TOO_LARGE_FOR_REMAINING_GAS;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.DROPPED;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.layered.TransactionsLayer.RemovalReason.REPLACED;
|
||||
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.GAS_PRICE_BELOW_CURRENT_BASE_FEE;
|
||||
import static org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_FULL;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.BLOCK_OCCUPANCY_ABOVE_THRESHOLD;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.CURRENT_TX_PRICE_BELOW_MIN;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.DATA_PRICE_BELOW_CURRENT_MIN;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.TX_TOO_LARGE_FOR_REMAINING_GAS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
@@ -47,9 +47,9 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionDroppedL
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolMetrics;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolReplacementHandler;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -311,7 +311,7 @@ public class LayeredPendingTransactionsTest extends BaseTransactionPoolTest {
|
||||
}
|
||||
|
||||
static Stream<TransactionSelectionResult> selectTransactionsUntilSelectorRequestsNoMore() {
|
||||
return Stream.of(BLOCK_OCCUPANCY_ABOVE_THRESHOLD, BLOCK_FULL);
|
||||
return Stream.of(BLOCK_OCCUPANCY_ABOVE_THRESHOLD, BLOCK_OCCUPANCY_ABOVE_THRESHOLD, BLOCK_FULL);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -18,7 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ADDED;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.ALREADY_KNOWN;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionAddedResult.REJECTED_UNDERPRICED_REPLACEMENT;
|
||||
import static org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult.SELECTED;
|
||||
import static org.hyperledger.besu.plugin.data.TransactionSelectionResult.SELECTED;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
@@ -40,10 +40,10 @@ import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionAddedLis
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactionDroppedListener;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.PendingTransactions;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionPoolConfiguration;
|
||||
import org.hyperledger.besu.ethereum.eth.transactions.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.metrics.StubMetricsSystem;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
import org.hyperledger.besu.testutil.TestClock;
|
||||
|
||||
import java.time.Clock;
|
||||
|
||||
1
ethereum/evmtool/txs.rlp
Normal file
1
ethereum/evmtool/txs.rlp
Normal file
@@ -0,0 +1 @@
|
||||
"0xf90620f860800a8307a12094000000000000000000000000000000000000010080801ca0f73b923883495dc2174285c8fa4176de3d45accfb11cc8034ea1dd09831a4ddfa01c6bccbcd655b4022bcc27de4b9d5cee9ce999cdb8459b0afec4f5054ea02243f860010a8307a12094000000000000000000000000000000000000010180801ba0bffca3f433f61c957d822af37f2b49c57700ff338588d51ea82dc9f720c91d9da0168bb65cc72d586384383f8ceef3a6a60e54b7f4aaa978a6dad271ced54b2ebff860020a8307a12094000000000000000000000000000000000000010280801ba03d9f110bcf0c44be552d4d0ec8387b705604f7d3bb3794dcef4004c38963103ea013bda734f3b5987b8c855f6aab046754506266ff32352ba0898c4eba4acaec8bf860030a8307a12094000000000000000000000000000000000000010380801ba0ecb276d2486664ea779813e599b6f07b7b0df746626d7fdddf60ea425efcb324a0739841682e79a8302dc2e146dfd1eecbdc611d386d42287bcdd94a39bf536020f860040a8307a12094000000000000000000000000000000000000010480801ba002866b5c5fa5dbfa3d88b71a49b82a779c2d508cda631893176782dbcd7435aaa003c380a9af9bfdb3503abcfd5037d3c66f39bb7a19011a3291712d22292c5236f860050a8307a12094000000000000000000000000000000000000010580801ca0c70d2e000e503933d0f1a9a923dc647924811a912adf77692ff7d8f6808d5617a04ad82c92b980580a4a67e4c405e83d560a14201c3fd4b3a42d34dcc19336479af860060a8307a12094000000000000000000000000000000000000010680801ca07f2527f8cbe14e021d270dd214a1820355c7af128001889f57b7f9bba46a6c5da03033308de0d39b9d1b47d28f81df39ceaff330349298c65deb836efe8bce273ff860070a8307a12094000000000000000000000000000000000000010780801ba0ecb720a8764f8967b95dc66e961c6261fceb392c0e90461d7d66113d3c8bbd12a02655e28b751cc2e03a835aa817d884b540765dba12968bc53f53737b4234ee21f860080a8307a12094000000000000000000000000000000000000010880801ba095a2e27c0b296679141c0ad61be112f689b134c04d1773814ddae67fefb2dfbda02955f126d57d8b9777f47c520ffe4285890ca2dd1189e67b3407d6369997e7ecf860090a8307a12094000000000000000000000000000000000000010980801ca02468a120d0ee8c57caac354f56842a1db10813169a328f9f852279668b573907a03971f4c2e6bc0aa666812712719199df6fe37c0e1e122131cdb47d6c0c77b371f8600a0a8307a12094000000000000000000000000000000000000010a80801ba0a3a2018ab0bc2695b94bb85d710f4d07132a94f8c3e0f385824da5fee11899a5a00d2dfe430ea5aaff3de8bbb9339e7485474c8e4e34636f787124a7a91e4d6d6af8600b0a8307a12094000000000000000000000000000000000000010b80801ba0b91968fdb3aecea26094ec30649daa4de81a875bcb1a123e732b8f3f112ce232a02ef8cd85969d8bcef5f4ee1f5d20783b8d9b7466726c15ebf911565825187665f8600c0a8307a12094000000000000000000000000000000000000010c80801ca0dd27e75aa990793205805c22265b04be8299b208fad4f37a7f652ecf32b67390a05aa8cda18521548ff8f95e88f49f309d05cab32de28a0942b8a7a824c50df459f8600d0a8307a12094000000000000000000000000000000000000010d80801ba0fad07ce7139dd4e00266194e6a51c048f74eaba3c0a1b03ece378a810abfaa63a04fec880dafaa5382797b4f88b16138b1f0c4e084817072c77ff9bf17ddd4ac26f8600e0a8307a12094000000000000000000000000000000000000010e80801ca0208b22ab245221bdc5cae6586d2ef019a2c37be41166e04b8abe354c41a8f5b6a032d5d6ef07731cd1684531c775c1727ef6ba75de18cda96d998aaa0c1db0bd68f8600f0a8307a12094000000000000000000000000000000000000010f80801ba0055225ffd3d8b2d19c32aa68cb46e7b52c1d99844fb8b7a53b922ea1649e9c5ba06ae2a1e3b9712354b706d0f4da6ea76ed2f8f75277a51a14a3e0ccf25b85c626"
|
||||
@@ -106,7 +106,8 @@ public class BlockchainReferenceTestCaseSpec {
|
||||
this.worldStateArchive = buildWorldStateArchive(accounts);
|
||||
this.blockchain = buildBlockchain(genesisBlockHeader);
|
||||
this.sealEngine = sealEngine;
|
||||
this.protocolContext = new ProtocolContext(this.blockchain, this.worldStateArchive, null);
|
||||
this.protocolContext =
|
||||
new ProtocolContext(this.blockchain, this.worldStateArchive, null, Optional.empty());
|
||||
}
|
||||
|
||||
public String getNetwork() {
|
||||
|
||||
@@ -168,7 +168,7 @@ public class RetestethContext {
|
||||
genesisState.writeStateTo(worldState);
|
||||
|
||||
blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
||||
protocolContext = new ProtocolContext(blockchain, worldStateArchive, null);
|
||||
protocolContext = new ProtocolContext(blockchain, worldStateArchive, null, Optional.empty());
|
||||
|
||||
blockchainQueries = new BlockchainQueries(blockchain, worldStateArchive, ethScheduler);
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ Calculated : ${currentHash}
|
||||
tasks.register('checkAPIChanges', FileStateChecker) {
|
||||
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
|
||||
files = sourceSets.main.allJava.files
|
||||
knownHash = 'WC7tcTTrQg//+cIarm7NSabnxm6nY0lLkHWOH6+7Rmo='
|
||||
knownHash = 'gfED3Pzd/+CSSrTtDo1X+lkc7qwffDqF98EZIDMCOIc='
|
||||
}
|
||||
check.dependsOn('checkAPIChanges')
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.hyperledger.besu.ethereum.eth.transactions;
|
||||
package org.hyperledger.besu.plugin.data;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright Hyperledger Besu Contributors.
|
||||
*
|
||||
* 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.plugin.services;
|
||||
|
||||
import org.hyperledger.besu.plugin.Unstable;
|
||||
import org.hyperledger.besu.plugin.services.txselection.TransactionSelectorFactory;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** Transaction selection service interface */
|
||||
@Unstable
|
||||
public interface TransactionSelectionService extends BesuService {
|
||||
|
||||
/**
|
||||
* Returns the (Optional) transaction selector factory
|
||||
*
|
||||
* @return the transaction selector factory
|
||||
*/
|
||||
Optional<TransactionSelectorFactory> get();
|
||||
|
||||
/**
|
||||
* Registers the transaction selector factory with the service
|
||||
*
|
||||
* @param transactionSelectorFactory transaction selector factory to be used
|
||||
*/
|
||||
void registerTransactionSelectorFactory(TransactionSelectorFactory transactionSelectorFactory);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright Hyperledger Besu Contributors.
|
||||
*
|
||||
* 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.plugin.services.txselection;
|
||||
|
||||
import org.hyperledger.besu.plugin.Unstable;
|
||||
import org.hyperledger.besu.plugin.data.Log;
|
||||
import org.hyperledger.besu.plugin.data.Transaction;
|
||||
import org.hyperledger.besu.plugin.data.TransactionSelectionResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Interface for the transaction selector */
|
||||
@Unstable
|
||||
public interface TransactionSelector {
|
||||
|
||||
/**
|
||||
* Method called to decide whether a transaction is added to a block. The method can also indicate
|
||||
* that no further transactions can be added to the block.
|
||||
*
|
||||
* @param transaction candidate transaction
|
||||
* @param success true, if the transaction executed successfully
|
||||
* @param logs the logs created by this transaction
|
||||
* @param cumulativeGasUsed gas used by this and all previous transaction in the block
|
||||
* @return TransactionSelectionResult that indicates whether to include the transaction
|
||||
*/
|
||||
TransactionSelectionResult selectTransaction(
|
||||
final Transaction transaction,
|
||||
final boolean success,
|
||||
final List<Log> logs,
|
||||
final long cumulativeGasUsed);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright Hyperledger Besu Contributors.
|
||||
*
|
||||
* 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.plugin.services.txselection;
|
||||
|
||||
import org.hyperledger.besu.plugin.Unstable;
|
||||
|
||||
/** Interface for a factory that creates transaction selectors */
|
||||
@Unstable
|
||||
public interface TransactionSelectorFactory {
|
||||
|
||||
/**
|
||||
* Create a transaction selector
|
||||
*
|
||||
* @return the transaction selector
|
||||
*/
|
||||
TransactionSelector create();
|
||||
}
|
||||
Reference in New Issue
Block a user