Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@
[submodule "third_party/cthash"]
path = third_party/cthash
url = https://github.com/hanickadot/cthash.git
[submodule "third_party/immer"]
path = third_party/immer
url = https://github.com/arximboldi/immer.git
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ add_subdirectory("third_party/cthash")
set(ETHASH_TESTING NO)
add_subdirectory("third_party/ethash")

# immer
add_library(immer INTERFACE)
target_include_directories(immer INTERFACE "third_party/immer")

# intx
add_subdirectory("third_party/intx")

Expand Down
14 changes: 14 additions & 0 deletions category/core/bytes_hash_compare.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,18 @@ struct BytesHashCompare
}
};

// An avalanching hasher, for use by ankerl unordered maps. The avalanching
// field tells ankerl the hash output is high quality and doesn't require an
// extra mixing step.
template <class Bytes>
struct BytesHashAvalanching
{
using is_avalanching = void;

auto operator()(Bytes const &a) const noexcept -> uint64_t
{
return komihash(a.bytes, sizeof(Bytes), 0);
}
};

MONAD_NAMESPACE_END
24 changes: 24 additions & 0 deletions category/execution/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ target_link_libraries(
PRIVATE PkgConfig::crypto++
PUBLIC ethash::keccak
PUBLIC evmc
PUBLIC immer
PUBLIC intx::intx
PUBLIC nlohmann_json::nlohmann_json
PUBLIC quill::quill
Expand All @@ -295,6 +296,29 @@ target_link_libraries(
PUBLIC TBB::tbb)
monad_compile_options(monad_execution_ethereum)

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(IMMER_CPP_DISABLED_WARNINGS
-Wno-unused-parameter
-Wno-extended-offsetof
-Wno-c++17-extensions
-Wno-sign-conversion
-Wno-shorten-64-to-32
-Wno-deprecated-declarations
-Wno-c++1z-extensions
-Wno-unknown-warning-option
-Wno-type-limits
)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(IMMER_CPP_DISABLED_WARNINGS
-Wno-array-bounds
-Wno-unused-parameter
-Wno-deprecated-declarations
-Wno-type-limits
-Wno-conversion
)
endif()
target_compile_options(immer INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:${IMMER_CPP_DISABLED_WARNINGS}>")

target_link_options(monad_execution_ethereum PRIVATE LINKER:-z,defs)

target_link_libraries(
Expand Down
4 changes: 3 additions & 1 deletion category/execution/ethereum/state2/block_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ bool BlockState::can_merge(State &state) const

void BlockState::merge(State const &state)
{
ankerl::unordered_dense::segmented_set<bytes32_t> code_hashes;
ankerl::unordered_dense::
segmented_set<bytes32_t, BytesHashAvalanching<bytes32_t>>
code_hashes;

auto const &current = state.current();
for (auto const &[address, stack] : current) {
Expand Down
1 change: 1 addition & 0 deletions category/execution/ethereum/state2/block_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#pragma once

#include <category/core/bytes.hpp>
#include <category/core/bytes_hash_compare.hpp>
#include <category/core/config.hpp>
#include <category/execution/ethereum/core/block.hpp>
#include <category/execution/ethereum/core/receipt.hpp>
Expand Down
4 changes: 2 additions & 2 deletions category/execution/ethereum/state3/account_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ evmc_storage_status AccountState::zero_out_key(
return EVMC_STORAGE_MODIFIED_DELETED;
}();

storage_[key] = bytes32_t{};
storage_ = storage_.insert({key, bytes32_t{}});

return status;
}
Expand Down Expand Up @@ -67,7 +67,7 @@ evmc_storage_status AccountState::set_current_value(
return EVMC_STORAGE_ASSIGNED;
}();

storage_[key] = value;
storage_ = storage_.insert({key, value});

return status;
}
Expand Down
25 changes: 13 additions & 12 deletions category/execution/ethereum/state3/account_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@

#include <category/core/assert.h>
#include <category/core/bytes.hpp>
#include <category/core/bytes_hash_compare.hpp>
#include <category/core/config.hpp>
#include <category/core/int.hpp>
#include <category/core/likely.h>
#include <category/execution/ethereum/core/account.hpp>
#include <category/execution/ethereum/state3/account_substate.hpp>

#include <evmc/evmc.h>

#include <immer/map.hpp>
#include <intx/intx.hpp>

#include <ankerl/unordered_dense.h>

#include <cstdint>
#include <optional>
#include <utility>
Expand All @@ -38,8 +37,8 @@ MONAD_NAMESPACE_BEGIN
class AccountState : public AccountSubstate
{
public: // TODO
template <class Key, class T>
using Map = ankerl::unordered_dense::segmented_map<Key, T>;
template <class K, class V>
using Map = immer::map<K, V, BytesHashAvalanching<K>>;

std::optional<Account> account_{};
Map<bytes32_t, bytes32_t> storage_{};
Expand Down Expand Up @@ -71,9 +70,9 @@ class AccountState : public AccountSubstate

bytes32_t get_transient_storage(bytes32_t const &key) const
{
auto const it = transient_storage_.find(key);
if (MONAD_LIKELY(it != transient_storage_.end())) {
return it->second;
auto *const it = transient_storage_.find(key);
if (MONAD_LIKELY(it != nullptr)) {
return *it;
}
return {};
}
Expand All @@ -84,9 +83,9 @@ class AccountState : public AccountSubstate
{
bytes32_t current_value = original_value;
{
auto const it = storage_.find(key);
if (it != storage_.end()) {
current_value = it->second;
auto *const it = storage_.find(key);
if (it != nullptr) {
current_value = *it;
}
}
if (value == bytes32_t{}) {
Expand All @@ -97,10 +96,12 @@ class AccountState : public AccountSubstate

void set_transient_storage(bytes32_t const &key, bytes32_t const &value)
{
transient_storage_[key] = value;
transient_storage_ = transient_storage_.insert({key, value});
}
};

static_assert(sizeof(AccountState) == 144);

// RELAXED MERGE
// track the min original balance needed at start of transaction and if the
// original and current balances can be adjusted
Expand Down
17 changes: 9 additions & 8 deletions category/execution/ethereum/state3/account_substate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,23 @@
#pragma once

#include <category/core/bytes.hpp>
#include <category/core/bytes_hash_compare.hpp>
#include <category/core/config.hpp>

#include <evmc/evmc.h>

#include <ankerl/unordered_dense.h>
#include <immer/set.hpp>

MONAD_NAMESPACE_BEGIN

// YP 6.1
class AccountSubstate
{
template <class Key>
using Set = ankerl::unordered_dense::set<Key>;
using Set = immer::set<bytes32_t, BytesHashAvalanching<bytes32_t>>;

bool destructed_{false}; // A_s
bool touched_{false}; // A_t
bool accessed_{false}; // A_a
Set<bytes32_t> accessed_storage_{}; // A_K
Set accessed_storage_{}; // A_K

public:
AccountSubstate() = default;
Expand All @@ -55,7 +54,7 @@ class AccountSubstate
}

// A_K
Set<bytes32_t> const &get_accessed_storage() const
Set get_accessed_storage() const
{
return accessed_storage_;
}
Expand Down Expand Up @@ -88,12 +87,14 @@ class AccountSubstate
// A_K
evmc_access_status access_storage(bytes32_t const &key)
{
bool const inserted = accessed_storage_.emplace(key).second;
if (inserted) {
if (accessed_storage_.count(key) == 0) {
accessed_storage_ = accessed_storage_.insert(key);
return EVMC_ACCESS_COLD;
}
return EVMC_ACCESS_WARM;
}
};

static_assert(sizeof(AccountSubstate) == 24);

MONAD_NAMESPACE_END
Loading
Loading