Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New evmone API: StateView & StateDiff #802

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

chfast
Copy link
Member

@chfast chfast commented Jan 31, 2024

A step towards of the new API for evmone. It uses the test runners as users and modifies the State API from state.h.

  • the user provides read-only StateView interface with (simpler than State) representation of the State.
  • the transaction execution (i.e. evmone via transition()) takes the StateView and produces StateDiff.
  • user must apply the StateDiff to its StateView implementation.

The current state diff building is based on visiting the intra state cache of accounts loaded from initial state. This approach is relatively simple but has some false positives and may not be efficient.

Copy link

codecov bot commented Feb 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.23%. Comparing base (46dc5ee) to head (da4cd30).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #802      +/-   ##
==========================================
+ Coverage   94.21%   94.23%   +0.01%     
==========================================
  Files         153      155       +2     
  Lines       15933    15967      +34     
==========================================
+ Hits        15011    15046      +35     
+ Misses        922      921       -1     
Flag Coverage Δ
eof_execution_spec_tests 17.69% <93.10%> (+0.15%) ⬆️
ethereum_tests 27.49% <100.00%> (+0.15%) ⬆️
ethereum_tests_silkpre 19.35% <93.39%> (+0.20%) ⬆️
execution_spec_tests 20.61% <98.27%> (+0.15%) ⬆️
unittests 89.02% <98.27%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
test/state/account.hpp 100.00% <100.00%> (ø)
test/state/host.cpp 100.00% <100.00%> (ø)
test/state/state.cpp 100.00% <100.00%> (ø)
test/state/state.hpp 100.00% <100.00%> (ø)
test/state/state_diff.hpp 100.00% <100.00%> (ø)
test/state/state_view.hpp 100.00% <100.00%> (ø)
test/state/system_contracts.cpp 100.00% <100.00%> (ø)
test/state/test_state.cpp 100.00% <100.00%> (ø)
test/state/test_state.hpp 88.88% <100.00%> (+8.88%) ⬆️
test/state/transaction.hpp 100.00% <ø> (ø)

@chfast chfast force-pushed the state/state_view branch 3 times, most recently from 1ea121a to 3f608b1 Compare February 2, 2024 14:07
@chfast chfast force-pushed the state/state_view branch 3 times, most recently from d77ecd8 to 83342e2 Compare February 6, 2024 10:34
@chfast chfast force-pushed the state/state_view branch 2 times, most recently from 0028573 to 1bab196 Compare August 30, 2024 13:33
@chfast chfast self-assigned this Sep 9, 2024
@chfast chfast force-pushed the state/state_view branch 3 times, most recently from e4e3eb4 to 838a5cf Compare September 16, 2024 10:01
@chfast chfast changed the title New API prototype: StateView New evmone API: StateView & StateDiff Sep 16, 2024
@chfast chfast marked this pull request as ready for review September 16, 2024 10:27
}

