From 9a22703b5d4c2301e8614737c803360059c24394 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 26 Oct 2023 15:15:56 +1000 Subject: [PATCH 1/4] Remove a BonsaiWorldStateProvider constructor (#6090) Was only used for supporting test code and can instead reuse static factory from InMemoryKeyValueStorageProvider Signed-off-by: Simon Dudley --- .../bonsai/BonsaiWorldStateProvider.java | 18 ------------------ .../core/InMemoryKeyValueStorageProvider.java | 7 ++++++- .../BlockImportExceptionHandlingTest.java | 8 +------- .../besu/ethereum/bonsai/LogRollingTests.java | 16 ++-------------- .../besu/ethereum/bonsai/RollingImport.java | 6 +----- 5 files changed, 10 insertions(+), 45 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiWorldStateProvider.java index bcb7f9f65fe..b64f3855a3e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/bonsai/BonsaiWorldStateProvider.java @@ -32,10 +32,8 @@ import org.hyperledger.besu.ethereum.proof.WorldStateProof; import org.hyperledger.besu.ethereum.proof.WorldStateProofProvider; import org.hyperledger.besu.ethereum.rlp.RLP; -import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; -import org.hyperledger.besu.ethereum.worldstate.DataStorageFormat; import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive; import org.hyperledger.besu.evm.worldstate.WorldState; @@ -68,22 +66,6 @@ public class BonsaiWorldStateProvider implements WorldStateArchive { private final BonsaiWorldStateKeyValueStorage worldStateStorage; private final CachedMerkleTrieLoader cachedMerkleTrieLoader; - public BonsaiWorldStateProvider( - final StorageProvider provider, - final Blockchain blockchain, - final CachedMerkleTrieLoader cachedMerkleTrieLoader, - final ObservableMetricsSystem metricsSystem, - final BesuContext pluginContext) { - this( - (BonsaiWorldStateKeyValueStorage) - provider.createWorldStateStorage(DataStorageFormat.BONSAI), - blockchain, - Optional.empty(), - cachedMerkleTrieLoader, - metricsSystem, - pluginContext); - } - public BonsaiWorldStateProvider( final BonsaiWorldStateKeyValueStorage worldStateStorage, final Blockchain blockchain, diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java index 3687643c6d9..f5d5fb9726e 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/InMemoryKeyValueStorageProvider.java @@ -16,6 +16,7 @@ import org.hyperledger.besu.ethereum.bonsai.BonsaiWorldStateProvider; import org.hyperledger.besu.ethereum.bonsai.cache.CachedMerkleTrieLoader; +import org.hyperledger.besu.ethereum.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.chain.Blockchain; import org.hyperledger.besu.ethereum.chain.DefaultBlockchain; import org.hyperledger.besu.ethereum.chain.MutableBlockchain; @@ -35,6 +36,8 @@ import org.hyperledger.besu.services.kvstore.InMemoryKeyValueStorage; import org.hyperledger.besu.services.kvstore.SegmentedInMemoryKeyValueStorage; +import java.util.Optional; + public class InMemoryKeyValueStorageProvider extends KeyValueStorageProvider { public InMemoryKeyValueStorageProvider() { @@ -86,8 +89,10 @@ public static BonsaiWorldStateProvider createBonsaiInMemoryWorldStateArchive( final CachedMerkleTrieLoader cachedMerkleTrieLoader = new CachedMerkleTrieLoader(new NoOpMetricsSystem()); return new BonsaiWorldStateProvider( - inMemoryKeyValueStorageProvider, + (BonsaiWorldStateKeyValueStorage) + inMemoryKeyValueStorageProvider.createWorldStateStorage(DataStorageFormat.BONSAI), blockchain, + Optional.empty(), cachedMerkleTrieLoader, new NoOpMetricsSystem(), null); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java index b936ed28fa3..9f1e30ff3ba 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java @@ -24,7 +24,6 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.bonsai.BonsaiWorldStateProvider; -import org.hyperledger.besu.ethereum.bonsai.cache.CachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.bonsai.worldview.BonsaiWorldState; import org.hyperledger.besu.ethereum.chain.BadBlockManager; @@ -82,14 +81,10 @@ public class BlockImportExceptionHandlingTest { private final WorldStateStorage worldStateStorage = new BonsaiWorldStateKeyValueStorage(storageProvider, new NoOpMetricsSystem()); - private CachedMerkleTrieLoader cachedMerkleTrieLoader; - private final WorldStateArchive worldStateArchive = // contains a BonsaiWorldState which we need to spy on. // do we need to also test with a DefaultWorldStateArchive? - spy( - new BonsaiWorldStateProvider( - storageProvider, blockchain, cachedMerkleTrieLoader, new NoOpMetricsSystem(), null)); + spy(InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive(blockchain)); private final BonsaiWorldState persisted = spy( @@ -109,7 +104,6 @@ public void setup() { mainnetBlockValidator = new MainnetBlockValidator( blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager); - cachedMerkleTrieLoader = new CachedMerkleTrieLoader(new NoOpMetricsSystem()); } @Test diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java index 0e2fb0c0d1a..054e1b88cc7 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/LogRollingTests.java @@ -22,7 +22,6 @@ import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.bonsai.cache.CachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogFactoryImpl; import org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogLayer; @@ -128,11 +127,7 @@ class LogRollingTests { @BeforeEach void createStorage() { provider = new InMemoryKeyValueStorageProvider(); - final CachedMerkleTrieLoader cachedMerkleTrieLoader = - new CachedMerkleTrieLoader(new NoOpMetricsSystem()); - archive = - new BonsaiWorldStateProvider( - provider, blockchain, cachedMerkleTrieLoader, new NoOpMetricsSystem(), null); + archive = InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive(blockchain); accountStorage = provider.getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.ACCOUNT_INFO_STATE); codeStorage = provider.getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.CODE_STORAGE); @@ -144,15 +139,8 @@ void createStorage() { provider.getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.TRIE_LOG_STORAGE); secondProvider = new InMemoryKeyValueStorageProvider(); - final CachedMerkleTrieLoader secondOptimizedMerkleTrieLoader = - new CachedMerkleTrieLoader(new NoOpMetricsSystem()); secondArchive = - new BonsaiWorldStateProvider( - secondProvider, - blockchain, - secondOptimizedMerkleTrieLoader, - new NoOpMetricsSystem(), - null); + InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive(blockchain); secondAccountStorage = secondProvider.getStorageBySegmentIdentifier(KeyValueSegmentIdentifier.ACCOUNT_INFO_STATE); secondCodeStorage = diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/RollingImport.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/RollingImport.java index 46e5b6af9f8..397ebf1f9ab 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/RollingImport.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/bonsai/RollingImport.java @@ -22,7 +22,6 @@ import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.CODE_STORAGE; import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; -import org.hyperledger.besu.ethereum.bonsai.cache.CachedMerkleTrieLoader; import org.hyperledger.besu.ethereum.bonsai.storage.BonsaiWorldStateKeyValueStorage; import org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogFactoryImpl; import org.hyperledger.besu.ethereum.bonsai.trielog.TrieLogLayer; @@ -51,11 +50,8 @@ public static void main(final String[] arg) throws IOException { new RollingFileReader((i, c) -> Path.of(String.format(arg[0] + "-%04d.rdat", i)), false); final InMemoryKeyValueStorageProvider provider = new InMemoryKeyValueStorageProvider(); - final CachedMerkleTrieLoader cachedMerkleTrieLoader = - new CachedMerkleTrieLoader(new NoOpMetricsSystem()); final BonsaiWorldStateProvider archive = - new BonsaiWorldStateProvider( - provider, null, cachedMerkleTrieLoader, new NoOpMetricsSystem(), null); + InMemoryKeyValueStorageProvider.createBonsaiInMemoryWorldStateArchive(null); final BonsaiWorldState bonsaiState = new BonsaiWorldState( archive, new BonsaiWorldStateKeyValueStorage(provider, new NoOpMetricsSystem())); From 7ac8af043882486797209931d52637c79b01c20f Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 26 Oct 2023 16:33:15 +1000 Subject: [PATCH 2/4] add RpcEndpointService to thread runner (#6091) Signed-off-by: Sally MacFarlane --- .../besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java index 0c5f170931b..da8d6bfad10 100644 --- a/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java +++ b/acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ThreadBesuNodeRunner.java @@ -44,6 +44,7 @@ import org.hyperledger.besu.plugin.services.BesuEvents; import org.hyperledger.besu.plugin.services.PicoCLIOptions; import org.hyperledger.besu.plugin.services.PluginTransactionValidatorService; +import org.hyperledger.besu.plugin.services.RpcEndpointService; import org.hyperledger.besu.plugin.services.SecurityModuleService; import org.hyperledger.besu.plugin.services.StorageService; import org.hyperledger.besu.plugin.services.TransactionSelectionService; @@ -98,6 +99,7 @@ private BesuPluginContextImpl buildPluginContext( besuPluginContext.addService(StorageService.class, storageService); besuPluginContext.addService(SecurityModuleService.class, securityModuleService); besuPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine)); + besuPluginContext.addService(RpcEndpointService.class, new RpcEndpointServiceImpl()); besuPluginContext.addService( TransactionSelectionService.class, new TransactionSelectionServiceImpl()); besuPluginContext.addService( From f58f6cffca1c877b566ee5f6e980a53b352bd3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20L=C3=B3pez=20Le=C3=B3n?= Date: Thu, 26 Oct 2023 04:31:41 -0300 Subject: [PATCH 3/4] ETC 'Spiral' network upgrade (#6078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add 23.10.2 section to changelog Signed-off-by: Diego López León * Set ENR tree for DNS discovery for Mordor network Signed-off-by: Diego López León * Add ECIP-1109: 'Spiral' network upgrade support Signed-off-by: Diego López León --------- Signed-off-by: Diego López León Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- CHANGELOG.md | 13 ++++++ .../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 | 2 + config/src/test/resources/all_forks.json | 3 +- .../internal/methods/AdminNodeInfoTest.java | 6 ++- .../mainnet/ClassicProtocolSpecs.java | 43 +++++++++++++++++++ .../mainnet/MainnetProtocolSpecFactory.java | 10 +++++ .../mainnet/ProtocolScheduleBuilder.java | 4 +- 11 files changed, 115 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 787ff1d137d..e264da3056f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,19 @@ ### Download Links +## 23.10.2 + +### Breaking Changes + +### Deprecations + +### Additions and Improvements +- Ethereum Classic Spiral network upgrade [#6078](https://github.com/hyperledger/besu/pull/6078) + +### Bug fixes + +### Download Links + ## 23.10.1 - Cache last n blocks by using a new Besu flag --cache-last-blocks=n [#6009](https://github.com/hyperledger/besu/pull/6009) - Optimize performances of RPC method Eth_feeHistory [#6011](https://github.com/hyperledger/besu/pull/6011) 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 5db1e4ce0ca..6cc5169cafb 100644 --- a/config/src/main/resources/mordor.json +++ b/config/src/main/resources/mordor.json @@ -8,8 +8,10 @@ "thanosBlock": 2520000, "magnetoBlock": 3985893, "mystiqueBlock": 5520000, + "spiralBlock": 9957000, "ethash": {}, "discovery": { + "dns": "enrtree://AJE62Q4DUX4QMMXEHCSSCSC65TDHZYSMONSD64P3WULVLSF6MRQ3K@all.mordor.blockd.info", "bootnodes": [ "enode://642cf9650dd8869d42525dbf6858012e3b4d64f475e733847ab6f7742341a4397414865d953874e8f5ed91b0e4e1c533dee14ad1d6bb276a5459b2471460ff0d@157.230.152.87:30303", "enode://651b484b652c07c72adebfaaf8bc2bd95b420b16952ef3de76a9c00ef63f07cca02a20bd2363426f9e6fe372cef96a42b0fec3c747d118f79fd5e02f2a4ebd4e@51.158.190.99:45678", 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..20284cb5de3 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 @@ -377,7 +377,8 @@ public void returnsClassicForkBlocks() { .phoenix(8) .thanos(9) .magneto(10) - .mystique(12); + .mystique(11) + .spiral(12); final AdminNodeInfo methodClassic = new AdminNodeInfo( @@ -403,7 +404,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( From 0345b2473f349e229af05d663b340da24741b121 Mon Sep 17 00:00:00 2001 From: delehef Date: Fri, 27 Oct 2023 00:33:10 +0200 Subject: [PATCH 4/4] Trigger contextEnter/Exit for all frames, including root (#6074) * Trigger contextEnter/Exit for all frames, including root * Differentiate between context entry and re-entry in `OperationTracer` * Update evm/src/test/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessorTest.java Co-authored-by: Sally MacFarlane Signed-off-by: delehef --------- Signed-off-by: Franklin Delehelle Signed-off-by: delehef Signed-off-by: Sally MacFarlane Co-authored-by: Sally MacFarlane --- .../processor/AbstractMessageProcessor.java | 12 +++-- .../besu/evm/tracing/OperationTracer.java | 7 +++ .../AbstractMessageProcessorTest.java | 51 +++++++------------ 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessor.java b/evm/src/main/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessor.java index 0e910068258..2bc98b58efc 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessor.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessor.java @@ -184,8 +184,12 @@ private void codeExecute(final MessageFrame frame, final OperationTracer operati * @param operationTracer the operation tracer */ public void process(final MessageFrame frame, final OperationTracer operationTracer) { - if (operationTracer != null && frame.getMessageStackSize() > 1) { - operationTracer.traceContextEnter(frame); + if (operationTracer != null) { + if (frame.getState() == MessageFrame.State.NOT_STARTED) { + operationTracer.traceContextEnter(frame); + } else { + operationTracer.traceContextReEnter(frame); + } } if (frame.getState() == MessageFrame.State.NOT_STARTED) { @@ -213,13 +217,13 @@ public void process(final MessageFrame frame, final OperationTracer operationTra } if (frame.getState() == MessageFrame.State.COMPLETED_SUCCESS) { - if (operationTracer != null && frame.getMessageStackSize() > 1) { + if (operationTracer != null) { operationTracer.traceContextExit(frame); } completedSuccess(frame); } if (frame.getState() == MessageFrame.State.COMPLETED_FAILED) { - if (operationTracer != null && frame.getMessageStackSize() > 1) { + if (operationTracer != null) { operationTracer.traceContextExit(frame); } completedFailed(frame); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java index 455911c6ca1..edaed8e2416 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OperationTracer.java @@ -102,6 +102,13 @@ default void traceEndTransaction( */ default void traceContextEnter(final MessageFrame frame) {} + /** + * Trace the re-entry in a context from a child context + * + * @param frame the frame + */ + default void traceContextReEnter(final MessageFrame frame) {} + /** * Trace the exiting of a context * diff --git a/evm/src/test/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessorTest.java index 598758fb752..016f3f6da37 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/processor/AbstractMessageProcessorTest.java @@ -17,9 +17,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hyperledger.besu.evm.processor.AbstractMessageProcessorTest.ContextTracer.TRACE_TYPE.CONTEXT_ENTER; import static org.hyperledger.besu.evm.processor.AbstractMessageProcessorTest.ContextTracer.TRACE_TYPE.CONTEXT_EXIT; +import static org.hyperledger.besu.evm.processor.AbstractMessageProcessorTest.ContextTracer.TRACE_TYPE.CONTEXT_RE_ENTER; import static org.hyperledger.besu.evm.processor.AbstractMessageProcessorTest.ContextTracer.TRACE_TYPE.POST_EXECUTION; import static org.hyperledger.besu.evm.processor.AbstractMessageProcessorTest.ContextTracer.TRACE_TYPE.PRE_EXECUTION; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -30,8 +30,8 @@ import org.hyperledger.besu.evm.fluent.EVMExecutor; import org.hyperledger.besu.evm.frame.MessageFrame; import org.hyperledger.besu.evm.operation.Operation; +import org.hyperledger.besu.evm.toy.ToyWorld; import org.hyperledger.besu.evm.tracing.OperationTracer; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.ArrayList; import java.util.Arrays; @@ -41,59 +41,37 @@ import org.apache.tuweni.bytes.Bytes; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) abstract class AbstractMessageProcessorTest { - @Mock MessageFrame messageFrame; @Mock OperationTracer operationTracer; @Mock Deque messageFrameStack; - @Mock WorldUpdater worldUpdater; protected abstract T getAbstractMessageProcessor(); - @ParameterizedTest - @ValueSource(ints = {0, 1}) - void shouldNotTraceContextIfStackSizeIsZero(final int stackSize) { - when(messageFrame.getMessageStackSize()).thenReturn(stackSize); - when(messageFrame.getState()) - .thenReturn(MessageFrame.State.COMPLETED_SUCCESS, MessageFrame.State.COMPLETED_FAILED); - when(messageFrame.getMessageFrameStack()).thenReturn(messageFrameStack); - - getAbstractMessageProcessor().process(messageFrame, operationTracer); - - verify(operationTracer, never()).traceContextEnter(messageFrame); - verify(operationTracer, never()).traceContextExit(messageFrame); - } - - @ParameterizedTest - @ValueSource(ints = {2, 3, 5, 15, Integer.MAX_VALUE}) - void shouldTraceContextIfStackSizeIsGreaterZeroAndSuccess(final int stackSize) { - when(messageFrame.getMessageStackSize()).thenReturn(stackSize); + @Test + void shouldTraceExitForContext() { + when(messageFrame.getWorldUpdater()).thenReturn(new ToyWorld()); when(messageFrame.getState()).thenReturn(MessageFrame.State.COMPLETED_SUCCESS); when(messageFrame.getMessageFrameStack()).thenReturn(messageFrameStack); - when(messageFrame.getWorldUpdater()).thenReturn(worldUpdater); getAbstractMessageProcessor().process(messageFrame, operationTracer); - verify(operationTracer, times(1)).traceContextEnter(messageFrame); + // As the only MessageFrame state will be COMPLETED_SUCCESS, only a contextExit is expected verify(operationTracer, times(1)).traceContextExit(messageFrame); } - @ParameterizedTest - @ValueSource(ints = {2, 3, 5, 15, Integer.MAX_VALUE}) - void shouldTraceContextIfStackSizeIsGreaterZeroAndFailure(final int stackSize) { - when(messageFrame.getMessageStackSize()).thenReturn(stackSize); + @Test + void shouldTraceExitEvenIfContextFailed() { when(messageFrame.getState()).thenReturn(MessageFrame.State.COMPLETED_FAILED); when(messageFrame.getMessageFrameStack()).thenReturn(messageFrameStack); getAbstractMessageProcessor().process(messageFrame, operationTracer); - verify(operationTracer, times(1)).traceContextEnter(messageFrame); + // As the only MessageFrame state will be COMPLETED_FAILED, only a contextExit is expected verify(operationTracer, times(1)).traceContextExit(messageFrame); } @@ -133,6 +111,7 @@ void shouldTraceContextEnterExitForEip3155Test() { final List expectedTraces = Arrays.asList( + CONTEXT_ENTER, // Entry in root context PRE_EXECUTION, // PUSH1 POST_EXECUTION, // PUSH1 PRE_EXECUTION, // DUP1 @@ -161,10 +140,12 @@ void shouldTraceContextEnterExitForEip3155Test() { POST_EXECUTION, // STATICCALL CONTEXT_ENTER, // STATICCALL CONTEXT_EXIT, // STATICCALL + CONTEXT_RE_ENTER, // Re-entry in root context post-STATICALL PRE_EXECUTION, // PUSH1 POST_EXECUTION, // PUSH1 PRE_EXECUTION, // RETURN - POST_EXECUTION // RETURN + POST_EXECUTION, // RETURN + CONTEXT_EXIT // Exiting root context ); assertThat(contextTracer.traceHistory()).isEqualTo(expectedTraces); @@ -175,6 +156,7 @@ enum TRACE_TYPE { PRE_EXECUTION, POST_EXECUTION, CONTEXT_ENTER, + CONTEXT_RE_ENTER, CONTEXT_EXIT } @@ -196,6 +178,11 @@ public void traceContextEnter(final MessageFrame frame) { traceHistory.add(TRACE_TYPE.CONTEXT_ENTER); } + @Override + public void traceContextReEnter(final MessageFrame frame) { + traceHistory.add(CONTEXT_RE_ENTER); + } + @Override public void traceContextExit(final MessageFrame frame) { traceHistory.add(TRACE_TYPE.CONTEXT_EXIT);