From 504c44fe43c7047f536b4ba58c3a2c5a2fb45a78 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 9 Jan 2023 16:07:18 -0700 Subject: [PATCH 1/2] Support Shanghai in Reference Tests Add support for Shanghai in reference tests * Add Shanghai and Cancun milestones * Add "withdrawals" and "withdrawalsRoot" to json objects * Migrate to schedule by block header. Signed-off-by: Danno Ferrin --- .../ethereum/core/BlockHeaderBuilder.java | 21 ++++++++++++ .../besu/evmtool/StateTestSubCommand.java | 6 ++-- .../BlockchainReferenceTestCaseSpec.java | 12 +++++-- .../ReferenceTestProtocolSchedules.java | 34 ++++++++++++++----- .../besu/ethereum/core/TransactionTest.java | 2 +- .../vm/BlockchainReferenceTestTools.java | 6 ++-- .../vm/GeneralStateReferenceTestTools.java | 3 +- 7 files changed, 65 insertions(+), 19 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java index d285b778845..1914dc24c1f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions; import org.hyperledger.besu.evm.log.LogsBloomFilter; import java.time.Instant; @@ -72,6 +73,26 @@ public static BlockHeaderBuilder create() { return new BlockHeaderBuilder(); } + public static BlockHeaderBuilder createDefault() { + return new BlockHeaderBuilder() + .parentHash(Hash.EMPTY) + .coinbase(Address.ZERO) + .difficulty(Difficulty.ONE) + .number(0) + .gasLimit(30_000_000) + .timestamp(0) + .ommersHash(Hash.EMPTY_LIST_HASH) + .stateRoot(Hash.EMPTY_TRIE_HASH) + .transactionsRoot(Hash.EMPTY) + .receiptsRoot(Hash.EMPTY) + .logsBloom(LogsBloomFilter.empty()) + .gasUsed(0) + .extraData(Bytes.EMPTY) + .mixHash(Hash.EMPTY) + .nonce(0) + .blockHeaderFunctions(new MainnetBlockHeaderFunctions()); + } + public static BlockHeaderBuilder fromHeader(final BlockHeader header) { return create() .parentHash(header.getParentHash()) diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java index 1fa3d854a1d..2ed207e9fee 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java @@ -24,8 +24,8 @@ import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; @@ -207,13 +207,13 @@ private void traceTestSpecs(final String test, final List builder = ImmutableMap.builder(); + final ImmutableMap.Builder builder = + ImmutableMap.builder(); builder.put("Frontier", createSchedule(new StubGenesisConfigOptions())); builder.put( "FrontierToHomesteadAt5", createSchedule(new StubGenesisConfigOptions().homesteadBlock(5))); @@ -73,21 +77,23 @@ public static ReferenceTestProtocolSchedules create() { builder.put( "Merge", createSchedule(new StubGenesisConfigOptions().mergeNetSplitBlock(0).baseFeePerGas(0x0a))); - builder.put("Shanghai", createSchedule(new StubGenesisConfigOptions().shanghaiTime(0))); - builder.put("Cancun", createSchedule(new StubGenesisConfigOptions().cancunTime(0))); - builder.put("FutureEips", createSchedule(new StubGenesisConfigOptions().futureEipsTime(0))); builder.put( - "ExperimentalEips", createSchedule(new StubGenesisConfigOptions().experimentalEipsTime(0))); + "Shanghai", + createTimestampSchedule( + new StubGenesisConfigOptions().shanghaiTime(0).baseFeePerGas(0x0a))); + builder.put( + "Cancun", + createTimestampSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))); return new ReferenceTestProtocolSchedules(builder.build()); } - private final Map schedules; + private final Map schedules; - private ReferenceTestProtocolSchedules(final Map schedules) { + private ReferenceTestProtocolSchedules(final Map schedules) { this.schedules = schedules; } - public ProtocolSchedule getByName(final String name) { + public HeaderBasedProtocolSchedule getByName(final String name) { return schedules.get(name); } @@ -103,6 +109,18 @@ private static ProtocolSchedule createSchedule(final GenesisConfigOptions option .createProtocolSchedule(); } + private static TimestampSchedule createTimestampSchedule(final GenesisConfigOptions options) { + return new TimestampScheduleBuilder( + options, + CHAIN_ID, + ProtocolSpecAdapters.create(0, Function.identity()), + PrivacyParameters.DEFAULT, + false, + options.isQuorum(), + EvmConfiguration.DEFAULT) + .createTimestampSchedule(); + } + public static boolean shouldClearEmptyAccounts(final String fork) { return !SPECS_PRIOR_TO_DELETING_EMPTY_ACCOUNTS.contains(fork); } diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java index 9ee175c160b..ec7f4fac8f8 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/core/TransactionTest.java @@ -53,7 +53,7 @@ public class TransactionTest { private static MainnetTransactionValidator transactionValidator(final String name) { return REFERENCE_TEST_PROTOCOL_SCHEDULES .getByName(name) - .getByBlockNumber(0) + .getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader()) .getTransactionValidator(); } diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java index d500aa122d0..8ca4556e697 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/BlockchainReferenceTestTools.java @@ -23,8 +23,8 @@ import org.hyperledger.besu.ethereum.core.BlockImporter; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.mainnet.BlockImportResult; +import org.hyperledger.besu.ethereum.mainnet.HeaderBasedProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.HeaderValidationMode; -import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.referencetests.BlockchainReferenceTestCaseSpec; import org.hyperledger.besu.ethereum.referencetests.ReferenceTestProtocolSchedules; @@ -103,7 +103,7 @@ public static void executeTest(final BlockchainReferenceTestCaseSpec spec) { .get(); assertThat(worldState.rootHash()).isEqualTo(genesisBlockHeader.getStateRoot()); - final ProtocolSchedule schedule = + final HeaderBasedProtocolSchedule schedule = REFERENCE_TEST_PROTOCOL_SCHEDULES.getByName(spec.getNetwork()); final MutableBlockchain blockchain = spec.getBlockchain(); @@ -118,7 +118,7 @@ public static void executeTest(final BlockchainReferenceTestCaseSpec spec) { try { final Block block = candidateBlock.getBlock(); - final ProtocolSpec protocolSpec = schedule.getByBlockNumber(block.getHeader().getNumber()); + final ProtocolSpec protocolSpec = schedule.getByBlockHeader(block.getHeader()); final BlockImporter blockImporter = protocolSpec.getBlockImporter(); final HeaderValidationMode validationMode = "NoProof".equalsIgnoreCase(spec.getSealEngine()) diff --git a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java index c134f3f0d8b..444bce72165 100644 --- a/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java +++ b/ethereum/referencetests/src/reference-test/java/org/hyperledger/besu/ethereum/vm/GeneralStateReferenceTestTools.java @@ -18,6 +18,7 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.BlockHeaderBuilder; import org.hyperledger.besu.ethereum.core.MutableWorldState; import org.hyperledger.besu.ethereum.core.Transaction; import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; @@ -50,7 +51,7 @@ public class GeneralStateReferenceTestTools { private static MainnetTransactionProcessor transactionProcessor(final String name) { return REFERENCE_TEST_PROTOCOL_SCHEDULES .getByName(name) - .getByBlockNumber(0) + .getByBlockHeader(BlockHeaderBuilder.createDefault().buildBlockHeader()) .getTransactionProcessor(); } From 1139d4f53962883f3fb17840038c57c93edd2bcf Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 9 Jan 2023 16:40:36 -0700 Subject: [PATCH 2/2] Add pending withdrawal code to test case spec Signed-off-by: Danno Ferrin --- .../BlockchainReferenceTestCaseSpec.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java index 48671babf4d..bdb6881b594 100644 --- a/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java +++ b/ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/BlockchainReferenceTestCaseSpec.java @@ -157,9 +157,8 @@ public ReferenceTestBlockHeader( @JsonProperty("baseFeePerGas") final String baseFee, @JsonProperty("mixHash") final String mixHash, @JsonProperty("nonce") final String nonce, - @JsonProperty("hash") final String hash, - @JsonProperty("withdrawalsRoot") final Object withdrawalsRoot) { - // TODO handle withdrawalsRoot + @JsonProperty("withdrawalsRoot") final String withdrawalsRoot, + @JsonProperty("hash") final String hash) { super( Hash.fromHexString(parentHash), // parentHash Hash.fromHexString(uncleHash), // ommersHash @@ -177,6 +176,7 @@ public ReferenceTestBlockHeader( baseFee != null ? Wei.fromHexString(baseFee) : null, // baseFee Hash.fromHexString(mixHash), // mixHash Bytes.fromHexStringLenient(nonce).toLong(), + // withdrawalsRoot == null ? Hash.EMPTY : Hash.fromHexString(withdrawalsRoot), new BlockHeaderFunctions() { @Override public Hash hash(final BlockHeader header) { @@ -257,6 +257,10 @@ public Block getBlock() { new BlockBody( input.readList(Transaction::readFrom), input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions))); + // input.readList(inputData -> BlockHeader.readFrom(inputData, blockHeaderFunctions), + // input.isEndOfCurrentList() + // ? Optional.empty() + // : Optional.of(input.readList(Withdrawal::readFrom)))); return new Block(header, body); } }