22// Copyright 2023 The evmone Authors.
33// SPDX-License-Identifier: Apache-2.0
44
5+ #include " ../state/ethash_difficulty.hpp"
56#include " ../state/mpt_hash.hpp"
67#include " ../state/requests.hpp"
78#include " ../state/rlp.hpp"
@@ -114,7 +115,7 @@ TransitionResult apply_block(const TestState& state, evmc::VM& vm, const state::
114115}
115116
116117bool validate_block (evmc_revision rev, state::BlobParams blob_params, const TestBlock& test_block,
117- const BlockHeader* parent_header) noexcept
118+ const BlockHeader* parent_header, bool parent_has_ommers ) noexcept
118119{
119120 // NOTE: includes only block validity unrelated to individual txs. See `apply_block`.
120121
@@ -142,6 +143,17 @@ bool validate_block(evmc_revision rev, state::BlobParams blob_params, const Test
142143 if (test_block.block_info .gas_limit < 5000 )
143144 return false ;
144145
146+ // FIXME: Some tests have timestamp not fitting into int64_t, type has to be uint64_t.
147+ if (static_cast <uint64_t >(test_block.block_info .timestamp ) <=
148+ static_cast <uint64_t >(parent_header->timestamp ))
149+ return false ;
150+
151+ if (test_block.block_info .difficulty != state::calculate_difficulty (parent_header->difficulty ,
152+ parent_has_ommers, parent_header->timestamp ,
153+ test_block.block_info .timestamp ,
154+ test_block.block_info .number , rev))
155+ return false ;
156+
145157 if (rev >= EVMC_PARIS && !test_block.block_info .ommers .empty ())
146158 return false ;
147159
@@ -154,11 +166,6 @@ bool validate_block(evmc_revision rev, state::BlobParams blob_params, const Test
154166 return false ;
155167 }
156168
157- // FIXME: Some tests have timestamp not fitting into int64_t, type has to be uint64_t.
158- if (static_cast <uint64_t >(test_block.block_info .timestamp ) <=
159- static_cast <uint64_t >(parent_header->timestamp ))
160- return false ;
161-
162169 if (test_block.block_info .extra_data .size () > 32 )
163170 return false ;
164171
@@ -272,11 +279,12 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
272279 struct BlockData
273280 {
274281 const BlockHeader* header;
282+ bool has_ommers = false ;
275283 TestState post_state;
276284 intx::uint256 total_difficulty;
277285 };
278286 std::unordered_map<hash256, BlockData> block_data{{{c.genesis_block_header .hash ,
279- {&c.genesis_block_header , c.pre_state , c.genesis_block_header .difficulty }}}};
287+ {&c.genesis_block_header , false , c.pre_state , c.genesis_block_header .difficulty }}}};
280288 const auto * canonical_state = &c.pre_state ;
281289 intx::uint256 max_total_difficulty = c.genesis_block_header .difficulty ;
282290
@@ -288,6 +296,8 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
288296 const auto parent_data_it = block_data.find (test_block.block_info .parent_hash );
289297 const auto * parent_header =
290298 parent_data_it != block_data.end () ? parent_data_it->second .header : nullptr ;
299+ const auto parent_has_ommers =
300+ parent_data_it != block_data.end () && parent_data_it->second .has_ommers ;
291301
292302 const auto rev = rev_schedule.get_revision (bi.timestamp );
293303 const auto blob_params = get_blob_params (c.network , c.blob_schedule , bi.timestamp );
@@ -297,7 +307,8 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
297307
298308 if (test_block.valid )
299309 {
300- ASSERT_TRUE (validate_block (rev, blob_params, test_block, parent_header))
310+ ASSERT_TRUE (
311+ validate_block (rev, blob_params, test_block, parent_header, parent_has_ommers))
301312 << " Expected block to be valid (validate_block)" ;
302313
303314 // Block being valid guarantees its parent was found.
@@ -312,9 +323,13 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
312323 block_hashes[test_block.expected_block_header .block_number ] =
313324 test_block.expected_block_header .hash ;
314325 const auto [inserted_it, _] = block_data.insert ({test_block.block_info .hash ,
315- {&test_block.expected_block_header , std::move (res.block_state ),
316- parent_data_it->second .total_difficulty +
317- test_block.block_info .difficulty }});
326+ {
327+ .header = &test_block.expected_block_header ,
328+ .has_ommers = !test_block.block_info .ommers .empty (),
329+ .post_state = std::move (res.block_state ),
330+ .total_difficulty = parent_data_it->second .total_difficulty +
331+ test_block.block_info .difficulty ,
332+ }});
318333 if (inserted_it->second .total_difficulty >= max_total_difficulty)
319334 {
320335 canonical_state = &inserted_it->second .post_state ;
@@ -350,7 +365,7 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
350365 }
351366 else
352367 {
353- if (!validate_block (rev, blob_params, test_block, parent_header))
368+ if (!validate_block (rev, blob_params, test_block, parent_header, parent_has_ommers ))
354369 continue ;
355370
356371 // Block being valid guarantees its parent was found.
@@ -401,7 +416,6 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
401416 print_state (std::get<TestState>(c.expectation .post_state )) :
402417 " " );
403418 }
404- // TODO: Add difficulty calculation verification.
405419}
406420
407421} // namespace evmone::test
0 commit comments