From a851507cb3ced6daaedb7596662efda23ca0a3e9 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 25 Aug 2024 22:33:05 -0600 Subject: [PATCH] evmtool was not respecting the --genesis option (#7518) * EVMTool should respect --genesis option Update the code so that the genesis file option will be respected when set. Also, default --fork options should set a rational base fee. Signed-off-by: Danno Ferrin --------- Signed-off-by: Danno Ferrin --- CHANGELOG.md | 3 ++- .../besu/datatypes/HardforkId.java | 16 ++++++++++++ .../besu/ethereum/core/BlockHeader.java | 21 ++++++++------- .../besu/evmtool/EvmToolCommand.java | 26 ++++++++++++------- .../besu/evmtool/GenesisFileModule.java | 4 ++- .../evmtool/MainnetGenesisFileModule.java | 14 +++++----- 6 files changed, 54 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9fccf29c4..8c31d55fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ## [Unreleased] ### Fixed -- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383] +- **DebugMetrics**: Fixed a `ClassCastException` occurring in `DebugMetrics` when handling nested metric structures. Previously, `Double` values within these structures were incorrectly cast to `Map` objects, leading to errors. This update allows for proper handling of both direct values and nested structures at the same level. Issue# [#7383](https://github.com/hyperledger/besu/pull/7383) +- `evmtool` was not respecting the `--genesis` setting, resulting in unexpected trace results. [#7433](https://github.com/hyperledger/besu/pull/7433) ### Tests - Added a comprehensive test case to reproduce the bug and verify the fix for the `ClassCastException` in `DebugMetrics`. This ensures that complex, dynamically nested metric structures can be handled without errors. diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java index 73eaddb7ca..85ec84b4ad 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/HardforkId.java @@ -14,6 +14,9 @@ */ package org.hyperledger.besu.datatypes; +import java.util.Comparator; +import java.util.stream.Stream; + /** Description and metadata for a hard fork */ public interface HardforkId { @@ -112,6 +115,19 @@ public interface HardforkId { public String description() { return description; } + + /** + * The most recent finalized mainnet hardfork Besu supports. This will change across versions + * and will be updated after mainnet activations. + * + * @return the most recently activated mainnet spec. + */ + public static MainnetHardforkId mostRecent() { + return Stream.of(MainnetHardforkId.values()) + .filter(MainnetHardforkId::finalized) + .max(Comparator.naturalOrder()) + .orElseThrow(); + } } /** List of all Ethereum Classic hard forks. */ diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 46d2f0847a..42f99fafb6 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -158,22 +158,23 @@ public class BlockHeader extends SealableBlockHeader out.writeBytes(extraData); out.writeBytes(mixHashOrPrevRandao); out.writeLong(nonce); - if (baseFee != null) { + do { + if (baseFee == null) break; out.writeUInt256Scalar(baseFee); - } - if (withdrawalsRoot != null) { + + if (withdrawalsRoot == null) break; out.writeBytes(withdrawalsRoot); - } - if (excessBlobGas != null && blobGasUsed != null) { + + if (excessBlobGas == null || blobGasUsed == null) break; out.writeLongScalar(blobGasUsed); out.writeUInt64Scalar(excessBlobGas); - } - if (parentBeaconBlockRoot != null) { + + if (parentBeaconBlockRoot == null) break; out.writeBytes(parentBeaconBlockRoot); - } - if (requestsRoot != null) { + + if (requestsRoot == null) break; out.writeBytes(requestsRoot); - } + } while (false); out.endList(); } diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java index 06ee967620..f9d7c0db47 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java @@ -478,7 +478,14 @@ public class EvmToolCommand implements Runnable { .mixHash(Hash.ZERO) .nonce(0) .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) - .baseFee(component.getBlockchain().getChainHeadHeader().getBaseFee().orElse(null)) + .baseFee( + component + .getBlockchain() + .getChainHeadHeader() + .getBaseFee() + .or(() -> genesisFileModule.providesGenesisConfigFile().getBaseFeePerGas()) + .orElse( + protocolSpec.getFeeMarket().implementsBaseFee() ? Wei.of(0xa) : null)) .buildBlockHeader(); Address contractAddress = @@ -519,13 +526,12 @@ public class EvmToolCommand implements Runnable { lastTime = stopwatch.elapsed().toNanos(); } if (lastLoop) { - if (messageFrame.getExceptionalHaltReason().isPresent()) { - out.println(messageFrame.getExceptionalHaltReason().get()); - } - if (messageFrame.getRevertReason().isPresent()) { - out.println( - new String(messageFrame.getRevertReason().get().toArrayUnsafe(), UTF_8)); - } + messageFrame + .getExceptionalHaltReason() + .ifPresent(haltReason -> out.println(haltReason)); + messageFrame + .getRevertReason() + .ifPresent(bytes -> out.println(new String(bytes.toArrayUnsafe(), UTF_8))); } } } @@ -572,7 +578,7 @@ public class EvmToolCommand implements Runnable { out.println("{"); worldState .streamAccounts(Bytes32.ZERO, Integer.MAX_VALUE) - .sorted(Comparator.comparing(o -> o.getAddress().get().toHexString())) + .sorted(Comparator.comparing(o -> o.getAddress().orElse(Address.ZERO).toHexString())) .forEach( a -> { var account = worldState.get(a.getAddress().get()); @@ -585,7 +591,7 @@ public class EvmToolCommand implements Runnable { .map( e -> Map.entry( - e.getKey().get(), + e.getKey().orElse(UInt256.ZERO), account.getStorageValue(UInt256.fromBytes(e.getKey().get())))) .filter(e -> !e.getValue().isZero()) .sorted(Map.Entry.comparingByKey()) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java index 6eae387a64..8512b5537e 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/GenesisFileModule.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; +import org.hyperledger.besu.datatypes.HardforkId.MainnetHardforkId; import org.hyperledger.besu.ethereum.chain.GenesisState; import org.hyperledger.besu.ethereum.core.Block; import org.hyperledger.besu.ethereum.core.BlockHeaderFunctions; @@ -28,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; +import java.util.Locale; import java.util.Optional; import javax.inject.Named; import javax.inject.Singleton; @@ -116,7 +118,7 @@ public class GenesisFileModule { final JsonObject config = new JsonObject(); genesis.put("config", config); config.put("chainId", 1337); - config.put("londonBlock", 0); + config.put(MainnetHardforkId.mostRecent().toString().toLowerCase(Locale.ROOT) + "Time", 0); genesis.put("baseFeePerGas", "0x3b9aca00"); genesis.put("gasLimit", "0x2540be400"); genesis.put("difficulty", "0x0"); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java index e36668f47c..0ce7bf98f5 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java @@ -27,7 +27,6 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolScheduleBuilder; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecAdapters; -import org.hyperledger.besu.evm.EvmSpecVersion; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; @@ -71,13 +70,12 @@ class MainnetGenesisFileModule extends GenesisFileModule { } } - var schedules = createSchedules(configOptions.getChainId().orElse(BigInteger.valueOf(1337))); - var schedule = - schedules.get( - fork.orElse(EvmSpecVersion.defaultVersion().getName()) - .toLowerCase(Locale.getDefault())); - if (schedule != null) { - return schedule.get(); + if (fork.isPresent()) { + var schedules = createSchedules(configOptions.getChainId().orElse(BigInteger.valueOf(1337))); + var schedule = schedules.get(fork.get().toLowerCase(Locale.getDefault())); + if (schedule != null) { + return schedule.get(); + } } return MainnetProtocolSchedule.fromConfig(