Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed May 6, 2022
1 parent 4968453 commit 45fa067
Show file tree
Hide file tree
Showing 4 changed files with 542 additions and 1 deletion.
1 change: 1 addition & 0 deletions test/state/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ add_library(evmone-state INTERFACE)
add_library(evmone::state ALIAS evmone-state)
target_sources(
evmone-state PRIVATE
rlp.hpp
)
117 changes: 117 additions & 0 deletions test/state/rlp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// evmone: Fast Ethereum Virtual Machine implementation
// Copyright 2021 The evmone Authors.
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <intx/intx.hpp>
#include <cassert>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

namespace evmone::rlp
{
using bytes = std::basic_string<uint8_t>;
using bytes_view = std::basic_string_view<uint8_t>;

namespace internal
{
template <uint8_t ShortBase, uint8_t LongBase>
inline bytes encode_length(size_t l)
{
static constexpr auto short_cutoff = 55;
static_assert(ShortBase + short_cutoff <= 0xff);
assert(l <= 0xffffff);

if (l <= short_cutoff)
return {static_cast<uint8_t>(ShortBase + l)};
else if (const auto l0 = static_cast<uint8_t>(l); l <= 0xff)
return {LongBase + 1, l0};
else if (const auto l1 = static_cast<uint8_t>(l >> 8); l <= 0xffff)
return {LongBase + 2, l1, l0};
else
return {LongBase + 3, static_cast<uint8_t>(l >> 16), l1, l0};
}

inline bytes wrap_list(const bytes& content)
{
return internal::encode_length<0xc0, 0xf7>(content.size()) + content;
}

template <typename InputIterator>
inline bytes encode_container(InputIterator begin, InputIterator end);
} // namespace internal

inline bytes_view trim(bytes_view b) noexcept
{
b.remove_prefix(std::min(b.find_first_not_of(uint8_t{0x00}), b.size()));
return b;
}

template <typename T>
inline decltype(rlp_encode(std::declval<T>())) encode(const T& v)
{
return rlp_encode(v);
}

inline bytes encode(bytes_view data)
{
static constexpr uint8_t short_base = 0x80;
if (data.size() == 1 && data[0] < short_base)
return {data[0]};

auto r = internal::encode_length<short_base, 0xb7>(data.size());
r += data;
return r;
}

inline bytes encode(uint64_t x)
{
uint8_t b[sizeof(x)];
intx::be::store(b, x);
return encode(trim({b, sizeof(b)}));
}

inline bytes encode(const intx::uint256& x)
{
uint8_t b[sizeof(x)];
intx::be::store(b, x);
return encode(trim({b, sizeof(b)}));
}

template <typename T>
inline bytes encode(const std::vector<T>& v)
{
return internal::encode_container(v.begin(), v.end());
}

template <typename T, size_t N>
inline bytes encode(const T (&v)[N])
{
return internal::encode_container(std::begin(v), std::end(v));
}

/// Encodes the fixed-size collection of heterogeneous values as RLP list.
template <typename... Types>
inline bytes tuple(const Types&... elements)
{
return internal::wrap_list((encode(elements) + ...));
}

/// Encodes the container as RLP list.
///
/// @tparam InputIterator Type of the input iterator.
/// @param begin Begin iterator.
/// @param end End iterator.
/// @return Bytes of the RLP list.
template <typename InputIterator>
inline bytes internal::encode_container(InputIterator begin, InputIterator end)
{
bytes content;
for (auto it = begin; it != end; ++it)
content += encode(*it);
return wrap_list(content);
}
} // namespace evmone::rlp
3 changes: 2 additions & 1 deletion test/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ add_executable(evmone-unittests
evmone_test.cpp
execution_state_test.cpp
instructions_test.cpp
state_rlp_test.cpp
tracing_test.cpp
utils_test.cpp
)
target_link_libraries(evmone-unittests PRIVATE evmone testutils evmc::instructions GTest::gtest GTest::gtest_main)
target_link_libraries(evmone-unittests PRIVATE evmone evmone::state testutils evmc::instructions GTest::gtest GTest::gtest_main)
target_include_directories(evmone-unittests PRIVATE ${evmone_private_include_dir})

gtest_discover_tests(evmone-unittests TEST_PREFIX ${PROJECT_NAME}/unittests/)
Expand Down
Loading

0 comments on commit 45fa067

Please sign in to comment.