-
Notifications
You must be signed in to change notification settings - Fork 278
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Introduce TestState and TestAccount
This decouples the `state::State` for transaction execution from the state object for test definitions and asserts. The `state::State` (also called "intra state") has some constructs and data related to transaction execution only (like "current" and "original" storage values). These should not be exposed to tests and make test definitions more complicated. This separation should also help with adding new public API for EVM with transaction-level execution granularity.
- Loading branch information
Showing
21 changed files
with
369 additions
and
313 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// evmone: Fast Ethereum Virtual Machine implementation | ||
// Copyright 2024 The evmone Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#include "test_state.hpp" | ||
#include "state.hpp" | ||
|
||
namespace evmone::test | ||
{ | ||
TestState::TestState(const state::State& intra_state) | ||
{ | ||
for (const auto& [addr, acc] : intra_state.get_accounts()) | ||
{ | ||
auto& test_acc = | ||
(*this)[addr] = {.nonce = acc.nonce, .balance = acc.balance, .code = acc.code}; | ||
auto& test_storage = test_acc.storage; | ||
for (const auto& [key, value] : acc.storage) | ||
test_storage[key] = value.current; | ||
} | ||
} | ||
|
||
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}); | ||
auto& storage = intra_acc.storage; | ||
for (const auto& [key, value] : acc.storage) | ||
storage[key] = {.current = value, .original = value}; | ||
} | ||
return intra_state; | ||
} | ||
} // namespace evmone::test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// evmone: Fast Ethereum Virtual Machine implementation | ||
// Copyright 2024 The evmone Authors. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#pragma once | ||
|
||
#include <evmc/evmc.hpp> | ||
#include <intx/intx.hpp> | ||
#include <map> | ||
|
||
namespace evmone | ||
{ | ||
namespace state | ||
{ | ||
class State; | ||
} | ||
|
||
namespace test | ||
{ | ||
using evmc::address; | ||
using evmc::bytes; | ||
using evmc::bytes32; | ||
using intx::uint256; | ||
|
||
/// Ethereum account representation for tests. | ||
struct TestAccount | ||
{ | ||
uint64_t nonce = 0; | ||
uint256 balance; | ||
std::map<bytes32, bytes32> storage; | ||
bytes code; | ||
|
||
bool operator==(const TestAccount&) const noexcept = default; | ||
}; | ||
|
||
/// Ethereum State representation for tests. | ||
/// | ||
/// 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<address, TestAccount> | ||
{ | ||
public: | ||
using map::map; | ||
|
||
/// Inserts new account to the state. | ||
/// | ||
/// This method is for compatibility with state::State::insert(). | ||
/// Don't use it in new tests, use std::map interface instead. | ||
/// TODO: deprecate this method. | ||
void insert(const address& addr, TestAccount&& acc) { (*this)[addr] = std::move(acc); } | ||
|
||
/// Gets the reference to an existing account. | ||
/// | ||
/// This method is for compatibility with state::State::get(). | ||
/// Don't use it in new tests, use std::map interface instead. | ||
/// TODO: deprecate this method. | ||
TestAccount& get(const address& addr) { return (*this)[addr]; } | ||
|
||
/// Converts the intra state to TestState. | ||
explicit TestState(const state::State& intra_state); | ||
|
||
/// Converts the TestState to intra state for transaction execution. | ||
[[nodiscard]] state::State to_intra_state() const; | ||
}; | ||
|
||
} // namespace test | ||
} // namespace evmone |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.