From 98f98b52eef1c4f1d4c46aa08820bae6a2f08175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20L=C3=B3pez=20Leo=CC=81n?= Date: Fri, 25 Aug 2023 11:14:27 -0300 Subject: [PATCH] Add ECIP-1109: 'Spiral' network upgrade support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Diego López León --- CHANGELOG.md | 1 + .../besu/ForkIdsNetworkConfigTest.java | 5 ++- .../besu/config/GenesisConfigOptions.java | 9 ++++ .../besu/config/JsonGenesisConfigOptions.java | 9 +++- .../besu/config/StubGenesisConfigOptions.java | 18 ++++++++ config/src/main/resources/mordor.json | 1 + config/src/test/resources/all_forks.json | 3 +- .../internal/methods/AdminNodeInfoTest.java | 3 +- .../mainnet/ClassicProtocolSpecs.java | 43 +++++++++++++++++++ .../mainnet/MainnetProtocolSpecFactory.java | 10 +++++ .../mainnet/ProtocolScheduleBuilder.java | 4 +- 11 files changed, 100 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 787ff1d137d..c3c330c483c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,7 @@ https://hyperledger.jfrog.io/artifactory/besu-binaries/besu/23.7.3/besu-23.7.3.z - JSON output is now compact by default. This can be overridden by the new `--json-pretty-print-enabled` CLI option. [#5766](https://github.com/hyperledger/besu/pull/5766) - New `eth_getBlockReceipts` JSON-RPC method to retrieve all transaction receipts for a block in a single call [#5771](https://github.com/hyperledger/besu/pull/5771) - Add new methods to `OperationTracer` to capture contexts enter/exit [#5756](https://github.com/hyperledger/besu/pull/5756) +- Ethereum Classic Spiral network upgrade [#6078](https://github.com/hyperledger/besu/pull/6078) ### Bug Fixes - Make smart contract permissioning features work with london fork [#5727](https://github.com/hyperledger/besu/pull/5727) diff --git a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java index bfa55c261aa..5bc1c30bd61 100644 --- a/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java +++ b/besu/src/test/java/org/hyperledger/besu/ForkIdsNetworkConfigTest.java @@ -127,8 +127,9 @@ public static Collection parameters() { new ForkId(Bytes.ofUnsignedInt(0xf42f5539L), 2520000L), new ForkId(Bytes.ofUnsignedInt(0x66b5c286L), 3985893), new ForkId(Bytes.ofUnsignedInt(0x92b323e0L), 5520000L), - new ForkId(Bytes.ofUnsignedInt(0x8c9b1797L), 0L), - new ForkId(Bytes.ofUnsignedInt(0x8c9b1797L), 0L)) + new ForkId(Bytes.ofUnsignedInt(0x8c9b1797L), 9957000L), + new ForkId(Bytes.ofUnsignedInt(0x3a6b00d7L), 0L), + new ForkId(Bytes.ofUnsignedInt(0x3a6b00d7L), 0L)) }, new Object[] { NetworkName.CLASSIC, diff --git a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java index f60bffec96f..a315ce72449 100644 --- a/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java @@ -419,6 +419,15 @@ default boolean isConsensusMigration() { */ OptionalLong getMystiqueBlockNumber(); + /** + * Block number to activate Spiral on Classic networks. + * + * @return block number of Spiral fork on Classic networks + * @see https://ecips.ethereumclassic.org/ECIPs/ecip-1109 + */ + OptionalLong getSpiralBlockNumber(); + /** * Gets chain id. * diff --git a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java index 3c8776cac40..29eaef94468 100644 --- a/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java @@ -380,6 +380,11 @@ public OptionalLong getMystiqueBlockNumber() { return getOptionalLong("mystiqueblock"); } + @Override + public OptionalLong getSpiralBlockNumber() { + return getOptionalLong("spiralblock"); + } + @Override public Optional getChainId() { return getOptionalBigInteger("chainid"); @@ -460,6 +465,7 @@ public Map asMap() { getThanosBlockNumber().ifPresent(l -> builder.put("thanosBlock", l)); getMagnetoBlockNumber().ifPresent(l -> builder.put("magnetoBlock", l)); getMystiqueBlockNumber().ifPresent(l -> builder.put("mystiqueBlock", l)); + getSpiralBlockNumber().ifPresent(l -> builder.put("spiralBlock", l)); getContractSizeLimit().ifPresent(l -> builder.put("contractSizeLimit", l)); getEvmStackSize().ifPresent(l -> builder.put("evmstacksize", l)); @@ -567,7 +573,8 @@ public List getForkBlockNumbers() { getPhoenixBlockNumber(), getThanosBlockNumber(), getMagnetoBlockNumber(), - getMystiqueBlockNumber()); + getMystiqueBlockNumber(), + getSpiralBlockNumber()); // when adding forks add an entry to ${REPO_ROOT}/config/src/test/resources/all_forks.json return forkBlockNumbers diff --git a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java index 0d1648f13d2..d36b823c745 100644 --- a/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java +++ b/config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java @@ -66,6 +66,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable private OptionalLong thanosBlockNumber = OptionalLong.empty(); private OptionalLong magnetoBlockNumber = OptionalLong.empty(); private OptionalLong mystiqueBlockNumber = OptionalLong.empty(); + private OptionalLong spiralBlockNumber = OptionalLong.empty(); private Optional chainId = Optional.empty(); private OptionalInt contractSizeLimit = OptionalInt.empty(); private OptionalInt stackSizeLimit = OptionalInt.empty(); @@ -316,6 +317,11 @@ public OptionalLong getMystiqueBlockNumber() { return mystiqueBlockNumber; } + @Override + public OptionalLong getSpiralBlockNumber() { + return spiralBlockNumber; + } + @Override public OptionalInt getContractSizeLimit() { return contractSizeLimit; @@ -374,6 +380,7 @@ public Map asMap() { getThanosBlockNumber().ifPresent(l -> builder.put("thanosBlock", l)); getMagnetoBlockNumber().ifPresent(l -> builder.put("magnetoBlock", l)); getMystiqueBlockNumber().ifPresent(l -> builder.put("mystiqueBlock", l)); + getSpiralBlockNumber().ifPresent(l -> builder.put("spiralBlock", l)); getContractSizeLimit().ifPresent(l -> builder.put("contractSizeLimit", l)); getEvmStackSize().ifPresent(l -> builder.put("evmStackSize", l)); @@ -800,6 +807,17 @@ public StubGenesisConfigOptions mystique(final long blockNumber) { return this; } + /** + * Spiral stub genesis config options. + * + * @param blockNumber the block number + * @return the stub genesis config options + */ + public StubGenesisConfigOptions spiral(final long blockNumber) { + spiralBlockNumber = OptionalLong.of(blockNumber); + return this; + } + /** * Chain id stub genesis config options. * diff --git a/config/src/main/resources/mordor.json b/config/src/main/resources/mordor.json index 0a33f7db0b1..6cc5169cafb 100644 --- a/config/src/main/resources/mordor.json +++ b/config/src/main/resources/mordor.json @@ -8,6 +8,7 @@ "thanosBlock": 2520000, "magnetoBlock": 3985893, "mystiqueBlock": 5520000, + "spiralBlock": 9957000, "ethash": {}, "discovery": { "dns": "enrtree://AJE62Q4DUX4QMMXEHCSSCSC65TDHZYSMONSD64P3WULVLSF6MRQ3K@all.mordor.blockd.info", diff --git a/config/src/test/resources/all_forks.json b/config/src/test/resources/all_forks.json index 8b255820a5c..a697a3748fd 100644 --- a/config/src/test/resources/all_forks.json +++ b/config/src/test/resources/all_forks.json @@ -27,6 +27,7 @@ "phoenixBlock": 108, "thanosBlock": 109, "magnetoBlock": 110, - "mystiqueBlock": 111 + "mystiqueBlock": 111, + "spiralBlock": 112 } } \ No newline at end of file diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminNodeInfoTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminNodeInfoTest.java index 57120d4a4fa..13f68b8e0d2 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminNodeInfoTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AdminNodeInfoTest.java @@ -403,7 +403,8 @@ public void returnsClassicForkBlocks() { "phoenixBlock", 8L, "thanosBlock", 9L, "magnetoBlock", 10L)); - expectedConfig.put("mystiqueBlock", 12L); + expectedConfig.put("mystiqueBlock", 11L); + expectedConfig.put("spiralBlock", 12L); final JsonRpcResponse response = methodClassic.response(request); assertThat(response).isInstanceOf(JsonRpcSuccessResponse.class); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java index bc460811ae0..5d193168b31 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ClassicProtocolSpecs.java @@ -31,6 +31,7 @@ import org.hyperledger.besu.evm.gascalculator.IstanbulGasCalculator; import org.hyperledger.besu.evm.gascalculator.LondonGasCalculator; import org.hyperledger.besu.evm.gascalculator.PetersburgGasCalculator; +import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator; import org.hyperledger.besu.evm.gascalculator.SpuriousDragonGasCalculator; import org.hyperledger.besu.evm.gascalculator.TangerineWhistleGasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; @@ -333,4 +334,46 @@ public static ProtocolSpecBuilder mystiqueDefinition( 1)) .name("Mystique"); } + + public static ProtocolSpecBuilder spiralDefinition( + final Optional chainId, + final OptionalInt configContractSizeLimit, + final OptionalInt configStackSizeLimit, + final boolean enableRevertReason, + final OptionalLong ecip1017EraRounds, + final EvmConfiguration evmConfiguration) { + final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE); + return mystiqueDefinition( + chainId, + configContractSizeLimit, + configStackSizeLimit, + enableRevertReason, + ecip1017EraRounds, + evmConfiguration) + // EIP-3860 + .gasCalculator(ShanghaiGasCalculator::new) + // EIP-3855 + .evmBuilder( + (gasCalculator, jdCacheConfig) -> + MainnetEVMs.shanghai( + gasCalculator, chainId.orElse(BigInteger.ZERO), evmConfiguration)) + // EIP-3651 + .transactionProcessorBuilder( + (gasCalculator, + feeMarket, + transactionValidatorFactory, + contractCreationProcessor, + messageCallProcessor) -> + new MainnetTransactionProcessor( + gasCalculator, + transactionValidatorFactory, + contractCreationProcessor, + messageCallProcessor, + true, + true, + stackSizeLimit, + feeMarket, + CoinbaseFeePriceCalculator.frontier())) + .name("Spiral"); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java index 3a06d803980..bcf5cdcc0b4 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java @@ -287,4 +287,14 @@ public ProtocolSpecBuilder mystiqueDefinition() { ecip1017EraRounds, evmConfiguration); } + + public ProtocolSpecBuilder spiralDefinition() { + return ClassicProtocolSpecs.spiralDefinition( + chainId, + contractSizeLimit, + evmStackSize, + isRevertReasonEnabled, + ecip1017EraRounds, + evmConfiguration); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java index 786fdd35976..519450b42fc 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java @@ -258,6 +258,7 @@ private void validateClassicForkOrdering() { lastForkBlock = validateForkOrder("Thanos", config.getThanosBlockNumber(), lastForkBlock); lastForkBlock = validateForkOrder("Magneto", config.getMagnetoBlockNumber(), lastForkBlock); lastForkBlock = validateForkOrder("Mystique", config.getMystiqueBlockNumber(), lastForkBlock); + lastForkBlock = validateForkOrder("Spiral", config.getSpiralBlockNumber(), lastForkBlock); assert (lastForkBlock >= 0); } @@ -329,7 +330,8 @@ private Stream> createMilestones( blockNumberMilestone(config.getPhoenixBlockNumber(), specFactory.phoenixDefinition()), blockNumberMilestone(config.getThanosBlockNumber(), specFactory.thanosDefinition()), blockNumberMilestone(config.getMagnetoBlockNumber(), specFactory.magnetoDefinition()), - blockNumberMilestone(config.getMystiqueBlockNumber(), specFactory.mystiqueDefinition())); + blockNumberMilestone(config.getMystiqueBlockNumber(), specFactory.mystiqueDefinition()), + blockNumberMilestone(config.getSpiralBlockNumber(), specFactory.spiralDefinition())); } private Optional timestampMilestone(