bytes32 Host::get_code_hash(const address& addr) const noexcept
{
// TODO: Cache code hash. It will be needed also to compute the MPT hash.
const auto raw_code = m_state.get_code(addr);
if (is_eof_container(raw_code))
return keccak256(raw_code.substr(0, 2));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably good idea to handle EOF ext code and possible code hash caching up front.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposed in #1035.

test/state/state.cpp Outdated Show resolved Hide resolved
test/state/state.cpp Outdated Show resolved Hide resolved
test/t8n/t8n.cpp Outdated Show resolved Hide resolved
test/state/state_view.hpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@pdobacz pdobacz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to wrap head around this, but here some early comments

@@ -92,37 +89,45 @@ bytes_view extcode(bytes_view code) noexcept
/// as defined in the [EIP-7610](https://eips.ethereum.org/EIPS/eip-7610).
[[nodiscard]] bool is_create_collision(const Account& acc) noexcept
{
if (acc.nonce != 0 || !acc.code.empty())
// TODO: This requires much more testing:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better file as issue(s)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -62,14 +63,16 @@ class State
std::variant<JournalBalanceChange, JournalTouched, JournalStorageChange, JournalNonceBump,
JournalCreate, JournalTransientStorageChange, JournalDestruct, JournalAccessAccount>;

const StateView* m_cold = nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment pls what this means, making sure to answer its relation to the notion of cold/warm storage (access lists and whatnot). I kinda know but would appreciate the comment to make sure and make it easier to digest.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maybe rename this and m_accounts: m_initial_state and m_modified_accounts maybe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "initial" and "modified" sounds nice. How about just m_initial and m_modified?

{
State ss{state};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe to early to nitpick, but the StateView instance is usually sv

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These names are because of the prototype quality. My proposal for every place:

StateView state_view;
State intra_state;
TestState test_state;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, not so much of this is left so I'll change just this instance.

chfast added a commit that referenced this pull request Sep 18, 2024
Wrap the usage of the state transition API from the `evmone::state`
for tests so that the new API in `evmone::test` only exposes
`TestState` and hides `state::State`.

This isolates usage of the `evmone::state` to lower the disturbance
caused by API modifications,
e.g. in #802.
chfast added a commit that referenced this pull request Sep 18, 2024
Wrap the usage of the state transition API from the `evmone::state`
for tests so that the new API in `evmone::test` only exposes
`TestState` and hides `state::State`.

This isolates usage of the `evmone::state` to lower the disturbance
caused by API modifications,
e.g. in #802.
chfast added a commit that referenced this pull request Sep 18, 2024
Wrap the usage of the state transition API from the `evmone::state`
for tests so that the new API in `evmone::test` only exposes
`TestState` and hides `state::State`.

This isolates usage of the `evmone::state` to lower the disturbance
caused by API modifications,
e.g. in #802.
chfast added a commit that referenced this pull request Sep 23, 2024
Wrap the usage of the state transition API from the `evmone::state`
for tests so that the new API in `evmone::test` only exposes
`TestState` and hides `state::State`.

This isolates usage of the `evmone::state` to lower the disturbance
caused by API modifications,
e.g. in #802.
chfast added a commit that referenced this pull request Sep 24, 2024
Wrap the usage of the state transition API from the `evmone::state`
for tests so that the new API in `evmone::test` only exposes
`TestState` and hides `state::State`.

This isolates usage of the `evmone::state` to lower the disturbance
caused by API modifications,
e.g. in #802.
chfast added a commit that referenced this pull request Sep 24, 2024
Wrap the usage of the state transition API from the `evmone::state` for
tests so that the new API in `evmone::test` only exposes `TestState` and
hides `state::State`.

This isolates usage of the `evmone::state` to lower the disturbance
caused by API modifications,
e.g. in #802.
test/state/state.hpp Outdated Show resolved Hide resolved
test/state/account.hpp Outdated Show resolved Hide resolved
@chfast
Copy link
Member Author

chfast commented Sep 25, 2024

@chfast chfast force-pushed the state/state_view branch 2 times, most recently from 954d0ec to 97aaffa Compare September 27, 2024 15:38
@@ -107,6 +149,18 @@ Account& State::get_or_insert(const address& addr, Account account)
return insert(addr, std::move(account));
}

bytes_view State::get_code(const address& addr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be const method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. We potentially load an account and/or its code from initial state.

if (std::ranges::any_of(
acc.storage, [](auto& e) noexcept { return !is_zero(e.second.current); }))
if (acc.code_hash != Account::EMPTY_CODE_HASH)
return true;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not covered by any tests, so more work for #1037. Should I remove/shorten the TODO comments here?

test/t8n/t8n.cpp Outdated Show resolved Hide resolved
Introduce the type `StateDiff` to represent a set of modifications
to the State. Implement the procedure to collect the set of changes
out of an intra state object.
Implement `TestState::appy(StateDiff)` procedure to apply state changes
back to the state.
Return `StateDiff` out of:
- `state::transition()` (as a subobject of `TransactionReceipt`)
- `state::system_call()`
- `state::finalize()`
Introduce `StateView` interface as a way to read the initial/cold State.
Implement `StateView` interface in `TestState`. This will be used later.
Modify the `State` to require `StateView` interface as a parameter
and use it to read the initial state values.

This drops `TestState` dependency on `State`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants