Merge branch 'main' into zkbesu

This commit is contained in:
Fabio Di Fabio
2024-03-27 14:06:57 +01:00
256 changed files with 3383 additions and 3604 deletions

View File

@@ -7,6 +7,7 @@
- BFT networks won't start with SNAP or CHECKPOINT sync (previously Besu would start with this config but quietly fail to sync, so it's now more obvious that it won't work) [#6625](https://github.com/hyperledger/besu/pull/6625), [#6667](https://github.com/hyperledger/besu/pull/6667)
### Upcoming Breaking Changes
- Receipt compaction will be enabled by default in a future version of Besu. After this change it will not be possible to downgrade to the previous Besu version.
### Deprecations
@@ -25,11 +26,13 @@
- `eth_call` for blob tx allows for empty `maxFeePerBlobGas` [#6731](https://github.com/hyperledger/besu/pull/6731)
- Extend error handling of plugin RPC methods [#6759](https://github.com/hyperledger/besu/pull/6759)
- Added engine_newPayloadV4 and engine_getPayloadV4 methods [#6783](https://github.com/hyperledger/besu/pull/6783)
- Reduce storage size of receipts [#6602](https://github.com/hyperledger/besu/pull/6602)
### Bug fixes
- Fix txpool dump/restore race condition [#6665](https://github.com/hyperledger/besu/pull/6665)
- Make block transaction selection max time aware of PoA transitions [#6676](https://github.com/hyperledger/besu/pull/6676)
- Don't enable the BFT mining coordinator when running sub commands such as `blocks export` [#6675](https://github.com/hyperledger/besu/pull/6675)
- In JSON-RPC return optional `v` fields for type 1 and type 2 transactions [#6762](https://github.com/hyperledger/besu/pull/6762)
### Download Links

View File

@@ -56,15 +56,12 @@ import java.math.BigInteger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.After;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Superclass for acceptance tests. For now (transition to junit5 is ongoing) this class supports
* junit4 format.
*/
/** Superclass for acceptance tests. */
@ExtendWith(AcceptanceTestBaseTestWatcher.class)
public class AcceptanceTestBase {
@@ -131,7 +128,7 @@ public class AcceptanceTestBase {
exitedSuccessfully = new ExitedWithCode(0);
}
@After
@AfterEach
public void tearDownAcceptanceTestBase() {
reportMemory();
cluster.close();

View File

@@ -62,6 +62,7 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
@@ -431,7 +432,9 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
getGenesisConfig()
.map(
gc ->
gc.toLowerCase().contains("ibft") ? ConsensusType.IBFT2 : ConsensusType.QBFT)
gc.toLowerCase(Locale.ROOT).contains("ibft")
? ConsensusType.IBFT2
: ConsensusType.QBFT)
.orElse(ConsensusType.IBFT2);
nodeRequests =
@@ -786,6 +789,21 @@ public class BesuNode implements NodeConfiguration, RunnableNode, AutoCloseable
nodeRequests.shutdown();
nodeRequests = null;
}
deleteRuntimeFiles();
}
private void deleteRuntimeFiles() {
try {
Files.deleteIfExists(homeDirectory.resolve("besu.networks"));
} catch (IOException e) {
LOG.error("Failed to clean up besu.networks file in {}", homeDirectory, e);
}
try {
Files.deleteIfExists(homeDirectory.resolve("besu.ports"));
} catch (IOException e) {
LOG.error("Failed to clean up besu.ports file in {}", homeDirectory, e);
}
}
@Override

View File

@@ -52,6 +52,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
@@ -77,8 +78,15 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner {
final Path dataDir = node.homeDirectory();
final var workingDir =
new File(System.getProperty("user.dir")).getParentFile().getParentFile().toPath();
final List<String> params = new ArrayList<>();
params.add("build/install/besu/bin/besu");
if (SystemUtils.IS_OS_WINDOWS) {
params.add(workingDir.resolve("build\\install\\besu\\bin\\besu.bat").toString());
} else {
params.add("build/install/besu/bin/besu");
}
params.add("--data-path");
params.add(dataDir.toAbsolutePath().toString());
@@ -422,15 +430,13 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner {
LOG.info("Creating besu process with params {}", params);
final ProcessBuilder processBuilder =
new ProcessBuilder(params)
.directory(new File(System.getProperty("user.dir")).getParentFile().getParentFile())
.directory(workingDir.toFile())
.redirectErrorStream(true)
.redirectInput(Redirect.INHERIT);
if (!node.getPlugins().isEmpty()) {
processBuilder
.environment()
.put(
"BESU_OPTS",
"-Dbesu.plugins.dir=" + dataDir.resolve("plugins").toAbsolutePath().toString());
.put("BESU_OPTS", "-Dbesu.plugins.dir=" + dataDir.resolve("plugins").toAbsolutePath());
}
// Use non-blocking randomness for acceptance tests
processBuilder
@@ -572,7 +578,7 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner {
LOG.info("Killing {} process, pid {}", name, process.pid());
process.destroy();
process.descendants().forEach(ProcessHandle::destroy);
try {
process.waitFor(30, TimeUnit.SECONDS);
} catch (final InterruptedException e) {

View File

@@ -20,6 +20,7 @@ import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.web3j.crypto.Credentials;
@@ -83,7 +84,7 @@ public class DeploySmartContractTransaction<T extends Contract> implements Trans
@SuppressWarnings("rawtypes")
private boolean parameterTypesAreEqual(
final Class<?>[] expectedTypes, final ArrayList<Object> actualObjects) {
final Class<?>[] expectedTypes, final List<Object> actualObjects) {
if (expectedTypes.length != actualObjects.size()) {
return false;
}

View File

@@ -133,6 +133,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -800,7 +801,7 @@ public class RunnerBuilder {
metricsSystem,
supportedCapabilities,
jsonRpcConfiguration.getRpcApis().stream()
.filter(apiGroup -> !apiGroup.toLowerCase().startsWith("engine"))
.filter(apiGroup -> !apiGroup.toLowerCase(Locale.ROOT).startsWith("engine"))
.collect(Collectors.toList()),
filterManager,
accountLocalConfigPermissioningController,
@@ -938,7 +939,7 @@ public class RunnerBuilder {
metricsSystem,
supportedCapabilities,
webSocketConfiguration.getRpcApis().stream()
.filter(apiGroup -> !apiGroup.toLowerCase().startsWith("engine"))
.filter(apiGroup -> !apiGroup.toLowerCase(Locale.ROOT).startsWith("engine"))
.collect(Collectors.toList()),
filterManager,
accountLocalConfigPermissioningController,
@@ -1021,7 +1022,7 @@ public class RunnerBuilder {
metricsSystem,
supportedCapabilities,
jsonRpcIpcConfiguration.getEnabledApis().stream()
.filter(apiGroup -> !apiGroup.toLowerCase().startsWith("engine"))
.filter(apiGroup -> !apiGroup.toLowerCase(Locale.ROOT).startsWith("engine"))
.collect(Collectors.toList()),
filterManager,
accountLocalConfigPermissioningController,

View File

@@ -2623,10 +2623,7 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
SignatureAlgorithmFactory.setInstance(SignatureAlgorithmType.create(ecCurve.get()));
} catch (final IllegalArgumentException e) {
throw new CommandLine.InitializationException(
new StringBuilder()
.append("Invalid genesis file configuration for ecCurve. ")
.append(e.getMessage())
.toString());
"Invalid genesis file configuration for ecCurve. " + e.getMessage());
}
}

View File

@@ -15,6 +15,7 @@
package org.hyperledger.besu.cli.config;
import java.math.BigInteger;
import java.util.Locale;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
@@ -95,7 +96,7 @@ public enum NetworkName {
* @return the string
*/
public String normalize() {
return StringUtils.capitalize(name().toLowerCase());
return StringUtils.capitalize(name().toLowerCase(Locale.ROOT));
}
/**

View File

@@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.cli.config;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
/** Enum for profile names. Each profile corresponds to a configuration file. */
@@ -51,6 +53,6 @@ public enum ProfileName {
@Override
public String toString() {
return StringUtils.capitalize(name().replaceAll("_", " ").toLowerCase());
return StringUtils.capitalize(name().replaceAll("_", " ").toLowerCase(Locale.ROOT));
}
}

View File

@@ -18,6 +18,7 @@ import org.hyperledger.besu.plugin.services.metrics.MetricCategory;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import com.google.common.annotations.VisibleForTesting;
@@ -54,7 +55,7 @@ public class MetricCategoryConverter implements CommandLine.ITypeConverter<Metri
* @param metricCategory the metric category
*/
public void addRegistryCategory(final MetricCategory metricCategory) {
metricCategories.put(metricCategory.getName().toUpperCase(), metricCategory);
metricCategories.put(metricCategory.getName().toUpperCase(Locale.ROOT), metricCategory);
}
/**

View File

@@ -17,6 +17,7 @@
package org.hyperledger.besu.cli.options.stable;
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD;
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.DEFAULT_RECEIPT_COMPACTION_ENABLED;
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED;
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_LIMIT_TRIE_LOGS_ENABLED;
import static org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration.Unstable.DEFAULT_BONSAI_TRIE_LOG_PRUNING_WINDOW_SIZE;
@@ -29,6 +30,7 @@ import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguratio
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import picocli.CommandLine;
@@ -61,6 +63,12 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
arity = "1")
private Long bonsaiMaxLayersToLoad = DEFAULT_BONSAI_MAX_LAYERS_TO_LOAD;
@Option(
names = "--receipt-compaction-enabled",
description = "Enables compact storing of receipts (default: ${DEFAULT-VALUE}).",
arity = "1")
private Boolean receiptCompactionEnabled = DEFAULT_RECEIPT_COMPACTION_ENABLED;
@CommandLine.ArgGroup(validate = false)
private final DataStorageOptions.Unstable unstableOptions = new Unstable();
@@ -149,6 +157,7 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
final DataStorageOptions dataStorageOptions = DataStorageOptions.create();
dataStorageOptions.dataStorageFormat = domainObject.getDataStorageFormat();
dataStorageOptions.bonsaiMaxLayersToLoad = domainObject.getBonsaiMaxLayersToLoad();
dataStorageOptions.receiptCompactionEnabled = domainObject.getReceiptCompactionEnabled();
dataStorageOptions.unstableOptions.bonsaiLimitTrieLogsEnabled =
domainObject.getUnstable().getBonsaiLimitTrieLogsEnabled();
dataStorageOptions.unstableOptions.bonsaiTrieLogPruningWindowSize =
@@ -164,6 +173,7 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
return ImmutableDataStorageConfiguration.builder()
.dataStorageFormat(dataStorageFormat)
.bonsaiMaxLayersToLoad(bonsaiMaxLayersToLoad)
.receiptCompactionEnabled(receiptCompactionEnabled)
.unstable(
ImmutableDataStorageConfiguration.Unstable.builder()
.bonsaiLimitTrieLogsEnabled(unstableOptions.bonsaiLimitTrieLogsEnabled)
@@ -184,6 +194,6 @@ public class DataStorageOptions implements CLIOptions<DataStorageConfiguration>
* @return the normalized string
*/
public String normalizeDataStorageFormat() {
return StringUtils.capitalize(dataStorageFormat.toString().toLowerCase());
return StringUtils.capitalize(dataStorageFormat.toString().toLowerCase(Locale.ROOT));
}
}

View File

@@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.cli.options.stable;
import java.util.Locale;
import java.util.Set;
import picocli.CommandLine;
@@ -52,8 +53,8 @@ public class LoggingLevelOption {
if ("FATAL".equalsIgnoreCase(logLevel)) {
System.out.println("FATAL level is deprecated");
this.logLevel = "ERROR";
} else if (ACCEPTED_VALUES.contains(logLevel.toUpperCase())) {
this.logLevel = logLevel.toUpperCase();
} else if (ACCEPTED_VALUES.contains(logLevel.toUpperCase(Locale.ROOT))) {
this.logLevel = logLevel.toUpperCase(Locale.ROOT);
} else {
throw new CommandLine.ParameterException(
spec.commandLine(), "Unknown logging value: " + logLevel);

View File

@@ -178,11 +178,9 @@ class GenerateBlockchainConfig implements Runnable {
if (!SIGNATURE_ALGORITHM.get().isValidPublicKey(publicKey)) {
throw new IllegalArgumentException(
new StringBuilder()
.append(publicKeyText)
.append(" is not a valid public key for elliptic curve ")
.append(SIGNATURE_ALGORITHM.get().getCurveName())
.toString());
publicKeyText
+ " is not a valid public key for elliptic curve "
+ SIGNATURE_ALGORITHM.get().getCurveName());
}
writeKeypair(publicKey, null);
@@ -297,10 +295,7 @@ class GenerateBlockchainConfig implements Runnable {
SignatureAlgorithmFactory.setInstance(SignatureAlgorithmType.create(ecCurve.get()));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(
new StringBuilder()
.append("Invalid parameter for ecCurve in genesis config: ")
.append(e.getMessage())
.toString());
"Invalid parameter for ecCurve in genesis config: " + e.getMessage());
}
}

View File

@@ -27,9 +27,9 @@ import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.ethereum.rlp.RLP;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogFactoryImpl;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogLayer;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.trielog.TrieLogFactoryImpl;
import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import java.io.File;

View File

@@ -25,8 +25,8 @@ import org.hyperledger.besu.controller.BesuController;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogPruner;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogPruner;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.plugin.services.storage.DataStorageFormat;

View File

@@ -19,8 +19,8 @@ package org.hyperledger.besu.components;
import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.ethereum.eth.transactions.BlobCache;
import org.hyperledger.besu.ethereum.eth.transactions.BlobCacheModule;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.CachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.CachedMerkleTrieLoaderModule;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoaderModule;
import org.hyperledger.besu.metrics.MetricsSystemModule;
import org.hyperledger.besu.metrics.ObservableMetricsSystem;
import org.hyperledger.besu.services.BesuPluginContextImpl;
@@ -37,7 +37,7 @@ import org.slf4j.Logger;
modules = {
BesuCommandModule.class,
MetricsSystemModule.class,
CachedMerkleTrieLoaderModule.class,
BonsaiCachedMerkleTrieLoaderModule.class,
BesuPluginContextModule.class,
BlobCacheModule.class
})
@@ -55,7 +55,7 @@ public interface BesuComponent {
*
* @return CachedMerkleTrieLoader
*/
CachedMerkleTrieLoader getCachedMerkleTrieLoader();
BonsaiCachedMerkleTrieLoader getCachedMerkleTrieLoader();
/**
* a metrics system that is observable by a Prometheus or OTEL metrics collection subsystem

View File

@@ -81,11 +81,11 @@ import org.hyperledger.besu.ethereum.p2p.config.NetworkingConfiguration;
import org.hyperledger.besu.ethereum.p2p.config.SubProtocolConfiguration;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.ethereum.trie.bonsai.BonsaiWorldStateProvider;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.CachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogManager;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogPruner;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogManager;
import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogPruner;
import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive;
import org.hyperledger.besu.ethereum.trie.forest.pruner.MarkSweepPruner;
import org.hyperledger.besu.ethereum.trie.forest.pruner.Pruner;
@@ -564,7 +564,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
storageProvider.createWorldStateStorageCoordinator(dataStorageConfiguration);
final BlockchainStorage blockchainStorage =
storageProvider.createBlockchainStorage(protocolSchedule, variablesStorage);
storageProvider.createBlockchainStorage(
protocolSchedule, variablesStorage, dataStorageConfiguration);
final MutableBlockchain blockchain =
DefaultBlockchain.createMutable(
@@ -575,13 +576,14 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
dataDirectory.toString(),
numberOfBlocksToCache);
final CachedMerkleTrieLoader cachedMerkleTrieLoader =
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader =
besuComponent
.map(BesuComponent::getCachedMerkleTrieLoader)
.orElseGet(() -> new CachedMerkleTrieLoader(metricsSystem));
.orElseGet(() -> new BonsaiCachedMerkleTrieLoader(metricsSystem));
final WorldStateArchive worldStateArchive =
createWorldStateArchive(worldStateStorageCoordinator, blockchain, cachedMerkleTrieLoader);
createWorldStateArchive(
worldStateStorageCoordinator, blockchain, bonsaiCachedMerkleTrieLoader);
if (blockchain.getChainHeadBlockNumber() < 1) {
genesisState.writeStateTo(worldStateArchive.getMutable());
@@ -1047,7 +1049,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
WorldStateArchive createWorldStateArchive(
final WorldStateStorageCoordinator worldStateStorageCoordinator,
final Blockchain blockchain,
final CachedMerkleTrieLoader cachedMerkleTrieLoader) {
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader) {
return switch (dataStorageConfiguration.getDataStorageFormat()) {
case BONSAI -> {
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage =
@@ -1056,7 +1058,7 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
worldStateKeyValueStorage,
blockchain,
Optional.of(dataStorageConfiguration.getBonsaiMaxLayersToLoad()),
cachedMerkleTrieLoader,
bonsaiCachedMerkleTrieLoader,
besuComponent.map(BesuComponent::getBesuPluginContext).orElse(null),
evmConfiguration);
}
@@ -1066,6 +1068,8 @@ public abstract class BesuControllerBuilder implements MiningParameterOverrides
yield new ForestWorldStateArchive(
worldStateStorageCoordinator, preimageStorage, evmConfiguration);
}
default -> throw new IllegalStateException(
"Unexpected value: " + dataStorageConfiguration.getDataStorageFormat());
};
}

View File

@@ -249,6 +249,7 @@ public class TransitionBesuControllerBuilder extends BesuControllerBuilder {
return sync;
}
@SuppressWarnings("UnusedVariable")
private void initTransitionWatcher(
final ProtocolContext protocolContext, final TransitionCoordinator composedCoordinator) {

View File

@@ -67,4 +67,38 @@ public class BesuConfigurationImpl implements BesuConfiguration {
public Wei getMinGasPrice() {
return miningParameters.getMinTransactionGasPrice();
}
@Override
public org.hyperledger.besu.plugin.services.storage.DataStorageConfiguration
getDataStorageConfiguration() {
return new DataStoreConfigurationImpl(dataStorageConfiguration);
}
/**
* A concrete implementation of DataStorageConfiguration which is used in Besu plugin framework.
*/
public static class DataStoreConfigurationImpl
implements org.hyperledger.besu.plugin.services.storage.DataStorageConfiguration {
private final DataStorageConfiguration dataStorageConfiguration;
/**
* Instantiate the concrete implementation of the plugin DataStorageConfiguration.
*
* @param dataStorageConfiguration The Ethereum core module data storage configuration
*/
public DataStoreConfigurationImpl(final DataStorageConfiguration dataStorageConfiguration) {
this.dataStorageConfiguration = dataStorageConfiguration;
}
@Override
public DataStorageFormat getDatabaseFormat() {
return dataStorageConfiguration.getDataStorageFormat();
}
@Override
public boolean getReceiptCompactionEnabled() {
return dataStorageConfiguration.getReceiptCompactionEnabled();
}
}
}

View File

@@ -24,6 +24,7 @@ import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -58,7 +59,10 @@ public class RpcEndpointServiceImpl implements RpcEndpointService {
namespaces.stream()
.anyMatch(
namespace ->
entry.getKey().toUpperCase().startsWith(namespace.toUpperCase())))
entry
.getKey()
.toUpperCase(Locale.ROOT)
.startsWith(namespace.toUpperCase(Locale.ROOT))))
.map(entry -> new PluginJsonRpcMethod(entry.getKey(), entry.getValue()))
.collect(Collectors.toMap(PluginJsonRpcMethod::getName, e -> e));
}
@@ -71,6 +75,7 @@ public class RpcEndpointServiceImpl implements RpcEndpointService {
*/
public boolean hasNamespace(final String namespace) {
return rpcMethods.keySet().stream()
.anyMatch(key -> key.toUpperCase().startsWith(namespace.toUpperCase()));
.anyMatch(
key -> key.toUpperCase(Locale.ROOT).startsWith(namespace.toUpperCase(Locale.ROOT)));
}
}

View File

@@ -110,6 +110,24 @@ public class DataStorageOptionsTest
"false");
}
@Test
public void receiptCompactionCanBeEnabled() {
internalTestSuccess(
dataStorageConfiguration ->
assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(true),
"--receipt-compaction-enabled",
"true");
}
@Test
public void receiptCompactionCanBeDisabled() {
internalTestSuccess(
dataStorageConfiguration ->
assertThat(dataStorageConfiguration.getReceiptCompactionEnabled()).isEqualTo(false),
"--receipt-compaction-enabled",
"false");
}
@Override
protected DataStorageConfiguration createDefaultDomainObject() {
return DataStorageConfiguration.DEFAULT_CONFIG;

View File

@@ -31,9 +31,9 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture;
import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogFactoryImpl;
import org.hyperledger.besu.ethereum.trie.bonsai.trielog.TrieLogLayer;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.trielog.TrieLogFactoryImpl;
import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.TrieLogLayer;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
import org.hyperledger.besu.ethereum.worldstate.ImmutableDataStorageConfiguration;
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;

View File

@@ -108,12 +108,13 @@ public abstract class AbstractBftBesuControllerBuilderTest {
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
lenient()
.when(storageProvider.createBlockchainStorage(any(), any()))
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
new MainnetBlockHeaderFunctions(),
false));
lenient()
.when(
storageProvider.createWorldStateStorageCoordinator(

View File

@@ -43,9 +43,9 @@ import org.hyperledger.besu.ethereum.storage.StorageProvider;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier;
import org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueStoragePrefixedKeyBlockchainStorage;
import org.hyperledger.besu.ethereum.storage.keyvalue.VariablesKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.cache.CachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.BonsaiCachedMerkleTrieLoader;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.forest.pruner.PrunerConfiguration;
import org.hyperledger.besu.ethereum.trie.forest.storage.ForestWorldStateKeyValueStorage;
import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration;
@@ -124,12 +124,13 @@ public class BesuControllerBuilderTest {
when(ethashConfigOptions.getFixedDifficulty()).thenReturn(OptionalLong.empty());
when(storageProvider.getStorageBySegmentIdentifier(any()))
.thenReturn(new InMemoryKeyValueStorage());
when(storageProvider.createBlockchainStorage(any(), any()))
when(storageProvider.createBlockchainStorage(any(), any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
new MainnetBlockHeaderFunctions(),
false));
when(synchronizerConfiguration.getDownloaderParallelism()).thenReturn(1);
when(synchronizerConfiguration.getTransactionsParallelism()).thenReturn(1);
when(synchronizerConfiguration.getComputationParallelism()).thenReturn(1);
@@ -188,7 +189,7 @@ public class BesuControllerBuilderTest {
.createWorldStateArchive(
any(WorldStateStorageCoordinator.class),
any(Blockchain.class),
any(CachedMerkleTrieLoader.class));
any(BonsaiCachedMerkleTrieLoader.class));
doReturn(mockWorldState).when(worldStateArchive).getMutable();
when(storageProvider.createWorldStateStorageCoordinator(dataStorageConfiguration))
.thenReturn(new WorldStateStorageCoordinator(bonsaiWorldStateStorage));

View File

@@ -117,12 +117,13 @@ public class CliqueBesuControllerBuilderTest {
lenient().when(genesisConfigFile.getConfigOptions()).thenReturn(genesisConfigOptions);
lenient().when(genesisConfigOptions.getCheckpointOptions()).thenReturn(checkpointConfigOptions);
lenient()
.when(storageProvider.createBlockchainStorage(any(), any()))
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
new MainnetBlockHeaderFunctions(),
false));
lenient()
.when(
storageProvider.createWorldStateStorageCoordinator(

View File

@@ -133,12 +133,13 @@ public class MergeBesuControllerBuilderTest {
when(genesisConfigOptions.getTerminalBlockHash()).thenReturn(Optional.of(Hash.ZERO));
lenient().when(genesisConfigOptions.getTerminalBlockNumber()).thenReturn(OptionalLong.of(1L));
lenient()
.when(storageProvider.createBlockchainStorage(any(), any()))
.when(storageProvider.createBlockchainStorage(any(), any(), any()))
.thenReturn(
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()));
new MainnetBlockHeaderFunctions(),
false));
lenient()
.when(storageProvider.getStorageBySegmentIdentifier(any()))
.thenReturn(new InMemoryKeyValueStorage());

View File

@@ -122,7 +122,8 @@ public class BesuEventsImplTest {
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()),
new MainnetBlockHeaderFunctions(),
false),
new NoOpMetricsSystem(),
0);

View File

@@ -215,6 +215,7 @@ ethstats-cacert-file="./root.cert"
# Data storage
data-storage-format="BONSAI"
bonsai-historical-block-limit=512
receipt-compaction-enabled=true
# feature flags
Xsecp256k1-native-enabled=false

View File

@@ -29,7 +29,7 @@ plugins {
id 'com.jfrog.artifactory' version '5.1.11'
id 'io.spring.dependency-management' version '1.1.4'
id 'me.champeau.jmh' version '0.7.2' apply false
id 'net.ltgt.errorprone' version '3.0.1'
id 'net.ltgt.errorprone' version '3.1.0'
id 'maven-publish'
}
@@ -75,6 +75,9 @@ def _strListCmdArg(name) {
return _strListCmdArg(name, null)
}
// set the shell command to use according to os
def shell = org.gradle.internal.os.OperatingSystem.current().isWindows() ? "${projectDir}\\wslsh.bat" : '/bin/bash'
licenseReport {
// This is for the allowed-licenses-file in checkLicense Task
// Accepts File, URL or String path to local or remote file
@@ -115,12 +118,12 @@ allprojects {
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
archiveClassifier = 'javadoc'
from javadoc.outputDirectory
}
@@ -143,6 +146,7 @@ allprojects {
url 'https://splunk.jfrog.io/splunk/ext-releases-local'
content { includeGroupByRegex('com\\.splunk\\..*') }
}
mavenCentral()
// ethereum execution spec tests fixtures. Exclusively for ethereum submodule to run ref tests
@@ -164,6 +168,8 @@ allprojects {
dependencies {
components.all(BouncyCastleCapability)
errorprone 'com.google.errorprone:error_prone_core'
// https://github.com/hyperledger/besu-errorprone-checks/
errorprone "org.hyperledger.besu:besu-errorprone-checks"
}
configurations.all {
@@ -199,7 +205,7 @@ allprojects {
format 'sol', { target '**/*.sol' }
}
tasks.withType(JavaCompile) {
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += [
'-Xlint:unchecked',
'-Xlint:cast',
@@ -212,8 +218,8 @@ allprojects {
]
options.errorprone {
excludedPaths = '.*/(generated/*.*|.*ReferenceTest_.*|build/.*/annotation-output/.*)'
excludedPaths = '.*/generated/*.*'
disableWarningsInGeneratedCode = true
// Our equals need to be symmetric, this checker doesn't respect that.
check('EqualsGetClass', CheckSeverity.OFF)
// We like to use futures with no return values.
@@ -275,7 +281,7 @@ allprojects {
*
*/
test {
jvmArgs = [
jvmArgs += [
'-Xmx4g',
'-XX:-UseGCOverheadLimit',
// Mockito and jackson-databind do some strange reflection during tests.
@@ -380,7 +386,7 @@ subprojects {
task testSupportJar(type: Jar) {
archiveBaseName = "${project.name}-support-test"
classifier = 'test-support'
archiveClassifier = 'test-support'
from sourceSets.testSupport.output
}
}
@@ -739,7 +745,7 @@ task distDocker {
println "Building for platform ${project.getProperty('docker-platform')}"
}
def gitDetails = getGitCommitDetails(10)
executable "sh"
executable shell
workingDir dockerBuildDir
args "-c", "docker build ${dockerPlatform} --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${gitDetails.hash} -t ${image} ."
}
@@ -747,7 +753,7 @@ task distDocker {
// tag the "default" (which is the variant in the zero position)
exec {
executable "sh"
executable shell
args "-c", "docker tag '${dockerImageName}:${dockerBuildVersion}-${dockerVariants[0]}' '${dockerImageName}:${dockerBuildVersion}'"
}
}
@@ -766,8 +772,8 @@ task testDocker {
exec {
def image = project.hasProperty('release.releaseVersion') ? "${dockerImageName}:" + project.property('release.releaseVersion') : "${dockerImageName}:${project.version}"
workingDir "${projectDir}/docker/${variant}"
executable "sh"
args "-c", "bash ../test.sh ${image}-${variant}"
executable shell
args "-c", "../test.sh ${image}-${variant}"
}
}
}
@@ -795,7 +801,7 @@ task dockerUpload {
def cmd = "docker tag '${variantImage}' '${archVariantImage}' && docker push '${archVariantImage}'"
additionalTags.each { tag -> cmd += " && docker tag '${variantImage}' '${dockerImageName}:${tag.trim()}-${variant}-${architecture}' && docker push '${dockerImageName}:${tag.trim()}-${variant}-${architecture}'" }
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -805,7 +811,7 @@ task dockerUpload {
def cmd = "docker tag ${image} ${archImage} && docker push '${archImage}'"
additionalTags.each { tag -> cmd += " && docker tag '${image}' '${dockerImageName}:${tag.trim()}-${architecture}' && docker push '${dockerImageName}:${tag.trim()}-${architecture}'" }
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -822,13 +828,13 @@ task dockerUploadRelease {
exec {
def cmd = "docker pull '${variantImage}-${architecture}' && docker tag '${variantImage}-${architecture}' '${dockerImageName}:latest-${variant}-${architecture}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
exec {
def cmd = "docker push '${dockerImageName}:latest-${variant}-${architecture}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -837,13 +843,13 @@ task dockerUploadRelease {
def archImage = "${image}-${architecture}"
def cmd = "docker pull '${archImage}' && docker tag ${archImage} '${dockerImageName}:latest-${architecture}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
exec {
def cmd = "docker push '${dockerImageName}:latest-${architecture}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -873,13 +879,13 @@ task manifestDocker {
exec {
def cmd = "docker manifest create '${variantImage}' ${targets}"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
exec {
def cmd = "docker manifest push '${variantImage}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -889,13 +895,13 @@ task manifestDocker {
archs.forEach { arch -> targets += "'${baseTag}-${arch}' " }
def cmd = "docker manifest create '${baseTag}' ${targets}"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
exec {
def cmd = "docker manifest push '${baseTag}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -915,13 +921,13 @@ task manifestDockerRelease {
exec {
def cmd = "docker manifest create '${variantImage}' ${targets} --amend"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
exec {
def cmd = "docker manifest push '${variantImage}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -931,13 +937,13 @@ task manifestDockerRelease {
archs.forEach { arch -> targets += "'${baseTag}-${arch}' " }
def cmd = "docker manifest create '${baseTag}' ${targets} --amend"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
exec {
def cmd = "docker manifest push '${baseTag}'"
println "Executing '${cmd}'"
executable "sh"
executable shell
args "-c", cmd
}
}
@@ -968,7 +974,7 @@ task checkSpdxHeader(type: CheckSpdxHeader) {
jacocoTestReport {
reports {
xml.enabled true
xml.required = true
}
}
@@ -979,25 +985,12 @@ task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
executionData.from fileTree(dir: '.', includes: ['**/jacoco/*.exec'])
reports {
xml.required = true
xml.enabled = true
csv.required = true
html.destination file("build/reports/jacocoHtml")
}
onlyIf = { true }
}
configurations { annotationProcessor }
// Prevent errorprone-checks being dependent upon errorprone-checks!
// However, ensure all subprojects comply with the custom rules.
configure(subprojects.findAll { it.name != 'errorprone-checks' }) {
dependencies { annotationProcessor project(":errorprone-checks") }
tasks.withType(JavaCompile) {
options.annotationProcessorPath = configurations.annotationProcessor
}
}
// http://label-schema.org/rc1/
// using the RFC3339 format "2016-04-12T23:20:50.52Z"
def buildTime() {
@@ -1078,9 +1071,11 @@ tasks.register("verifyDistributions") {
}
dependencies {
errorprone 'com.google.errorprone:error_prone_core'
// https://github.com/hyperledger/besu-errorprone-checks/
errorprone 'org.hyperledger.besu:besu-errorprone-checks'
implementation project(':besu')
implementation project(':ethereum:evmtool')
errorprone 'com.google.errorprone:error_prone_core'
}
@CompileStatic

View File

@@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Address;
import java.math.BigInteger;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.OptionalInt;
@@ -89,7 +90,7 @@ public class BftFork implements Fork {
return Optional.empty();
}
final String weiStr = configFileContent.get();
if (weiStr.toLowerCase().startsWith("0x")) {
if (weiStr.toLowerCase(Locale.ROOT).startsWith("0x")) {
return Optional.of(new BigInteger(1, Bytes.fromHexStringLenient(weiStr).toArrayUnsafe()));
}
return Optional.of(new BigInteger(weiStr));

View File

@@ -17,6 +17,7 @@ package org.hyperledger.besu.config;
import org.hyperledger.besu.datatypes.Address;
import java.math.BigInteger;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
@@ -117,7 +118,7 @@ public class JsonBftConfigOptions implements BftConfigOptions {
return BigInteger.ZERO;
}
final String weiStr = configFileContent.get();
if (weiStr.toLowerCase().startsWith("0x")) {
if (weiStr.toLowerCase(Locale.ROOT).startsWith("0x")) {
return new BigInteger(1, Bytes.fromHexStringLenient(weiStr).toArrayUnsafe());
}
return new BigInteger(weiStr);

View File

@@ -446,7 +446,8 @@ public class JsonUtil {
final String errorMessage =
String.format(
"Expected %s value but got %s",
expectedType.toString().toLowerCase(), node.getNodeType().toString().toLowerCase());
expectedType.toString().toLowerCase(Locale.ROOT),
node.getNodeType().toString().toLowerCase(Locale.ROOT));
throw new IllegalArgumentException(errorMessage);
}
return true;

View File

@@ -17,6 +17,7 @@
"cancunTime": 1707305664,
"ethash": {},
"discovery": {
"dns": "AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.holesky.ethdisco.net",
"bootnodes": [
"enode://ac906289e4b7f12df423d654c5a962b6ebe5b3a74cc9e06292a85221f9a64a6f1cfdd6b714ed6dacef51578f92b34c60ee91e9ede9c7f8fadc4d347326d95e2b@146.190.13.128:30303",
"enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303"

View File

@@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.Util;
import java.util.ArrayList;
import java.util.List;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
@@ -29,11 +30,11 @@ import com.google.common.collect.Iterables;
public class NetworkLayout {
private final NodeParams localNode;
private final TreeMap<Address, NodeParams> addressKeyMap;
private final NavigableMap<Address, NodeParams> addressKeyMap;
private final List<NodeParams> remotePeers;
public NetworkLayout(
final NodeParams localNode, final TreeMap<Address, NodeParams> addressKeyMap) {
final NodeParams localNode, final NavigableMap<Address, NodeParams> addressKeyMap) {
this.localNode = localNode;
this.addressKeyMap = addressKeyMap;
this.remotePeers = new ArrayList<>(addressKeyMap.values());
@@ -42,14 +43,14 @@ public class NetworkLayout {
public static NetworkLayout createNetworkLayout(
final int validatorCount, final int firstLocalNodeBlockNum) {
final TreeMap<Address, NodeParams> addressKeyMap = createValidators(validatorCount);
final NavigableMap<Address, NodeParams> addressKeyMap = createValidators(validatorCount);
final NodeParams localNode = Iterables.get(addressKeyMap.values(), firstLocalNodeBlockNum);
return new NetworkLayout(localNode, addressKeyMap);
}
private static TreeMap<Address, NodeParams> createValidators(final int validatorCount) {
private static NavigableMap<Address, NodeParams> createValidators(final int validatorCount) {
// Map is required to be sorted by address
final TreeMap<Address, NodeParams> addressKeyMap = new TreeMap<>();

View File

@@ -49,10 +49,8 @@ public class SignatureAlgorithmFactory {
if (!SignatureAlgorithmType.isDefault(instance)) {
LOG.info(
new StringBuilder("The signature algorithm uses the elliptic curve ")
.append(instance.getCurveName())
.append(". The usage of alternative elliptic curves is still experimental.")
.toString());
"The signature algorithm uses the elliptic curve {}. The usage of alternative elliptic curves is still experimental.",
instance.getCurveName());
}
}

View File

@@ -94,11 +94,9 @@ public class SignatureAlgorithmType {
}
private static String invalidTypeErrorMessage(final String invalidEcCurve) {
return new StringBuilder()
.append(invalidEcCurve)
.append(" is not in the list of valid elliptic curves ")
.append(getEcCurvesListAsString())
.toString();
return invalidEcCurve
+ " is not in the list of valid elliptic curves "
+ getEcCurvesListAsString();
}
private static String getEcCurvesListAsString() {

View File

@@ -160,7 +160,7 @@ public class SECP256R1Test {
final BigInteger recoveredPubKeyBigInt =
secp256R1.recoverFromSignature(
signature.getRecId(), signature.getR(), signature.getS(), dataHash);
assertThat(recoveredPubKeyBigInt).isEqualTo(recoveredPubKeyBigInt);
assertThat(recoveredPubKeyBigInt).isEqualTo(publicKeyBigInt);
});
}

View File

@@ -16,6 +16,7 @@ package org.hyperledger.besu.datatypes;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Locale;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.BaseUInt256Value;
@@ -224,7 +225,7 @@ public final class Wei extends BaseUInt256Value<Wei> implements Quantity {
@Override
public String toString() {
return name().toLowerCase();
return name().toLowerCase(Locale.ROOT);
}
}
}

View File

@@ -32,6 +32,7 @@ import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.StringJoiner;
@@ -93,6 +94,6 @@ public class TlsHelpers {
joiner.add(String.format("%02X", b));
}
return joiner.toString().toLowerCase();
return joiner.toString().toLowerCase(Locale.ROOT);
}
}

View File

@@ -1,9 +0,0 @@
The creation of custom errorprone checkers was largely derived from:
* https://github.com/tbroyer/gradle-errorprone-plugin
* https://errorprone.info/docs/installation
* https://github.com/google/error-prone/wiki/Writing-a-check
To allow for debugging from within intellij, the following must be added to the VM args
in the run/debug configuration (this assumes your gradle cache is at the default location under
your home):
-Xbootclasspath/p:${HOME}/.gradle/caches/./modules-2/files-2.1/com.google.errorprone/javac/9+181-r4173-1/bdf4c0aa7d540ee1f7bf14d47447aea4bbf450c5/javac-9+181-r4173-1.jar

View File

@@ -1,70 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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
*/
// we use this config to get the path of the JDK 9 javac jar, to
// stick it in the bootclasspath when running tests
configurations.maybeCreate("epJavac")
apply plugin: 'java'
apply plugin: 'net.ltgt.errorprone'
sourceCompatibility = 17
targetCompatibility = 17
dependencies {
api 'org.slf4j:slf4j-api'
annotationProcessor 'com.google.auto.service:auto-service'
implementation 'com.google.auto.service:auto-service'
implementation 'com.google.errorprone:error_prone_annotation'
implementation 'com.google.errorprone:error_prone_core'
implementation 'info.picocli:picocli'
testImplementation 'com.google.errorprone:error_prone_test_helpers'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.junit.jupiter:junit-jupiter'
// imported to get org.jetbrains.annotations.NotNull
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib'
epJavac 'com.google.errorprone:error_prone_check_api'
}
test { testLogging { showStandardStreams = true } }
tasks.withType(JavaCompile) {
options.compilerArgs += [
'--add-exports',
'jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
'--add-exports',
'jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED'
]
}
javadoc { enabled = false }

View File

@@ -1,60 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import static com.google.errorprone.matchers.Description.NO_MATCH;
import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod;
import java.util.Map;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Some methods should not be used, make sure that doesn't happen.",
severity = WARNING,
linkType = BugPattern.LinkType.NONE)
public class BannedMethod extends BugChecker implements MethodInvocationTreeMatcher {
private static final ImmutableMap<Matcher<ExpressionTree>, String> BANNED_METHOD_LIST =
ImmutableMap.of(
staticMethod().onClass("com.google.common.base.Objects").withAnyName(),
"Do not use com.google.common.base.Objects methods, use java.util.Objects methods instead.",
staticMethod().onClass("org.junit.Assert"),
"Do not use junit assertions. Use assertj assertions instead.",
staticMethod().onClass("org.apache.logging.log4j.LogManager"),
"Do not use org.apache.logging.log4j.LogManager, use org.slf4j.LoggerFactory methods instead.");
@Override
public Description matchMethodInvocation(
final MethodInvocationTree tree, final VisitorState state) {
for (final Map.Entry<Matcher<ExpressionTree>, String> entry : BANNED_METHOD_LIST.entrySet()) {
if (entry.getKey().matches(tree, state)) {
return buildDescription(tree).setMessage(entry.getValue()).build();
}
}
return NO_MATCH;
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.NewClassTree;
import com.sun.tools.javac.code.Symbol;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Do not create SecureRandom directly.",
severity = WARNING,
linkType = BugPattern.LinkType.NONE)
public class DoNotCreateSecureRandomDirectly extends BugChecker
implements MethodInvocationTreeMatcher, NewClassTreeMatcher {
@SuppressWarnings("TreeToString")
@Override
public Description matchMethodInvocation(
final MethodInvocationTree tree, final VisitorState state) {
if (tree.getMethodSelect().toString().equals("SecureRandom.getInstance")) {
return describeMatch(tree);
}
return Description.NO_MATCH;
}
@Override
public Description matchNewClass(final NewClassTree tree, final VisitorState state) {
final Symbol sym = ASTHelpers.getSymbol(tree.getIdentifier());
if (sym != null && sym.toString().equals("java.security.SecureRandom")) {
return describeMatch(tree);
}
return Description.NO_MATCH;
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.sun.source.tree.MethodInvocationTree;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Do not invoke MessageDigest.getInstance directly.",
severity = WARNING,
linkType = BugPattern.LinkType.NONE)
public class DoNotInvokeMessageDigestDirectly extends BugChecker
implements MethodInvocationTreeMatcher {
@SuppressWarnings("TreeToString")
@Override
public Description matchMethodInvocation(
final MethodInvocationTree tree, final VisitorState state) {
if (tree.getMethodSelect().toString().equals("MessageDigest.getInstance")) {
return describeMatch(tree);
}
return Description.NO_MATCH;
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION;
import static com.google.errorprone.matchers.Matchers.contains;
import static com.sun.source.tree.Tree.Kind.NULL_LITERAL;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ReturnTree;
import com.sun.source.tree.Tree;
/*
* This is reworked from an example found at:
* https://github.com/google/error-prone/wiki/Writing-a-check
*/
@AutoService(BugChecker.class) // the service descriptor
@BugPattern(
summary = "Do not return null optionals.",
severity = SUGGESTION,
linkType = BugPattern.LinkType.NONE)
public class DoNotReturnNullOptionals extends BugChecker implements MethodTreeMatcher {
private static class ReturnNullMatcher implements Matcher<Tree> {
@Override
public boolean matches(final Tree tree, final VisitorState state) {
if ((tree instanceof ReturnTree) && (((ReturnTree) tree).getExpression() != null)) {
return ((ReturnTree) tree).getExpression().getKind() == NULL_LITERAL;
}
return false;
}
}
private static final Matcher<Tree> RETURN_NULL = new ReturnNullMatcher();
private static final Matcher<Tree> CONTAINS_RETURN_NULL = contains(RETURN_NULL);
@SuppressWarnings("TreeToString")
@Override
public Description matchMethod(final MethodTree tree, final VisitorState state) {
if ((tree.getReturnType() == null)
|| !tree.getReturnType().toString().startsWith("Optional<")
|| (tree.getBody() == null)
|| (!CONTAINS_RETURN_NULL.matches(tree.getBody(), state))) {
return Description.NO_MATCH;
}
return describeMatch(tree);
}
}

View File

@@ -1,76 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import java.util.Map;
import java.util.Optional;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.ExecutableElement;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.AnnotationTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.AnnotationTree;
import com.sun.tools.javac.tree.JCTree;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Experimental options must be hidden and not present in the BesuCommand class.",
severity = WARNING,
linkType = BugPattern.LinkType.NONE)
public class ExperimentalCliOptionMustBeCorrectlyDisplayed extends BugChecker
implements AnnotationTreeMatcher {
@Override
public Description matchAnnotation(AnnotationTree tree, VisitorState state) {
final AnnotationMirror annotationMirror = ASTHelpers.getAnnotationMirror(tree);
if (annotationMirror.getAnnotationType().toString().equals("picocli.CommandLine.Option")) {
final Optional<? extends AnnotationValue> names =
getAnnotationValue(annotationMirror, "names");
if (names.isPresent() && names.get().getValue().toString().contains("--X")) {
final JCTree.JCCompilationUnit compilation =
(JCTree.JCCompilationUnit) state.getPath().getCompilationUnit();
if (compilation.getSourceFile().getName().endsWith("BesuCommand.java")) {
return describeMatch(tree);
}
final Optional<? extends AnnotationValue> isHidden =
getAnnotationValue(annotationMirror, "hidden");
if (isHidden.isEmpty() || !((boolean) isHidden.get().getValue())) {
return describeMatch(tree);
}
}
}
return Description.NO_MATCH;
}
private Optional<? extends AnnotationValue> getAnnotationValue(
final AnnotationMirror annotationMirror, final String name) {
final Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues =
annotationMirror.getElementValues();
final Optional<? extends AnnotationValue> retValue =
elementValues.keySet().stream()
.filter(k -> k.getSimpleName().toString().equals(name))
.map(elementValues::get)
.findAny();
return retValue;
}
}

View File

@@ -1,131 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import javax.lang.model.element.Modifier;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher;
import com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ModifiersTree;
import com.sun.source.tree.VariableTree;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Method input parameters must be final.",
severity = WARNING,
linkType = BugPattern.LinkType.NONE)
public class MethodInputParametersMustBeFinal extends BugChecker
implements MethodTreeMatcher, ClassTreeMatcher {
private boolean isAbstraction = false;
private boolean isGenerated = false;
@Override
public Description matchClass(final ClassTree tree, final VisitorState state) {
isAbstraction =
isInterface(tree.getModifiers())
|| isAnonymousClassInAbstraction(tree)
|| isEnumInAbstraction(tree);
isGenerated = ASTHelpers.hasDirectAnnotationWithSimpleName(tree, "Generated");
return Description.NO_MATCH;
}
@Override
public Description matchMethod(final MethodTree tree, final VisitorState state) {
if (isGenerated) {
return Description.NO_MATCH;
}
final ModifiersTree mods = tree.getModifiers();
if (isAbstraction) {
if (isConcreteMethod(mods)) {
return matchParameters(tree);
}
} else if (isNotAbstract(mods)) {
return matchParameters(tree);
}
return Description.NO_MATCH;
}
private Description matchParameters(final MethodTree tree) {
for (final VariableTree inputParameter : tree.getParameters()) {
if (isMissingFinalModifier(inputParameter)) {
return describeMatch(tree);
}
}
return Description.NO_MATCH;
}
private boolean isMissingFinalModifier(final VariableTree inputParameter) {
return !inputParameter.getModifiers().getFlags().contains(Modifier.FINAL);
}
private boolean isNotAbstract(final ModifiersTree mods) {
return !mods.getFlags().contains(Modifier.ABSTRACT);
}
@SuppressWarnings("TreeToString")
private boolean isInterface(final ModifiersTree mods) {
return mods.toString().contains("interface");
}
private boolean isConcreteMethod(final ModifiersTree mods) {
return mods.getFlags().contains(Modifier.DEFAULT) || mods.getFlags().contains(Modifier.STATIC);
}
private boolean isAnonymousClassInAbstraction(final ClassTree tree) {
return isAbstraction && isAnonymousClass(tree);
}
private boolean isAnonymousClass(final ClassTree tree) {
return tree.getSimpleName().contentEquals("");
}
private boolean isEnumInAbstraction(final ClassTree tree) {
return isAbstraction && isEnum(tree);
}
@SuppressWarnings("TreeToString")
private boolean isEnum(final ClassTree tree) {
return tree.toString().contains("enum");
}
@Override
public boolean equals(Object o) {
// isAbstract and isGenerated are transient calculations, not relevant to equality checks
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
return super.equals(o);
}
@Override
public int hashCode() {
// isAbstract and isGenerated are transient calculations, not relevant to equality checks
return super.hashCode();
}
}

View File

@@ -1,75 +0,0 @@
/*
* (c) Copyright 2023 Palantir Technologies Inc. All rights reserved.
* 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
*/
/* Derived from https://github.com/palantir/gradle-baseline/blob/6fe385a80291473e7fc1441f176454bec4184d6b/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/PreferCommonAnnotations.java */
package org.hyperledger.errorpronechecks;
import java.util.Map;
import java.util.Objects;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.BugPattern.SeverityLevel;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.ImportTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ImportTree;
import com.sun.tools.javac.code.Type;
/**
* Checker that recommends using the common version of an annotation.
*
* <p>Examples: - Guava's version of {@code @VisibleForTesting} over other copies.
*/
@AutoService(BugChecker.class)
@BugPattern(
summary = "Prefer the common version of annotations over other copies.",
severity = SeverityLevel.WARNING)
public final class PreferCommonAnnotations extends BugChecker implements ImportTreeMatcher {
/** ClassName -> preferred import. */
private static final Map<String, String> PREFERRED_IMPORTS =
Map.of("org.jetbrains.annotations.NotNull", "javax.annotation.Nonnull");
@Override
public Description matchImport(ImportTree tree, VisitorState state) {
Type importType = ASTHelpers.getType(tree.getQualifiedIdentifier());
if (importType == null) {
return Description.NO_MATCH;
}
String importName = importType.toString();
for (Map.Entry<String, String> entry : PREFERRED_IMPORTS.entrySet()) {
String affectedClassName = entry.getKey();
String preferredType = entry.getValue();
if (importName.endsWith(affectedClassName) && !Objects.equals(importName, preferredType)) {
SuggestedFix fix =
SuggestedFix.builder().removeImport(importName).addImport(preferredType).build();
return this.buildDescription(tree)
.setMessage("Do not use " + importName + " use " + preferredType + " instead.")
.addFix(fix)
.build();
}
}
return Description.NO_MATCH;
}
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.fixes.SuggestedFixes.addModifiers;
import static com.google.errorprone.matchers.Description.NO_MATCH;
import static com.google.errorprone.util.ASTHelpers.getType;
import static com.google.errorprone.util.ASTHelpers.isSubtype;
import java.util.List;
import java.util.Optional;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.suppliers.Supplier;
import com.google.errorprone.suppliers.Suppliers;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
@AutoService(BugChecker.class)
@BugPattern(
summary = "Logger classes should be private, static, and final.",
severity = WARNING,
linkType = BugPattern.LinkType.NONE)
public class PrivateStaticFinalLoggers extends BugChecker implements VariableTreeMatcher {
static final Supplier<Type> ORG_SLF4J_LOGGER = Suppliers.typeFromString("org.slf4j.Logger");
@Override
public Description matchVariable(final VariableTree tree, final VisitorState state) {
final Symbol.VarSymbol sym = ASTHelpers.getSymbol(tree);
if (sym == null || sym.getKind() != ElementKind.FIELD) {
return NO_MATCH;
}
if (sym.getModifiers()
.containsAll(List.of(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL))) {
return NO_MATCH;
}
if (!isSubtype(getType(tree), ORG_SLF4J_LOGGER.get(state), state)) {
return NO_MATCH;
}
Optional<SuggestedFix> fixes =
addModifiers(tree, state, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL);
return buildDescription(tree)
.addFix(fixes.isPresent() ? fixes.get() : SuggestedFix.emptyFix())
.build();
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class BannedMethodTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper = CompilationTestHelper.newInstance(BannedMethod.class, getClass());
}
@Test
public void bannedMethodsPositiveCases() {
compilationHelper.addSourceFile("BannedMethodPositiveCases.java").doTest();
}
@Test
public void bannedMethodsNegativeCases() {
compilationHelper.addSourceFile("BannedMethodNegativeCases.java").doTest();
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class DoNotCreateSecureRandomDirectlyTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(DoNotCreateSecureRandomDirectly.class, getClass());
}
@Test
public void doNotCreateSecureRandomDirectlyPositiveCases() {
compilationHelper.addSourceFile("DoNotCreateSecureRandomDirectlyPositiveCases.java").doTest();
}
@Test
public void doNotCreateSecureRandomDirectlyNegativeCases() {
compilationHelper.addSourceFile("DoNotCreateSecureRandomDirectlyNegativeCases.java").doTest();
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class DoNotInvokeMessageDigestDirectlyTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(DoNotInvokeMessageDigestDirectly.class, getClass());
}
@Test
public void doNotInvokeMessageDigestDirectlyPositiveCases() {
compilationHelper.addSourceFile("DoNotInvokeMessageDigestDirectlyPositiveCases.java").doTest();
}
@Test
public void doNotInvokeMessageDigestDirectlyNegativeCases() {
compilationHelper.addSourceFile("DoNotInvokeMessageDigestDirectlyNegativeCases.java").doTest();
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class DoNotReturnNullOptionalsTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(DoNotReturnNullOptionals.class, getClass());
}
@Test
public void doNotReturnNullPositiveCases() {
compilationHelper.addSourceFile("DoNotReturnNullOptionalsPositiveCases.java").doTest();
}
@Test
public void doNotReturnNullNegativeCases() {
compilationHelper.addSourceFile("DoNotReturnNullOptionalsNegativeCases.java").doTest();
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class ExperimentalCliOptionMustBeCorrectlyDisplayedTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(
ExperimentalCliOptionMustBeCorrectlyDisplayed.class, getClass());
}
@Test
public void experimentalCliOptionMustBeHiddenPositiveCases() {
compilationHelper
.addSourceFile("ExperimentalCliOptionMustBeCorrectlyDisplayedPositiveCases.java")
.doTest();
}
@Test
public void experimentalCliOptionMustBeHiddenNegativeCases() {
compilationHelper
.addSourceFile("ExperimentalCliOptionMustBeCorrectlyDisplayedNegativeCases.java")
.doTest();
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class MethodInputParametersMustBeFinalTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(MethodInputParametersMustBeFinal.class, getClass());
}
@Test
public void methodInputParametersMustBeFinalPositiveCases() {
compilationHelper.addSourceFile("MethodInputParametersMustBeFinalPositiveCases.java").doTest();
}
@Test
public void methodInputParametersMustBeFinalInterfacePositiveCases() {
compilationHelper
.addSourceFile("MethodInputParametersMustBeFinalInterfacePositiveCases.java")
.doTest();
}
@Test
public void methodInputParametersMustBeFinalNegativeCases() {
compilationHelper.addSourceFile("MethodInputParametersMustBeFinalNegativeCases.java").doTest();
}
@Test
public void methodInputParametersMustBeFinalInterfaceNegativeCases() {
compilationHelper
.addSourceFile("MethodInputParametersMustBeFinalInterfaceNegativeCases.java")
.doTest();
}
}

View File

@@ -1,40 +0,0 @@
/*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class PreferCommonAnnotationsTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(PreferCommonAnnotations.class, getClass());
}
@Test
void preferCommonAnnotationsPositiveCases() {
compilationHelper.addSourceFile("PreferCommonAnnotationsPositiveCases.java").doTest();
}
@Test
void preferCommonAnnotationsNegativeCases() {
compilationHelper.addSourceFile("PreferCommonAnnotationsNegativeCases.java").doTest();
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class PrivateStaticFinalLoggersTest {
private CompilationTestHelper compilationHelper;
@BeforeEach
public void setup() {
compilationHelper =
CompilationTestHelper.newInstance(PrivateStaticFinalLoggers.class, getClass());
}
@Test
public void privateStaticFinalLoggersPositiveCases() {
compilationHelper.addSourceFile("PrivateStaticFinalLoggersPositiveCases.java").doTest();
}
@Test
public void privateStaticFinalLoggersNegativeCases() {
compilationHelper.addSourceFile("PrivateStaticFinalLoggersNegativeCases.java").doTest();
}
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import com.google.common.base.Objects;
public class BannedMethodPositiveCases {
public void callsObjectsEquals() throws Exception {
// BUG: Diagnostic contains: Do not use com.google.common.base.Objects methods, use
// java.util.Objects methods instead.
Objects.equal("1", "1");
}
public void callsObjectsHashCode() throws Exception {
// BUG: Diagnostic contains: Do not use com.google.common.base.Objects methods, use
// java.util.Objects methods instead.
Objects.hashCode("1", "1");
}
public void usesJUnitAssertions() throws Exception {
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertEquals(1, 1);
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertNotEquals(1, 2);
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertTrue(true);
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertFalse(false);
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertNull(null);
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertNotNull("foo");
// BUG: Diagnostic contains: Do not use junit assertions. Use assertj assertions instead.
org.junit.Assert.assertArrayEquals(new int[] {1}, new int[] {1});
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import java.security.Provider;
import java.security.SecureRandom;
public class DoNotCreateSecureRandomDirectlyNegativeCases {
public void callsNonJRESecureRandomGetInstance() throws Exception {
TestSecureRandom.getInstance("");
TestSecureRandom.getInstance("", "");
TestSecureRandom.getInstance("", new Provider("", 0, "") {});
}
public void invokesNonJRESecureRandomConstructor() throws Exception {
new TestSecureRandom();
}
private class TestSecureRandom extends SecureRandom {}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import java.security.Provider;
import java.security.SecureRandom;
public class DoNotCreateSecureRandomDirectlyPositiveCases {
public void callsSecureRandomGetInstance() throws Exception {
// BUG: Diagnostic contains: Do not create SecureRandom directly.
SecureRandom.getInstance("");
// BUG: Diagnostic contains: Do not create SecureRandom directly.
SecureRandom.getInstance("", "");
// BUG: Diagnostic contains: Do not create SecureRandom directly.
SecureRandom.getInstance("", new Provider("", 0, "") {});
}
public void invokesSecureRandomConstructor() throws Exception {
// BUG: Diagnostic contains: Do not create SecureRandom directly.
new SecureRandom();
// BUG: Diagnostic contains: Do not create SecureRandom directly.
new SecureRandom(new byte[] {});
}
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class DoNotInvokeMessageDigestDirectlyPositiveCases {
public void callsMessageDigestGetInstance() throws NoSuchAlgorithmException {
// BUG: Diagnostic contains: Do not invoke MessageDigest.getInstance directly.
MessageDigest dig = MessageDigest.getInstance("SHA-256");
}
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import java.util.Optional;
import javax.annotation.Nullable;
public class DoNotReturnNullOptionalsNegativeCases {
public interface allInterfacesAreValid {
public Optional<Long> ExpectToBeOverridden();
}
public DoNotReturnNullOptionalsNegativeCases() {}
public Optional<Long> doesNotReturnNull() {
return Optional.of(3L);
}
@Nullable
public Optional<Long> returnsNullButAnnotatedWithNullable() {
return Optional.empty();
}
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import java.util.Optional;
public class DoNotReturnNullOptionalsPositiveCases {
// BUG: Diagnostic contains: Do not return null optionals.
public Optional<Long> returnsNull() {
return null;
}
// BUG: Diagnostic contains: Do not return null optionals.
public Optional<Long> sometimesReturnsNull(boolean random) {
if (random) {
return null;
}
return Optional.of(2L);
}
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import picocli.CommandLine;
public class ExperimentalCliOptionMustBeCorrectlyDisplayedNegativeCases {
@CommandLine.Option(
hidden = true,
names = {"--Xexperimental"})
private String experimental = "";
@CommandLine.Option(
hidden = false,
names = {"--notExperimental"})
private String notExperimental = "";
@CommandLine.Option(names = {"--notExperimental2"})
private String notExperimental2 = "";
private class AnotherClass {
@CommandLine.Option(names = {"--notExperimentalInAnotherClass"})
private String notExperimentalInAnotherClass = "";
@CommandLine.Option(
hidden = true,
names = {"--XexperimentalInAnotherClass"})
private String experimentalInAnotherClass = "";
}
private class BesuCommand {
@CommandLine.Option(names = {"--notExperimentalInBesuCommandClass"})
private String notExperimentalInBesuCommandClass = "";
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import picocli.CommandLine;
public class ExperimentalCliOptionMustBeCorrectlyDisplayedPositiveCases {
// BUG: Diagnostic contains: Experimental options must be hidden and not present in the
// BesuCommand class.
@CommandLine.Option(
hidden = false,
names = {"--Xexperimental"})
private String experimental = "";
// BUG: Diagnostic contains: Experimental options must be hidden and not present in the
// BesuCommand class.
@CommandLine.Option(names = {"--Xexperimental2"})
private String experimental2 = "";
private class BesuCommand {
// BUG: Diagnostic contains: Experimental options must be hidden and not present in the
// BesuCommand class.
@CommandLine.Option(names = {"--XexperimentalInBesuCommandClass"})
private String experimentalInBesuCommandClass = "";
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import java.util.Observable;
import java.util.Observer;
public interface MethodInputParametersMustBeFinalInterfaceNegativeCases {
void parameterCannotBeFinal(int value);
default void concreteMethod(final long value) {}
static void anotherConcreteMethod(final double value) {}
static Observer annonymousClass() {
return new Observer() {
@Override
public void update(final Observable o, final Object arg) {}
};
}
void methodAfterAnnonymousClass(int value);
enum Status {}
void methodAfterEnum(int value);
}

View File

@@ -1,24 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
public interface MethodInputParametersMustBeFinalInterfacePositiveCases {
// BUG: Diagnostic contains: Method input parameters must be final.
default void concreteMethod(int value) {}
// BUG: Diagnostic contains: Method input parameters must be final.
static void concreteStaticMethodsAreIncluded(int value) {}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import javax.annotation.processing.Generated;
public class MethodInputParametersMustBeFinalNegativeCases {
public void noInputParameters() {}
public void onlyPrimativeInputParameters(final long value) {}
public void onlyObjectInputParameters(final Object value) {}
public void mixedInputParameters(final Object value, final int anotherValue) {}
public interface allInterfacesAreValid {
void parameterCannotBeFinal(int value);
}
}
@Generated(
value = "test",
comments = "Every method is buggy, but ignored because the class has been tagged generated")
class MethodInputParametersMustBeFinalPositiveCasesBugGenerated1 {
public void primativeInputMethod(int value) {}
public void objectInputMethod(Object value) {}
public void mixedInputMethod(Object value, int anotherValue) {}
@Generated(
value = "test",
comments = "Every method is buggy, but ignored because the class has been tagged generated")
public abstract class abstractClassDefinition {
public void concreteMethodsAreIncluded(int value) {}
}
public void varArgsInputMethod(String... value) {}
}
@Generated(
value = "test",
comments = "Every method is buggy, but ignored because the class has been tagged generated")
class MethodInputParametersMustBeFinalPositiveCasesBugGenerated2 {
public void mixedInputMethodFirstFinal(final Object value, int anotherValue) {}
public void mixedInputMethodSecondFinal(Object value, final int anotherValue) {}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
public class MethodInputParametersMustBeFinalPositiveCases {
// BUG: Diagnostic contains: Method input parameters must be final.
public void primativeInputMethod(int value) {}
// BUG: Diagnostic contains: Method input parameters must be final.
public void objectInputMethod(Object value) {}
// BUG: Diagnostic contains: Method input parameters must be final.
public void mixedInputMethod(Object value, int anotherValue) {}
// BUG: Diagnostic contains: Method input parameters must be final.
public void mixedInputMethodFirstFinal(final Object value, int anotherValue) {}
// BUG: Diagnostic contains: Method input parameters must be final.
public void mixedInputMethodSecondFinal(Object value, final int anotherValue) {}
// BUG: Diagnostic contains: Method input parameters must be final.
public void varArgsInputMethod(String... value) {}
public abstract class abstractClassDefinition {
// BUG: Diagnostic contains: Method input parameters must be final.
public void concreteMethodsAreIncluded(int value) {}
}
}

View File

@@ -1,32 +0,0 @@
/*
* 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.errorpronechecks;
import javax.annotation.Nonnull;
public class PreferCommonAnnotationsNegativeCases {
@Nonnull
public String getFoo() {
return "Foo";
}
// Fully Qualified Name is the "escape hatch"
@org.jetbrains.annotations.NotNull
public String getBar() {
return "Bar";
}
}

View File

@@ -1,25 +0,0 @@
/*
* Copyright ConsenSys AG.
*
* 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.errorpronechecks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PrivateStaticFinalLoggersPositiveCases {
// BUG: Diagnostic contains: Logger classes should be private, static, and final.
private final Logger LOG = LoggerFactory.getLogger(PrivateStaticFinalLoggersPositiveCases.class);
}

View File

@@ -235,8 +235,7 @@ public class GraphQLHttpService {
private boolean hostIsInAllowlist(final String hostHeader) {
if (config.getHostsAllowlist().stream()
.anyMatch(
allowlistEntry -> allowlistEntry.toLowerCase().equals(hostHeader.toLowerCase()))) {
.anyMatch(allowlistEntry -> allowlistEntry.equalsIgnoreCase(hostHeader))) {
return true;
} else {
LOG.trace("Host not in allowlist: '{}'", hostHeader);

View File

@@ -330,7 +330,7 @@ public class Scalars {
if (input instanceof Number number) {
return number;
} else if (input instanceof String string) {
final String value = string.toLowerCase();
final String value = string.toLowerCase(Locale.ROOT);
if (value.startsWith("0x")) {
return Bytes.fromHexStringLenient(value).toLong();
} else {
@@ -352,7 +352,7 @@ public class Scalars {
if (input instanceof IntValue intValue) {
return intValue.getValue().longValue();
} else if (input instanceof StringValue stringValue) {
final String value = stringValue.getValue().toLowerCase();
final String value = stringValue.getValue().toLowerCase(Locale.ROOT);
if (value.startsWith("0x")) {
return Bytes.fromHexStringLenient(value).toLong();
} else {

View File

@@ -17,7 +17,7 @@ package org.hyperledger.besu.ethereum.api.graphql.internal.pojoadapter;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.trie.bonsai.BonsaiAccount;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiAccount;
import org.hyperledger.besu.evm.account.Account;
import org.hyperledger.besu.evm.account.AccountState;

View File

@@ -274,7 +274,7 @@ public class TransactionAdapter extends AdapterBase {
.map(
receipt -> {
final BytesValueRLPOutput rlpOutput = new BytesValueRLPOutput();
receipt.getReceipt().writeTo(rlpOutput);
receipt.getReceipt().writeToForNetwork(rlpOutput);
return rlpOutput.encoded();
});
}

View File

@@ -524,8 +524,7 @@ public class JsonRpcHttpService {
private boolean hostIsInAllowlist(final String hostHeader) {
if (config.getHostsAllowlist().stream()
.anyMatch(
allowlistEntry -> allowlistEntry.toLowerCase().equals(hostHeader.toLowerCase()))) {
.anyMatch(allowlistEntry -> allowlistEntry.equalsIgnoreCase(hostHeader))) {
return true;
} else {
LOG.trace("Host not in allowlist: '{}'", hostHeader);

View File

@@ -55,7 +55,7 @@ public class DebugGetRawReceipts extends AbstractBlockParameterOrBlockHashMethod
private String[] toRLP(final List<TransactionReceipt> receipts) {
return receipts.stream()
.map(receipt -> RLP.encode(receipt::writeTo).toHexString())
.map(receipt -> RLP.encode(receipt::writeToForNetwork).toHexString())
.toArray(String[]::new);
}
}

View File

@@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
@@ -38,7 +39,7 @@ public class BlockParameter {
@JsonCreator
public BlockParameter(final String value) {
final String normalizedValue = value.toLowerCase();
final String normalizedValue = value.toLowerCase(Locale.ROOT);
switch (normalizedValue) {
case "earliest":

View File

@@ -18,6 +18,7 @@ import org.hyperledger.besu.config.JsonUtil;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.BlockHeader;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalLong;
@@ -44,7 +45,7 @@ public class BlockParameterOrBlockHash {
@JsonCreator
public BlockParameterOrBlockHash(final Object value) throws JsonProcessingException {
if (value instanceof String) {
final String normalizedValue = String.valueOf(value).toLowerCase();
final String normalizedValue = String.valueOf(value).toLowerCase(Locale.ROOT);
if (Objects.equals(normalizedValue, "earliest")) {
type = BlockParameterType.EARLIEST;

View File

@@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.transaction.po
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
@@ -82,7 +83,7 @@ public class PendingTransactionsParams {
} else if (!map.isEmpty()) {
final Map.Entry<String, String> foundEntry = map.entrySet().stream().findFirst().get();
final Predicate predicate =
Predicate.fromValue(foundEntry.getKey().toUpperCase())
Predicate.fromValue(foundEntry.getKey().toUpperCase(Locale.ROOT))
.orElseThrow(
() ->
new InvalidJsonRpcParameters(

View File

@@ -126,7 +126,7 @@ public class TransactionCompleteResult implements TransactionResult {
this.v =
(transactionType == TransactionType.ACCESS_LIST
|| transactionType == TransactionType.EIP1559)
? this.yParity
? Quantity.create(transaction.getV())
: null;
}
this.value = Quantity.create(transaction.getValue());

View File

@@ -116,7 +116,7 @@ public class TransactionPendingResult implements TransactionResult {
this.v =
(transactionType == TransactionType.ACCESS_LIST
|| transactionType == TransactionType.EIP1559)
? this.yParity
? Quantity.create(transaction.getV())
: null;
}
this.value = Quantity.create(transaction.getValue());

View File

@@ -331,9 +331,7 @@ public class WebSocketService {
.map(
header ->
configuration.getHostsAllowlist().stream()
.anyMatch(
allowlistEntry ->
allowlistEntry.toLowerCase().equals(header.toLowerCase())))
.anyMatch(allowListEntry -> allowListEntry.equalsIgnoreCase(header)))
.orElse(false);
}
}

View File

@@ -73,7 +73,7 @@ public class PendingTransactionDetailResult implements JsonRpcResult {
this.v =
(transactionType == TransactionType.ACCESS_LIST
|| transactionType == TransactionType.EIP1559)
? this.yParity
? Quantity.create(tx.getV())
: null;
}
this.value = Quantity.create(tx.getValue());

View File

@@ -311,7 +311,7 @@ public class StateBackupService {
bodyWriter.writeBytes(bodyOutput.encoded().toArrayUnsafe());
final BytesValueRLPOutput receiptsOutput = new BytesValueRLPOutput();
receiptsOutput.writeList(receipts.get(), TransactionReceipt::writeToWithRevertReason);
receiptsOutput.writeList(receipts.get(), (r, rlpOut) -> r.writeToForStorage(rlpOut, false));
receiptsWriter.writeBytes(receiptsOutput.encoded().toArrayUnsafe());
backupStatus.storedBlock = blockNumber;

View File

@@ -159,7 +159,7 @@ public class TransactionLogBloomCacher {
return;
}
final long blockNumber = blockHeader.getNumber();
LOG.atDebug()
LOG.atTrace()
.setMessage("Caching logs bloom for block {}")
.addArgument(() -> "0x" + Long.toHexString(blockNumber))
.log();

View File

@@ -43,6 +43,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -1742,7 +1743,7 @@ public class JsonRpcHttpServiceTest extends JsonRpcHttpServiceTestBase {
assertThat(Long.decode(result.getString("timestamp"))).isEqualTo(header.getTimestamp());
assertThat(Long.decode(result.getString("number"))).isEqualTo(header.getNumber());
// Nonce is a data field and should represent 8 bytes exactly
final String nonceResult = result.getString("nonce").toLowerCase();
final String nonceResult = result.getString("nonce").toLowerCase(Locale.ROOT);
assertThat(nonceResult.length() == 18 && nonceResult.startsWith("0x")).isTrue();
assertThat(Long.parseUnsignedLong(nonceResult.substring(2), 16)).isEqualTo(header.getNonce());
assertThat(Hash.fromHexString(result.getString("hash"))).isEqualTo(header.getHash());

View File

@@ -63,7 +63,8 @@ public class NewBlockHeadersSubscriptionServiceTest {
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions());
new MainnetBlockHeaderFunctions(),
false);
private final Block genesisBlock = gen.genesisBlock();
private final MutableBlockchain blockchain =
DefaultBlockchain.createMutable(genesisBlock, blockchainStorage, new NoOpMetricsSystem(), 0);

View File

@@ -1,5 +1,5 @@
{
"request": "{transaction (hash : \"0x3ecd2ca6cf26c864d0ea5f038a58d4cd4a46a3e242fe92f446f392fdc232dd98\") { accessList { address storageKeys } maxFeePerGas maxPriorityFeePerGas nonce type status } } ",
"request": "{transaction (hash : \"0x3ecd2ca6cf26c864d0ea5f038a58d4cd4a46a3e242fe92f446f392fdc232dd98\") { accessList { address storageKeys } maxFeePerGas maxPriorityFeePerGas nonce type status yParity v} } ",
"response": {
"data": {
"transaction": {
@@ -15,7 +15,9 @@
"maxPriorityFeePerGas": "0x3b9aca00",
"nonce": "0x20",
"type": "0x2",
"status": "0x1"
"status": "0x1",
"yParity": "0x0",
"v": "0x25"
}
}
},

View File

@@ -58,7 +58,7 @@
"type": "0x2",
"value": "0x0",
"yParity": "0x0",
"v" : "0x0",
"v" : "0x25",
"r": "0x8abbfbd4c5f2a13a8d5ed394ac50bac7d678f83a23f645818492f76e8ee17ab3",
"s": "0x7bd38c6929235f775d68b45bd7dea7981264f9a265b6bea97b070e15be88389c"
}

View File

@@ -192,7 +192,7 @@ public class BlockTransactionSelector {
isTimeout.set(true);
}
LOG.warn(
"Interrupting transaction selection since it is taking more than the max configured time of "
"Interrupting the selection of transactions for block inclusion as it exceeds the maximum configured duration of "
+ blockTxsSelectionMaxTime
+ "ms",
e);

View File

@@ -167,7 +167,8 @@ public abstract class AbstractBlockTransactionSelectorTest {
new KeyValueStoragePrefixedKeyBlockchainStorage(
new InMemoryKeyValueStorage(),
new VariablesKeyValueStorage(new InMemoryKeyValueStorage()),
new MainnetBlockHeaderFunctions()),
new MainnetBlockHeaderFunctions(),
false),
new NoOpMetricsSystem(),
0);

View File

@@ -33,6 +33,7 @@ dependencies {
api 'org.web3j:core'
annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess'
annotationProcessor 'org.hyperledger.besu:besu-errorprone-checks'
implementation project(':config')
implementation project(':crypto:algorithms')

View File

@@ -495,10 +495,14 @@ public class Transaction
@Override
public BigInteger getV() {
if (transactionType != null && transactionType != TransactionType.FRONTIER) {
// EIP-2718 typed transaction, use yParity:
if (transactionType != null
&& transactionType != TransactionType.FRONTIER
&& transactionType != TransactionType.ACCESS_LIST
&& transactionType != TransactionType.EIP1559) {
// Newer transaction type lacks V, so return null
return null;
} else {
// Mandatory for legacy, optional for EIP-2930 and EIP-1559 TXes, prohibited for all others.
final BigInteger recId = BigInteger.valueOf(signature.getRecId());
return chainId
.map(bigInteger -> recId.add(REPLAY_PROTECTED_V_BASE).add(TWO.multiply(bigInteger)))

View File

@@ -30,6 +30,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import org.apache.tuweni.bytes.Bytes;
@@ -169,23 +170,26 @@ public class TransactionReceipt implements org.hyperledger.besu.plugin.data.Tran
*
* @param out The RLP output to write to
*/
public void writeTo(final RLPOutput out) {
writeTo(out, false);
public void writeToForNetwork(final RLPOutput out) {
writeTo(out, false, false);
}
public void writeToWithRevertReason(final RLPOutput out) {
writeTo(out, true);
public void writeToForStorage(final RLPOutput out, final boolean compacted) {
writeTo(out, true, compacted);
}
private void writeTo(final RLPOutput rlpOutput, final boolean withRevertReason) {
@VisibleForTesting
void writeTo(final RLPOutput rlpOutput, final boolean withRevertReason, final boolean compacted) {
if (transactionType.equals(TransactionType.FRONTIER)) {
writeToForReceiptTrie(rlpOutput, withRevertReason);
writeToForReceiptTrie(rlpOutput, withRevertReason, compacted);
} else {
rlpOutput.writeBytes(RLP.encode(out -> writeToForReceiptTrie(out, withRevertReason)));
rlpOutput.writeBytes(
RLP.encode(out -> writeToForReceiptTrie(out, withRevertReason, compacted)));
}
}
public void writeToForReceiptTrie(final RLPOutput rlpOutput, final boolean withRevertReason) {
public void writeToForReceiptTrie(
final RLPOutput rlpOutput, final boolean withRevertReason, final boolean compacted) {
if (!transactionType.equals(TransactionType.FRONTIER)) {
rlpOutput.writeIntScalar(transactionType.getSerializedType());
}
@@ -200,8 +204,10 @@ public class TransactionReceipt implements org.hyperledger.besu.plugin.data.Tran
rlpOutput.writeLongScalar(status);
}
rlpOutput.writeLongScalar(cumulativeGasUsed);
rlpOutput.writeBytes(bloomFilter);
rlpOutput.writeList(logs, Log::writeTo);
if (!compacted) {
rlpOutput.writeBytes(bloomFilter);
}
rlpOutput.writeList(logs, (log, logOutput) -> log.writeTo(logOutput, compacted));
if (withRevertReason && revertReason.isPresent()) {
rlpOutput.writeBytes(revertReason.get());
}
@@ -240,10 +246,21 @@ public class TransactionReceipt implements org.hyperledger.besu.plugin.data.Tran
// correct transaction receipt encoding to use.
final RLPInput firstElement = input.readAsRlp();
final long cumulativeGas = input.readLongScalar();
// The logs below will populate the bloom filter upon construction.
LogsBloomFilter bloomFilter = null;
final boolean hasLogs = !input.nextIsList() && input.nextSize() == LogsBloomFilter.BYTE_SIZE;
if (hasLogs) {
// The logs below will populate the bloom filter upon construction.
bloomFilter = LogsBloomFilter.readFrom(input);
}
// TODO consider validating that the logs and bloom filter match.
final LogsBloomFilter bloomFilter = LogsBloomFilter.readFrom(input);
final List<Log> logs = input.readList(Log::readFrom);
final boolean compacted = !hasLogs;
final List<Log> logs = input.readList(logInput -> Log.readFrom(logInput, compacted));
if (compacted) {
bloomFilter = LogsBloomFilter.builder().insertLogs(logs).build();
}
final Optional<Bytes> revertReason;
if (input.isEndOfCurrentList()) {
revertReason = Optional.empty();

View File

@@ -31,8 +31,8 @@ import org.hyperledger.besu.ethereum.core.Withdrawal;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.trie.MerkleTrieException;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState;
import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldStateUpdateAccumulator;
import org.hyperledger.besu.ethereum.vm.BlockHashLookup;
import org.hyperledger.besu.ethereum.vm.CachingBlockHashLookup;
import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator;

View File

@@ -118,7 +118,8 @@ public final class BodyValidation {
trie.put(
indexKey(i),
RLP.encode(
rlpOutput -> receipts.get(i).writeToForReceiptTrie(rlpOutput, false))));
rlpOutput ->
receipts.get(i).writeToForReceiptTrie(rlpOutput, false, false))));
return Hash.wrap(trie.getRootHash());
}

View File

@@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
import org.hyperledger.besu.evm.internal.EvmConfiguration;
import java.math.BigInteger;
import java.util.NavigableMap;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.TreeMap;
@@ -126,7 +127,7 @@ public class ProtocolScheduleBuilder {
validateForkOrdering();
final TreeMap<Long, BuilderMapEntry> builders = buildMilestoneMap(specFactory);
final NavigableMap<Long, BuilderMapEntry> builders = buildMilestoneMap(specFactory);
// At this stage, all milestones are flagged with correct modifier, but ProtocolSpecs must be
// inserted _AT_ the modifier block entry.
@@ -320,7 +321,7 @@ public class ProtocolScheduleBuilder {
return referenceForkBlock;
}
private TreeMap<Long, BuilderMapEntry> buildMilestoneMap(
private NavigableMap<Long, BuilderMapEntry> buildMilestoneMap(
final MainnetProtocolSpecFactory specFactory) {
return createMilestones(specFactory)
.flatMap(Optional::stream)

View File

@@ -168,16 +168,14 @@ public class PrivateTransactionReceipt {
if (obj == this) {
return true;
}
if (!(obj instanceof PrivateTransactionReceipt)) {
if (!(obj instanceof PrivateTransactionReceipt other)) {
return false;
}
final PrivateTransactionReceipt other = (PrivateTransactionReceipt) obj;
return logs.equals(other.getLogs())
&& status == other.status
&& output.equals(other.output)
&& revertReason.isPresent()
? revertReason.get().equals(other.revertReason.get())
: true;
return !logs.equals(other.getLogs())
|| status != other.status
|| !output.equals(other.output)
|| revertReason.isEmpty()
|| revertReason.get().equals(other.revertReason.get());
}
@Override

View File

@@ -33,7 +33,9 @@ public interface StorageProvider extends Closeable {
VariablesStorage createVariablesStorage();
BlockchainStorage createBlockchainStorage(
ProtocolSchedule protocolSchedule, VariablesStorage variablesStorage);
ProtocolSchedule protocolSchedule,
VariablesStorage variablesStorage,
DataStorageConfiguration storageConfiguration);
WorldStateKeyValueStorage createWorldStateStorage(
DataStorageConfiguration dataStorageConfiguration);

Some files were not shown because too many files have changed in this diff Show More