diff --git a/test/state/state.cpp b/test/state/state.cpp index f838afec98..4edf6dde2b 100644 --- a/test/state/state.cpp +++ b/test/state/state.cpp @@ -117,6 +117,14 @@ evmc_message build_message(const Transaction& tx, int64_t execution_gas_limit) n } } // namespace +void finalize(State& state, evmc_revision rev) +{ + std::erase_if(state.get_accounts(), [rev](const std::pair& p) noexcept { + const auto& acc = p.second; + return acc.destructed || (rev >= EVMC_SPURIOUS_DRAGON && acc.erasable && acc.is_empty()); + }); +} + std::variant transition( State& state, const BlockInfo& block, const Transaction& tx, evmc_revision rev, evmc::VM& vm) { @@ -124,12 +132,7 @@ std::variant transition( const auto validation_result = validate_transaction(sender_acc, block, tx, rev); if (holds_alternative(validation_result)) - { - // Pre EIP-158 coinbase has to be touched also for invalid tx. - if (rev <= EVMC_TANGERINE_WHISTLE) - state.touch(block.coinbase); return get(validation_result); - } const auto execution_gas_limit = get(validation_result); @@ -177,10 +180,7 @@ std::variant transition( state.touch(block.coinbase).balance += gas_used * priority_gas_price; // Apply destructs and clear erasable empty accounts. - std::erase_if(state.get_accounts(), [rev](const std::pair& p) noexcept { - const auto& acc = p.second; - return acc.destructed || (rev >= EVMC_SPURIOUS_DRAGON && acc.erasable && acc.is_empty()); - }); + finalize(state, rev); auto receipt = TransactionReceipt{tx.kind, result.status_code, gas_used, host.take_logs(), {}}; diff --git a/test/state/state.hpp b/test/state/state.hpp index 82bbf8a5b6..08b2377fda 100644 --- a/test/state/state.hpp +++ b/test/state/state.hpp @@ -118,6 +118,9 @@ struct TransactionReceipt BloomFilter logs_bloom_filter; }; +/// Clears destructed accounts and empty accounts for post EIP158 rev. +void finalize(State& state, evmc_revision rev); + [[nodiscard]] std::variant transition( State& state, const BlockInfo& block, const Transaction& tx, evmc_revision rev, evmc::VM& vm); diff --git a/test/statetest/statetest_runner.cpp b/test/statetest/statetest_runner.cpp index 9863d9de1f..0f2f468cbf 100644 --- a/test/statetest/statetest_runner.cpp +++ b/test/statetest/statetest_runner.cpp @@ -43,6 +43,11 @@ void run_state_test(const StateTransitionTest& test, evmc::VM& vm) } const auto res = state::transition(state, test.block, tx, rev, vm); + + // Touches coinbase even if block reward is 0. It remains in state pre EIP158. + state.touch(test.block.coinbase); + state::finalize(state, rev); + if (holds_alternative(res)) EXPECT_EQ(logs_hash(get(res).logs), expected.logs_hash); else diff --git a/test/t8n/t8n.cpp b/test/t8n/t8n.cpp index 5c62ab5f31..480b8c3675 100644 --- a/test/t8n/t8n.cpp +++ b/test/t8n/t8n.cpp @@ -157,9 +157,12 @@ int main(int argc, const char* argv[]) } } + // Touches coinbase even if block reward is 0. It remains in state pre EIP158. if (block_reward.has_value()) state.touch(block.coinbase).balance += *block_reward; + state::finalize(state, rev); + j_result["logsHash"] = hex0x(logs_hash(txs_logs)); j_result["stateRoot"] = hex0x(state::mpt_hash(state.get_accounts())); }