diff --git a/test/state/test_state.cpp b/test/state/test_state.cpp index dd4bec3ec7..c6a1af7381 100644 --- a/test/state/test_state.cpp +++ b/test/state/test_state.cpp @@ -7,13 +7,33 @@ namespace evmone::test { +std::optional TestState::get_account(const address& addr) const noexcept +{ + const auto it = find(addr); + if (it == end()) + return std::nullopt; + + const auto& acc = it->second; + // TODO: Cache code hash for MTP root hash calculation? + return Account{acc.nonce, acc.balance, keccak256(acc.code), !acc.storage.empty()}; +} + +bytes TestState::get_account_code(const address& addr) const noexcept +{ + const auto it = find(addr); + if (it == end()) + return {}; + + return it->second.code; +} + state::State TestState::to_intra_state() const { state::State intra_state; for (const auto& [addr, acc] : *this) { auto& intra_acc = intra_state.insert( - addr, {.nonce = acc.nonce, .balance = acc.balance, .code = acc.code}); + addr, {.nonce = acc.nonce, .balance = acc.balance, .code = get_account_code(addr)}); auto& storage = intra_acc.storage; for (const auto& [key, value] : acc.storage) storage[key] = {.current = value, .original = value}; @@ -43,6 +63,16 @@ void TestState::apply(const state::StateDiff& diff) erase(addr); } +bytes32 TestState::get_storage(const address& addr, const bytes32& key) const noexcept +{ + const auto ait = find(addr); + if (ait == end()) // TODO: When? + return bytes32{}; + const auto& storage = ait->second.storage; + const auto it = storage.find(key); + return (it != storage.end()) ? it->second : bytes32{}; +} + [[nodiscard]] std::variant transition(TestState& state, const state::BlockInfo& block, const state::Transaction& tx, evmc_revision rev, evmc::VM& vm, int64_t block_gas_left, int64_t blob_gas_left) diff --git a/test/state/test_state.hpp b/test/state/test_state.hpp index 45bf27feb3..6150d54dba 100644 --- a/test/state/test_state.hpp +++ b/test/state/test_state.hpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once +#include "state_view.hpp" #include #include #include @@ -45,11 +46,15 @@ struct TestAccount /// This is a simplified variant of state::State: /// it hides some details related to transaction execution (e.g. original storage values) /// and is also easier to work with in tests. -class TestState : public std::map +class TestState : public state::StateView, public std::map { public: using map::map; + std::optional get_account(const address& addr) const noexcept override; + bytes get_account_code(const address& addr) const noexcept override; + bytes32 get_storage(const address& addr, const bytes32& key) const noexcept override; + /// Inserts new account to the state. /// /// This method is for compatibility with state::State::insert().