From 3e16ad715ef13ecbe3906d7760154d0715afdf08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 24 Jan 2025 15:38:34 +0100 Subject: [PATCH] state: Simplify code modification indicator in StateDiff --- test/state/account.hpp | 3 +++ test/state/host.cpp | 34 +++++++++++++++++++--------------- test/state/state.cpp | 2 +- test/state/state_diff.hpp | 4 ++-- test/state/test_state.cpp | 4 ++-- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/test/state/account.hpp b/test/state/account.hpp index d08c009559..f4810ab44c 100644 --- a/test/state/account.hpp +++ b/test/state/account.hpp @@ -73,6 +73,9 @@ struct Account /// The account has been created in the current transaction. bool just_created = false; + // This account's code has been modified. + bool code_changed = false; + evmc_access_status access_status = EVMC_ACCESS_COLD; [[nodiscard]] bool is_empty() const noexcept diff --git a/test/state/host.cpp b/test/state/host.cpp index 59413a7aea..5465c6acfa 100644 --- a/test/state/host.cpp +++ b/test/state/host.cpp @@ -377,26 +377,30 @@ evmc::Result Host::create(const evmc_message& msg) noexcept evmc::Result{EVMC_FAILURE}; } - if (!code.empty() && code[0] == 0xEF) + if (!code.empty()) { - if (m_rev >= EVMC_OSAKA) + if (code[0] == 0xEF) { - // Only EOFCREATE/EOF-creation-tx is allowed to deploy code starting with EF. - // It must be valid EOF, which was validated before execution. - if (msg.kind != EVMC_EOFCREATE) + if (m_rev >= EVMC_OSAKA) + { + // Only EOFCREATE/EOF-creation-tx is allowed to deploy code starting with EF. + // It must be valid EOF, which was validated before execution. + if (msg.kind != EVMC_EOFCREATE) + return evmc::Result{EVMC_CONTRACT_VALIDATION_FAILURE}; + assert(validate_eof(m_rev, ContainerKind::runtime, code) == + EOFValidationError::success); + } + else if (m_rev >= EVMC_LONDON) + { + // EIP-3541: Reject EF code. return evmc::Result{EVMC_CONTRACT_VALIDATION_FAILURE}; - assert( - validate_eof(m_rev, ContainerKind::runtime, code) == EOFValidationError::success); - } - else if (m_rev >= EVMC_LONDON) - { - // EIP-3541: Reject EF code. - return evmc::Result{EVMC_CONTRACT_VALIDATION_FAILURE}; + } } - } - new_acc->code_hash = keccak256(code); - new_acc->code = code; + new_acc->code_hash = keccak256(code); + new_acc->code = code; + new_acc->code_changed = true; + } return evmc::Result{result.status_code, gas_left, result.gas_refund, msg.recipient}; } diff --git a/test/state/state.cpp b/test/state/state.cpp index 2a78de53f6..f5b9387e19 100644 --- a/test/state/state.cpp +++ b/test/state/state.cpp @@ -130,7 +130,7 @@ StateDiff State::build_diff(evmc_revision rev) const // Output only the new code. // TODO: Output also the code hash. It will be needed for DB update and MPT hash. - if (m.just_created && !m.code.empty()) + if (m.code_changed) a.code = m.code; for (const auto& [k, v] : m.storage) diff --git a/test/state/state_diff.hpp b/test/state/state_diff.hpp index 81fba225fc..4268804753 100644 --- a/test/state/state_diff.hpp +++ b/test/state/state_diff.hpp @@ -30,8 +30,8 @@ struct StateDiff /// TODO: Currently it is not guaranteed the value is different from the initial one. uint256 balance; - /// New account code. If empty, it means the code has not changed. - bytes code; + /// New or modified account code. If bytes are empty, it means the code has been cleared. + std::optional code; /// The list of the account's storage modifications: key => new value. /// The value 0 means the storage entry is deleted. diff --git a/test/state/test_state.cpp b/test/state/test_state.cpp index c94af16ef6..fc83008422 100644 --- a/test/state/test_state.cpp +++ b/test/state/test_state.cpp @@ -34,8 +34,8 @@ void TestState::apply(const state::StateDiff& diff) auto& a = (*this)[m.addr]; a.nonce = m.nonce; a.balance = m.balance; - if (!m.code.empty()) - a.code = m.code; // TODO: Consider taking rvalue ref to avoid code copy. + if (m.code.has_value()) + a.code = *m.code; // TODO: Consider taking rvalue ref to avoid code copy. for (const auto& [k, v] : m.modified_storage) { if (v)