mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-09 22:07:59 -05:00
Update evmtool graalvm build (#5639)
* add new class to reflection config * move CLI output to be system-err oriented * make logger in evmtool nop * exclude some problematic jars from compilation - mixed versions of bouncy castle - netty initializations of log4j * Standardize JSON ObjectMapper Construction * Add some manual mappings * Directly instantiate crypto algorithms where appropriate Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
### Breaking Changes
|
||||
|
||||
### Additions and Improvements
|
||||
- EvmTool now executes the `execution-spec-tests` via the `t8n` and `b11r`. See the [README](ethereum/evmtool/README.md) in EvmTool for more instructions.
|
||||
|
||||
### Bug Fixes
|
||||
- Use the node's configuration to determine if DNS enode URLs are allowed in calls to `admin_addPeer` and `admin_removePeer` [#5584](https://github.com/hyperledger/besu/pull/5584)
|
||||
|
||||
@@ -1021,7 +1021,6 @@ tasks.register("verifyDistributions") {
|
||||
|
||||
dependencies {
|
||||
implementation project(':besu')
|
||||
implementation project(':ethereum:evmtool')
|
||||
errorprone 'com.google.errorprone:error_prone_core'
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
*/
|
||||
package org.hyperledger.besu.crypto;
|
||||
|
||||
import static org.hyperledger.besu.crypto.MessageDigestFactory.BLAKE2BF_ALG;
|
||||
import static org.hyperledger.besu.crypto.MessageDigestFactory.KECCAK256_ALG;
|
||||
import static org.hyperledger.besu.crypto.MessageDigestFactory.RIPEMD160_ALG;
|
||||
import static org.hyperledger.besu.crypto.MessageDigestFactory.SHA256_ALG;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.function.Supplier;
|
||||
@@ -26,13 +31,6 @@ import org.apache.tuweni.bytes.Bytes32;
|
||||
public abstract class Hash {
|
||||
private Hash() {}
|
||||
|
||||
/** The constant KECCAK256_ALG. */
|
||||
public static final String KECCAK256_ALG = "KECCAK-256";
|
||||
|
||||
private static final String SHA256_ALG = "SHA-256";
|
||||
private static final String RIPEMD160_ALG = "RIPEMD160";
|
||||
private static final String BLAKE2BF_ALG = "BLAKE2BF";
|
||||
|
||||
private static final Supplier<MessageDigest> KECCAK256_SUPPLIER =
|
||||
Suppliers.memoize(() -> messageDigest(KECCAK256_ALG));
|
||||
private static final Supplier<MessageDigest> SHA256_SUPPLIER =
|
||||
|
||||
@@ -18,11 +18,25 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Security;
|
||||
|
||||
import org.bouncycastle.jcajce.provider.digest.Keccak;
|
||||
import org.bouncycastle.jcajce.provider.digest.RIPEMD160;
|
||||
import org.bouncycastle.jcajce.provider.digest.SHA256;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
/** The Message digest factory. */
|
||||
public class MessageDigestFactory {
|
||||
|
||||
private MessageDigestFactory() {}
|
||||
|
||||
/** Keccak-256 */
|
||||
public static final String KECCAK256_ALG = "KECCAK-256";
|
||||
/** SHA-256 */
|
||||
public static final String SHA256_ALG = "SHA-256";
|
||||
/** RipeMD-160 */
|
||||
public static final String RIPEMD160_ALG = "RIPEMD160";
|
||||
/** Blake2b F Function */
|
||||
public static final String BLAKE2BF_ALG = "BLAKE2BF";
|
||||
|
||||
static {
|
||||
Security.addProvider(new BesuProvider());
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
@@ -37,6 +51,12 @@ public class MessageDigestFactory {
|
||||
*/
|
||||
@SuppressWarnings("DoNotInvokeMessageDigestDirectly")
|
||||
public static MessageDigest create(final String algorithm) throws NoSuchAlgorithmException {
|
||||
return MessageDigest.getInstance(algorithm);
|
||||
return switch (algorithm) {
|
||||
case KECCAK256_ALG -> new Keccak.Digest256();
|
||||
case SHA256_ALG -> new SHA256.Digest();
|
||||
case RIPEMD160_ALG -> new RIPEMD160.Digest();
|
||||
case BLAKE2BF_ALG -> new Blake2bfMessageDigest();
|
||||
default -> MessageDigest.getInstance(algorithm);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ import com.google.common.collect.Lists;
|
||||
|
||||
public class TlsHelpers {
|
||||
|
||||
private TlsHelpers() {}
|
||||
|
||||
private static KeyStore loadP12KeyStore(final File pkcsFile, final String password)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, CertificateException {
|
||||
final KeyStore store = KeyStore.getInstance("pkcs12");
|
||||
@@ -82,7 +84,7 @@ public class TlsHelpers {
|
||||
|
||||
private static String generateFingerprint(final X509Certificate cert)
|
||||
throws NoSuchAlgorithmException, CertificateEncodingException {
|
||||
final MessageDigest md = MessageDigestFactory.create("SHA-256");
|
||||
final MessageDigest md = MessageDigestFactory.create(MessageDigestFactory.SHA256_ALG);
|
||||
md.update(cert.getEncoded());
|
||||
final byte[] digest = md.digest();
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
package org.hyperledger.besu.ethereum.mainnet;
|
||||
|
||||
import static org.hyperledger.besu.crypto.MessageDigestFactory.KECCAK256_ALG;
|
||||
import static org.hyperledger.besu.ethereum.mainnet.EthHash.EPOCH_LENGTH;
|
||||
|
||||
import org.hyperledger.besu.crypto.Hash;
|
||||
import org.hyperledger.besu.crypto.MessageDigestFactory;
|
||||
|
||||
import java.security.DigestException;
|
||||
@@ -25,11 +25,13 @@ import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class DirectAcyclicGraphSeed {
|
||||
|
||||
private DirectAcyclicGraphSeed() {}
|
||||
|
||||
public static final ThreadLocal<MessageDigest> KECCAK_256 =
|
||||
ThreadLocal.withInitial(
|
||||
() -> {
|
||||
try {
|
||||
return MessageDigestFactory.create(Hash.KECCAK256_ALG);
|
||||
return MessageDigestFactory.create(KECCAK256_ALG);
|
||||
} catch (final NoSuchAlgorithmException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
127
ethereum/evmtool/README.md
Normal file
127
ethereum/evmtool/README.md
Normal file
@@ -0,0 +1,127 @@
|
||||
EVM Tool
|
||||
========
|
||||
|
||||
EVM Tool is a stand alone EVM executor and test execution tool. The
|
||||
principal purpose of the tool is for testing and validation of the EVM
|
||||
and enclosing data structures.
|
||||
|
||||
Using EVM Tool in execution-specification-tests
|
||||
-----------------------------------------------
|
||||
|
||||
To use EVM Tool in Execution Spec tests it is recommended that you use
|
||||
the GraalVM build, as the framework incurs significant startup penalties
|
||||
for each invocation when run via the Java runtime.
|
||||
|
||||
### Building Execution Tests on macOS
|
||||
|
||||
Current as of 24 Jun 2023.
|
||||
|
||||
MacOS users will typically encounter two problems,one relating to the
|
||||
version of Python used and one relating to zsh.
|
||||
|
||||
Homebrew will only install the most recent version of Python
|
||||
as `python3`, and that is 3.11. The execution tests require 3.10. The
|
||||
solution is to use a 3.10 version of python to set up the virtual
|
||||
environment.
|
||||
|
||||
```zsh
|
||||
python3.10 -m venv ./venv/
|
||||
```
|
||||
|
||||
Zsh requires braces to be escaped in the command line, so the step to
|
||||
install python packages needs to escape the brackets
|
||||
|
||||
```zsh
|
||||
pip install -e .\[docs,lint,test\]
|
||||
```
|
||||
|
||||
An all-in-one script, including homebrew, would look like
|
||||
|
||||
```zsh
|
||||
brew install ethereum solidity
|
||||
git clone https://github.com/ethereum/execution-spec-tests
|
||||
cd execution-spec-tests
|
||||
python3 -m venv ./venv/
|
||||
source ./venv/bin/activate
|
||||
pip install -e .[docs,lint,test]
|
||||
```
|
||||
|
||||
### Building EvmTool with GraalVM on macOS
|
||||
|
||||
First you need a GraalVM JDK installed, if not already installed.
|
||||
|
||||
It is recommended you install [SDKMAN](https://sdkman.io/install) to
|
||||
manage the graalVM install, homebrew has issues with native attributes
|
||||
and code signing.
|
||||
|
||||
```zsh
|
||||
sdk install java 22.3.r17-grl
|
||||
sdk use java 22.3.r17-grl
|
||||
```
|
||||
|
||||
You can also manually install GraalVM from
|
||||
the [GraalVM website](https://www.graalvm.org/downloads)..
|
||||
|
||||
Once GraalVM is installed you use the `nativeCompile` target.
|
||||
|
||||
```zsh
|
||||
./gradlew nativeCompile
|
||||
```
|
||||
|
||||
The resulting binary
|
||||
is `./ethereum/evmtool/build/native/nativeCompile/evmtool`
|
||||
|
||||
If the testing repository and besu are installed in the same parent
|
||||
directory, the command to run the execution tests is
|
||||
|
||||
```zsh
|
||||
fill -v tests --evm-bin ../besu/ethereum/evmtool/build/install/evmtool/bin/evm
|
||||
```
|
||||
|
||||
Assuming homebrew and SDKMan are both installed, the complete script is
|
||||
|
||||
```zsh
|
||||
sdk install java 22.3.r17-grl
|
||||
sdk use java 22.3.r17-grl
|
||||
git clone https://github.com/hyperledger/besu
|
||||
cd besu
|
||||
./gradlew nativeCompile
|
||||
cd ..
|
||||
|
||||
brew install ethereum solidity
|
||||
git clone https://github.com/ethereum/execution-spec-tests
|
||||
cd execution-spec-tests
|
||||
python3 -m venv ./venv/
|
||||
source ./venv/bin/activate
|
||||
pip install -e .[docs,lint,test]
|
||||
|
||||
fill -v tests --evm-bin ../besu/ethereum/evmtool/build/install/evmtool/bin/evm
|
||||
```
|
||||
|
||||
If you don't want to use the GraalVM tool the binary that is compatible
|
||||
is generated by the `ethereum:evmtool:installdist` target and is located
|
||||
at `./ethereum/evmtool/build/install/evmtool/bin/evm`
|
||||
|
||||
Why not GraalVM for everything?
|
||||
-------------------------------
|
||||
|
||||
Using GraalVM in execution-spec-tests results in over 20x performance
|
||||
increase in execution. It will be faster to build GraalVM from scratch
|
||||
and run the execution-spec-tests than to run just the Java version.
|
||||
|
||||
It is demonstrably faster to run the Java version for a node.
|
||||
All the test execution gains are the result of reduced startup
|
||||
penalties. Larger benchmarks will show that performance intensive EVM
|
||||
code will be slower in GraalVM than the Java version due to the adaptive
|
||||
compiler.
|
||||
|
||||
For contracts that execute 30 million gas in small operations it is
|
||||
often faster to run the Java EVMTool than the GraalVM EVMTool, including
|
||||
startup penalty. The execution tests focus on smaller VM tests that
|
||||
demonstrate specification conformance.
|
||||
|
||||
We would also need to reconsider some library choices. GraalVM does not
|
||||
work with Log4J, and we would have to ban that library across Besu and
|
||||
all dependents. Libraries such as Netty also have some problematic entry
|
||||
points that interact poorly with how SLF4J needs to initialize.
|
||||
|
||||
@@ -56,6 +56,8 @@ dependencies {
|
||||
implementation 'info.picocli:picocli'
|
||||
implementation 'io.vertx:vertx-core'
|
||||
|
||||
runtimeOnly 'org.slf4j:slf4j-nop'
|
||||
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler'
|
||||
annotationProcessor 'info.picocli:picocli-codegen'
|
||||
|
||||
@@ -65,9 +67,6 @@ dependencies {
|
||||
testImplementation 'org.mockito:mockito-core'
|
||||
|
||||
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
|
||||
|
||||
// No logging in grallvm EvmTool
|
||||
nativeImageClasspath 'org.slf4j:slf4j-nop'
|
||||
}
|
||||
|
||||
mainClassName = 'org.hyperledger.besu.evmtool.EvmTool'
|
||||
@@ -160,7 +159,7 @@ graalvmNative {
|
||||
|
||||
|
||||
// Netty drags in older versions of bouncy castle, exclude it so there are no conflicts
|
||||
excludeConfig.put("io.netty:netty-buffer:4.1.74.Final", [".*"])
|
||||
excludeConfig.put("io.netty:netty-buffer", [".*"])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,10 +168,12 @@ graalvmNative {
|
||||
configurations.nativeImageClasspath {
|
||||
// netty statically allocates some problematic classes
|
||||
exclude group: 'io.netty', module: 'netty-buffer'
|
||||
exclude group: 'io.netty', module: 'netty-common'
|
||||
exclude group: 'io.netty', module: 'netty-transport'
|
||||
|
||||
// keep log4j from sneaking in. GraalVM has an aleric reaction if it sees even one class
|
||||
exclude group: 'org.slf4j', module: 'log4j-over-slf4j:1.7.36'
|
||||
exclude group: "log4j", module: "log4j"
|
||||
exclude group: "org.apache.logging.log4j"
|
||||
exclude group: 'org.bouncycastle', module: 'bcprov-jdk18on'
|
||||
}
|
||||
|
||||
@@ -64,41 +64,57 @@
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.ethereum.referencetests.ReferenceTestEnv",
|
||||
"queryAllPublicConstructors" : true,
|
||||
"queryAllPublicMethods" : true,
|
||||
"queryAllPublicConstructors": true,
|
||||
"queryAllPublicMethods": true,
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicMethods": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.ethereum.referencetests.ReferenceTestEnv$EnvWithdrawal",
|
||||
"queryAllPublicConstructors" : true,
|
||||
"queryAllPublicMethods" : true,
|
||||
"queryAllPublicConstructors": true,
|
||||
"queryAllPublicMethods": true,
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicMethods": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState",
|
||||
"queryAllPublicConstructors" : true,
|
||||
"queryAllPublicMethods" : true,
|
||||
"queryAllPublicConstructors": true,
|
||||
"queryAllPublicMethods": true,
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicMethods": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.ethereum.referencetests.ReferenceTestWorldState$AccountMock",
|
||||
"queryAllPublicConstructors" : true,
|
||||
"queryAllPublicMethods" : true,
|
||||
"queryAllPublicConstructors": true,
|
||||
"queryAllPublicMethods": true,
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicMethods": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec$ReferenceTestBlockHeader",
|
||||
"queryAllPublicConstructors" : true,
|
||||
"queryAllPublicMethods" : true,
|
||||
"queryAllPublicConstructors": true,
|
||||
"queryAllPublicMethods": true,
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicMethods": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.evm.internal.ReturnStack$ReturnStackItem[]",
|
||||
"unsafeAllocated": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.evmtool.T8nSubCommand$RejectedTransaction",
|
||||
"queryAllPublicConstructors": true,
|
||||
"queryAllPublicMethods": true,
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicMethods": true
|
||||
},
|
||||
{
|
||||
"name": "org.hyperledger.besu.evm.log.Log",
|
||||
"allDeclaredConstructors": true,
|
||||
"allPublicConstructors": true,
|
||||
"allDeclaredMethods": true,
|
||||
"allPublicMethods": true,
|
||||
"allDeclaredFields": true,
|
||||
"allPublicFields": true
|
||||
}
|
||||
]
|
||||
@@ -23,7 +23,6 @@ import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder;
|
||||
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
|
||||
import org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec.ReferenceTestBlockHeader;
|
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
|
||||
import org.hyperledger.besu.util.LogConfigurator;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -37,17 +36,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.util.DefaultIndenter;
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.IParameterConsumer;
|
||||
@@ -64,8 +58,6 @@ import picocli.CommandLine.ParentCommand;
|
||||
mixinStandardHelpOptions = true,
|
||||
versionProvider = VersionProvider.class)
|
||||
public class B11rSubCommand implements Runnable {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(B11rSubCommand.class);
|
||||
|
||||
static final String COMMAND_NAME = "block-builder";
|
||||
static final String COMMAND_ALIAS = "b11r";
|
||||
private static final Path stdoutPath = Path.of("stdout");
|
||||
@@ -126,8 +118,6 @@ public class B11rSubCommand implements Runnable {
|
||||
description = "The account state after the transition")
|
||||
private final Path outBlock = Path.of("block.json");
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@ParentCommand private final EvmToolCommand parentCommand;
|
||||
|
||||
@Parameters(parameterConsumer = OnlyEmptyParams.class)
|
||||
@@ -162,14 +152,8 @@ public class B11rSubCommand implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LogConfigurator.setLevel("", "OFF");
|
||||
objectMapper.setDefaultPrettyPrinter(
|
||||
(new DefaultPrettyPrinter())
|
||||
.withSpacesInObjectEntries()
|
||||
.withObjectIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" "))
|
||||
.withArrayIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" ")));
|
||||
ObjectMapper objectMapper = JsonUtils.createObjectMapper();
|
||||
final ObjectReader b11rReader = objectMapper.reader();
|
||||
objectMapper.disable(Feature.AUTO_CLOSE_SOURCE);
|
||||
|
||||
ObjectNode config;
|
||||
try {
|
||||
@@ -216,11 +200,12 @@ public class B11rSubCommand implements Runnable {
|
||||
jpe.printStackTrace();
|
||||
return;
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Unable to read state file", e);
|
||||
System.err.println("Unable to read state file");
|
||||
e.printStackTrace(System.err);
|
||||
return;
|
||||
}
|
||||
|
||||
var testHeader = this.readHeader(config.get("header"));
|
||||
var testHeader = this.readHeader(config.get("header"), objectMapper);
|
||||
Bytes txsBytes = null;
|
||||
|
||||
if (config.has("txs")) {
|
||||
@@ -277,7 +262,8 @@ public class B11rSubCommand implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private ReferenceTestBlockHeader readHeader(final JsonNode jsonObject) {
|
||||
private ReferenceTestBlockHeader readHeader(
|
||||
final JsonNode jsonObject, final ObjectMapper objectMapper) {
|
||||
ObjectNode objectNode = (ObjectNode) jsonObject;
|
||||
maybeMoveField(objectNode, "sha3Uncles", "uncleHash");
|
||||
maybeMoveField(objectNode, "miner", "coinbase");
|
||||
|
||||
@@ -38,14 +38,11 @@ import javax.inject.Singleton;
|
||||
import com.google.common.base.Suppliers;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"CloseableProvides"})
|
||||
@Module(includes = GenesisFileModule.class)
|
||||
public class DataStoreModule {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DataStoreModule.class);
|
||||
private final Supplier<RocksDBKeyValueStorageFactory> rocksDBFactory =
|
||||
Suppliers.memoize(
|
||||
() ->
|
||||
@@ -131,7 +128,7 @@ public class DataStoreModule {
|
||||
case "rocksdb":
|
||||
return rocksDBFactory.get().create(segment, commonConfiguration, metricsSystem);
|
||||
default:
|
||||
LOG.error("Unknown key, continuing as though 'memory' was specified");
|
||||
System.err.println("Unknown key, continuing as though 'memory' was specified");
|
||||
// fall through
|
||||
case "memory":
|
||||
return new InMemoryKeyValueStorage();
|
||||
|
||||
@@ -43,7 +43,6 @@ import org.hyperledger.besu.evm.tracing.StandardJsonTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.metrics.MetricsSystemModule;
|
||||
import org.hyperledger.besu.util.LogConfigurator;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -70,8 +69,6 @@ import io.vertx.core.json.JsonObject;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.apache.tuweni.units.bigints.UInt256;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Option;
|
||||
@@ -98,8 +95,6 @@ import picocli.CommandLine.Option;
|
||||
})
|
||||
public class EvmToolCommand implements Runnable {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(EvmToolCommand.class);
|
||||
|
||||
@Option(
|
||||
names = {"--code"},
|
||||
paramLabel = "<code>",
|
||||
@@ -288,7 +283,6 @@ public class EvmToolCommand implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LogConfigurator.setLevel("", "OFF");
|
||||
try {
|
||||
final EvmToolComponent component =
|
||||
DaggerEvmToolComponent.builder()
|
||||
@@ -438,7 +432,8 @@ public class EvmToolCommand implements Runnable {
|
||||
} while (remainingIters-- > 0);
|
||||
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Unable to create Genesis module", e);
|
||||
System.err.println("Unable to create Genesis module");
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright Hyperledger Besu Contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hyperledger.besu.evmtool;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature;
|
||||
import com.fasterxml.jackson.core.util.DefaultIndenter;
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
|
||||
public class JsonUtils {
|
||||
|
||||
private JsonUtils() {}
|
||||
|
||||
/**
|
||||
* Create an object mapper with all the standard bells and whistles needed for evmtool
|
||||
*
|
||||
* @return a properly constructed ObjectMapper
|
||||
*/
|
||||
public static ObjectMapper createObjectMapper() {
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
// Attempting to get byte-perfect to go's standard json output
|
||||
objectMapper.setDefaultPrettyPrinter(
|
||||
(new DefaultPrettyPrinter())
|
||||
.withSpacesInObjectEntries()
|
||||
.withObjectIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" "))
|
||||
.withArrayIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" ")));
|
||||
|
||||
// When we stream stdin we cannot close the stream
|
||||
objectMapper.disable(Feature.AUTO_CLOSE_SOURCE);
|
||||
|
||||
// GraalVM has a hard time reflecting these classes for serialization
|
||||
SimpleModule serializers = new SimpleModule("Serializers");
|
||||
serializers.addSerializer(Address.class, ToStringSerializer.instance);
|
||||
serializers.addSerializer(Bytes.class, ToStringSerializer.instance);
|
||||
objectMapper.registerModule(serializers);
|
||||
|
||||
return objectMapper;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,6 @@ import org.hyperledger.besu.evm.tracing.StandardJsonTracer;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldState;
|
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater;
|
||||
import org.hyperledger.besu.evmtool.exception.UnsupportedForkException;
|
||||
import org.hyperledger.besu.util.LogConfigurator;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@@ -56,15 +55,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.Parameters;
|
||||
@@ -76,8 +72,6 @@ import picocli.CommandLine.ParentCommand;
|
||||
mixinStandardHelpOptions = true,
|
||||
versionProvider = VersionProvider.class)
|
||||
public class StateTestSubCommand implements Runnable {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StateTestSubCommand.class);
|
||||
|
||||
public static final String COMMAND_NAME = "state-test";
|
||||
|
||||
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"})
|
||||
@@ -92,8 +86,6 @@ public class StateTestSubCommand implements Runnable {
|
||||
@Parameters
|
||||
private final List<Path> stateTestFiles = new ArrayList<>();
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public StateTestSubCommand() {
|
||||
// PicoCLI requires this
|
||||
@@ -106,9 +98,8 @@ public class StateTestSubCommand implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LogConfigurator.setLevel("", "OFF");
|
||||
final ObjectMapper stateTestMapper = new ObjectMapper();
|
||||
stateTestMapper.disable(Feature.AUTO_CLOSE_SOURCE);
|
||||
final ObjectMapper stateTestMapper = JsonUtils.createObjectMapper();
|
||||
|
||||
final JavaType javaType =
|
||||
stateTestMapper
|
||||
.getTypeFactory()
|
||||
@@ -147,7 +138,8 @@ public class StateTestSubCommand implements Runnable {
|
||||
} catch (final JsonProcessingException jpe) {
|
||||
parentCommand.out.println("File content error: " + jpe);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Unable to read state file", e);
|
||||
System.err.println("Unable to read state file");
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +165,7 @@ public class StateTestSubCommand implements Runnable {
|
||||
parentCommand.showReturnData)
|
||||
: OperationTracer.NO_TRACING;
|
||||
|
||||
final ObjectMapper objectMapper = JsonUtils.createObjectMapper();
|
||||
for (final GeneralStateTestCaseEipSpec spec : specs) {
|
||||
|
||||
final BlockHeader blockHeader = spec.getBlockHeader();
|
||||
|
||||
@@ -40,7 +40,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.json.JsonArray;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.core.json.jackson.DatabindCodec;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import picocli.CommandLine;
|
||||
@@ -93,7 +92,7 @@ public class T8nServerSubCommand implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
ObjectMapper objectMapper = DatabindCodec.mapper();
|
||||
ObjectMapper objectMapper = JsonUtils.createObjectMapper();
|
||||
final T8nExecutor.T8nResult result =
|
||||
T8nExecutor.runTest(
|
||||
chainId,
|
||||
@@ -111,7 +110,9 @@ public class T8nServerSubCommand implements Runnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeTracer(final OperationTracer tracer) {}
|
||||
public void disposeTracer(final OperationTracer tracer) {
|
||||
// No output streams to dispose of
|
||||
}
|
||||
});
|
||||
|
||||
ObjectNode outputObject = objectMapper.createObjectNode();
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.hyperledger.besu.evm.AccessListEntry;
|
||||
import org.hyperledger.besu.evm.tracing.OperationTracer;
|
||||
import org.hyperledger.besu.evm.tracing.StandardJsonTracer;
|
||||
import org.hyperledger.besu.plugin.data.TransactionType;
|
||||
import org.hyperledger.besu.util.LogConfigurator;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
@@ -55,10 +54,7 @@ import java.util.Spliterators;
|
||||
import java.util.Stack;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.util.DefaultIndenter;
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
@@ -66,8 +62,6 @@ import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.apache.tuweni.bytes.Bytes32;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.IParameterConsumer;
|
||||
import picocli.CommandLine.Model.ArgSpec;
|
||||
@@ -84,7 +78,6 @@ import picocli.CommandLine.ParentCommand;
|
||||
mixinStandardHelpOptions = true,
|
||||
versionProvider = VersionProvider.class)
|
||||
public class T8nSubCommand implements Runnable {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(T8nSubCommand.class);
|
||||
|
||||
record RejectedTransaction(int index, String error) {}
|
||||
|
||||
@@ -189,15 +182,8 @@ public class T8nSubCommand implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LogConfigurator.setLevel("", "OFF");
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setDefaultPrettyPrinter(
|
||||
(new DefaultPrettyPrinter())
|
||||
.withSpacesInObjectEntries()
|
||||
.withObjectIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" "))
|
||||
.withArrayIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE.withIndent(" ")));
|
||||
final ObjectMapper objectMapper = JsonUtils.createObjectMapper();
|
||||
final ObjectReader t8nReader = objectMapper.reader();
|
||||
objectMapper.disable(Feature.AUTO_CLOSE_SOURCE);
|
||||
|
||||
MutableWorldState initialWorldState;
|
||||
ReferenceTestEnv referenceTestEnv;
|
||||
@@ -252,7 +238,8 @@ public class T8nSubCommand implements Runnable {
|
||||
jpe.printStackTrace();
|
||||
return;
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Unable to read state file", e);
|
||||
System.err.println("Unable to read state file");
|
||||
e.printStackTrace(System.err);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -349,7 +336,8 @@ public class T8nSubCommand implements Runnable {
|
||||
parentCommand.out.println(writer.writeValueAsString(outputObject));
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
LOG.error("Could not write results", ioe);
|
||||
System.err.println("Could not write results");
|
||||
ioe.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
"0xf90620f860800a8307a12094000000000000000000000000000000000000010080801ca0f73b923883495dc2174285c8fa4176de3d45accfb11cc8034ea1dd09831a4ddfa01c6bccbcd655b4022bcc27de4b9d5cee9ce999cdb8459b0afec4f5054ea02243f860010a8307a12094000000000000000000000000000000000000010180801ba0bffca3f433f61c957d822af37f2b49c57700ff338588d51ea82dc9f720c91d9da0168bb65cc72d586384383f8ceef3a6a60e54b7f4aaa978a6dad271ced54b2ebff860020a8307a12094000000000000000000000000000000000000010280801ba03d9f110bcf0c44be552d4d0ec8387b705604f7d3bb3794dcef4004c38963103ea013bda734f3b5987b8c855f6aab046754506266ff32352ba0898c4eba4acaec8bf860030a8307a12094000000000000000000000000000000000000010380801ba0ecb276d2486664ea779813e599b6f07b7b0df746626d7fdddf60ea425efcb324a0739841682e79a8302dc2e146dfd1eecbdc611d386d42287bcdd94a39bf536020f860040a8307a12094000000000000000000000000000000000000010480801ba002866b5c5fa5dbfa3d88b71a49b82a779c2d508cda631893176782dbcd7435aaa003c380a9af9bfdb3503abcfd5037d3c66f39bb7a19011a3291712d22292c5236f860050a8307a12094000000000000000000000000000000000000010580801ca0c70d2e000e503933d0f1a9a923dc647924811a912adf77692ff7d8f6808d5617a04ad82c92b980580a4a67e4c405e83d560a14201c3fd4b3a42d34dcc19336479af860060a8307a12094000000000000000000000000000000000000010680801ca07f2527f8cbe14e021d270dd214a1820355c7af128001889f57b7f9bba46a6c5da03033308de0d39b9d1b47d28f81df39ceaff330349298c65deb836efe8bce273ff860070a8307a12094000000000000000000000000000000000000010780801ba0ecb720a8764f8967b95dc66e961c6261fceb392c0e90461d7d66113d3c8bbd12a02655e28b751cc2e03a835aa817d884b540765dba12968bc53f53737b4234ee21f860080a8307a12094000000000000000000000000000000000000010880801ba095a2e27c0b296679141c0ad61be112f689b134c04d1773814ddae67fefb2dfbda02955f126d57d8b9777f47c520ffe4285890ca2dd1189e67b3407d6369997e7ecf860090a8307a12094000000000000000000000000000000000000010980801ca02468a120d0ee8c57caac354f56842a1db10813169a328f9f852279668b573907a03971f4c2e6bc0aa666812712719199df6fe37c0e1e122131cdb47d6c0c77b371f8600a0a8307a12094000000000000000000000000000000000000010a80801ba0a3a2018ab0bc2695b94bb85d710f4d07132a94f8c3e0f385824da5fee11899a5a00d2dfe430ea5aaff3de8bbb9339e7485474c8e4e34636f787124a7a91e4d6d6af8600b0a8307a12094000000000000000000000000000000000000010b80801ba0b91968fdb3aecea26094ec30649daa4de81a875bcb1a123e732b8f3f112ce232a02ef8cd85969d8bcef5f4ee1f5d20783b8d9b7466726c15ebf911565825187665f8600c0a8307a12094000000000000000000000000000000000000010c80801ca0dd27e75aa990793205805c22265b04be8299b208fad4f37a7f652ecf32b67390a05aa8cda18521548ff8f95e88f49f309d05cab32de28a0942b8a7a824c50df459f8600d0a8307a12094000000000000000000000000000000000000010d80801ba0fad07ce7139dd4e00266194e6a51c048f74eaba3c0a1b03ece378a810abfaa63a04fec880dafaa5382797b4f88b16138b1f0c4e084817072c77ff9bf17ddd4ac26f8600e0a8307a12094000000000000000000000000000000000000010e80801ca0208b22ab245221bdc5cae6586d2ef019a2c37be41166e04b8abe354c41a8f5b6a032d5d6ef07731cd1684531c775c1727ef6ba75de18cda96d998aaa0c1db0bd68f8600f0a8307a12094000000000000000000000000000000000000010f80801ba0055225ffd3d8b2d19c32aa68cb46e7b52c1d99844fb8b7a53b922ea1649e9c5ba06ae2a1e3b9712354b706d0f4da6ea76ed2f8f75277a51a14a3e0ccf25b85c626"
|
||||
@@ -21,6 +21,8 @@ import org.hyperledger.besu.ethereum.rlp.RLPOutput;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
@@ -42,7 +44,11 @@ public class Log {
|
||||
* @param data Data associated with this log.
|
||||
* @param topics Indexable topics associated with this log.
|
||||
*/
|
||||
public Log(final Address logger, final Bytes data, final List<LogTopic> topics) {
|
||||
@JsonCreator
|
||||
public Log(
|
||||
@JsonProperty("logger") final Address logger,
|
||||
@JsonProperty("data") final Bytes data,
|
||||
@JsonProperty("topics") final List<LogTopic> topics) {
|
||||
this.logger = logger;
|
||||
this.data = data;
|
||||
this.topics = ImmutableList.copyOf(topics);
|
||||
@@ -81,6 +87,7 @@ public class Log {
|
||||
*
|
||||
* @return the logger
|
||||
*/
|
||||
@JsonProperty("logger")
|
||||
public Address getLogger() {
|
||||
return logger;
|
||||
}
|
||||
@@ -90,6 +97,7 @@ public class Log {
|
||||
*
|
||||
* @return the data
|
||||
*/
|
||||
@JsonProperty("data")
|
||||
public Bytes getData() {
|
||||
return data;
|
||||
}
|
||||
@@ -99,16 +107,16 @@ public class Log {
|
||||
*
|
||||
* @return the topics
|
||||
*/
|
||||
@JsonProperty("topics")
|
||||
public List<LogTopic> getTopics() {
|
||||
return topics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (!(other instanceof Log)) return false;
|
||||
if (!(other instanceof Log that)) return false;
|
||||
|
||||
// Compare data
|
||||
final Log that = (Log) other;
|
||||
return this.data.equals(that.data)
|
||||
&& this.logger.equals(that.logger)
|
||||
&& this.topics.equals(that.topics);
|
||||
|
||||
Reference in New Issue
Block a user