From 52e4530c822c9f22477cae6c7e314caa3a79d562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 19 Aug 2024 17:31:13 +0200 Subject: [PATCH] blockchaintest: Only check state root for 5 first/last blocks This is blockchain tests execution optimization: only check state root hash of first 5 blocks (to detect early problems) and last 5 blocks (to do the final check of the chain of blocks). The current implementation of the MPT hash of the state builds the trie from scratch (no updates to the trie of the previous block). For the tests will a long chain of blocks the performance degrades significantly with 99% time spent in the keccak hash function. This improves testing of EIP-2935 implemented in https://github.com/ethereum/evmone/pull/953. --- test/blockchaintest/blockchaintest_runner.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/test/blockchaintest/blockchaintest_runner.cpp b/test/blockchaintest/blockchaintest_runner.cpp index c8d37448a9..16b88f3fbc 100644 --- a/test/blockchaintest/blockchaintest_runner.cpp +++ b/test/blockchaintest/blockchaintest_runner.cpp @@ -141,8 +141,9 @@ void run_blockchain_tests(std::span tests, evmc::VM& vm) std::unordered_map known_block_hashes{ {c.genesis_block_header.block_number, c.genesis_block_header.hash}}; - for (const auto& test_block : c.test_blocks) + for (size_t i = 0; i != c.test_blocks.size(); ++i) { + const auto& test_block = c.test_blocks[i]; auto bi = test_block.block_info; bi.known_block_hashes = known_block_hashes; @@ -157,8 +158,17 @@ void run_blockchain_tests(std::span tests, evmc::VM& vm) SCOPED_TRACE(std::string{evmc::to_string(rev)} + '/' + std::to_string(case_index) + '/' + c.name + '/' + std::to_string(test_block.block_info.number)); - EXPECT_EQ( - state::mpt_hash(TestState{state}), test_block.expected_block_header.state_root); + static constexpr size_t STATE_HASH_CHECK_MARGIN = 5; + if (i < STATE_HASH_CHECK_MARGIN || i >= c.test_blocks.size() - STATE_HASH_CHECK_MARGIN) + { + // Only check state hashes for first (early problems) + // and last (final check of the chain) blocks. + // Otherwise, for very long blockchain test we spend a lot of time in MPT hashing + // because the implementation of it is very simplistic: the trie is not updated + // along the state changes but a new trie is build from scratch for every block. + EXPECT_EQ( + state::mpt_hash(TestState{state}), test_block.expected_block_header.state_root); + } if (rev >= EVMC_SHANGHAI) {