diff --git a/test/statetest/statetest.hpp b/test/statetest/statetest.hpp index 29a4ecf1c9..f6808b4cff 100644 --- a/test/statetest/statetest.hpp +++ b/test/statetest/statetest.hpp @@ -68,6 +68,12 @@ struct StateTransitionTest template T from_json(const json::json& j) = delete; +template <> +uint64_t from_json(const json::json& j); + +template <> +int64_t from_json(const json::json& j); + template <> state::BlockInfo from_json(const json::json& j); diff --git a/test/statetest/statetest_loader.cpp b/test/statetest/statetest_loader.cpp index 83997c316d..6c21f89364 100644 --- a/test/statetest/statetest_loader.cpp +++ b/test/statetest/statetest_loader.cpp @@ -23,13 +23,23 @@ uint8_t from_json(const json::json& j) template <> int64_t from_json(const json::json& j) { - return static_cast(std::stoll(j.get(), nullptr, 16)); + if (j.is_number_integer()) + return j.get(); + else if (j.is_string()) + return std::stoll(j.get(), nullptr, 0); + else + throw std::invalid_argument("from_json: must be string or number"); } template <> uint64_t from_json(const json::json& j) { - return static_cast(std::stoull(j.get(), nullptr, 16)); + if (j.is_number_integer()) + return j.get(); + else if (j.is_string()) + return std::stoull(j.get(), nullptr, 0); + else + throw std::invalid_argument("from_json: must be string or number"); } template <> diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt index 24461911d1..37ef6ca117 100644 --- a/test/unittests/CMakeLists.txt +++ b/test/unittests/CMakeLists.txt @@ -31,6 +31,7 @@ target_sources( evmone_test.cpp execution_state_test.cpp instructions_test.cpp + json_loader_test.cpp state_bloom_filter_test.cpp state_mpt_hash_test.cpp state_mpt_test.cpp diff --git a/test/unittests/json_loader_test.cpp b/test/unittests/json_loader_test.cpp new file mode 100644 index 0000000000..b853998bc7 --- /dev/null +++ b/test/unittests/json_loader_test.cpp @@ -0,0 +1,57 @@ +// evmone: Fast Ethereum Virtual Machine implementation +// Copyright 2023 The evmone Authors. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +using namespace evmone; + +TEST(json_loader, uint64_t) +{ + EXPECT_EQ(test::from_json(json::basic_json("0x00000005")), 5); + EXPECT_EQ(test::from_json(json::basic_json("5")), 5); + EXPECT_EQ(test::from_json(json::basic_json(7)), 7); + + EXPECT_EQ(test::from_json(json::basic_json("0xffffffffffffffff")), + std::numeric_limits::max()); + EXPECT_EQ(test::from_json(json::basic_json("18446744073709551615")), + std::numeric_limits::max()); + EXPECT_THROW( + test::from_json(json::basic_json("0x10000000000000000")), std::out_of_range); + EXPECT_THROW( + test::from_json(json::basic_json("18446744073709551616")), std::out_of_range); + EXPECT_EQ(test::from_json(json::basic_json(0xffffffffffffffff)), + std::numeric_limits::max()); + + // TODO: Isn't it a little strange behaviour of std::stoull? + EXPECT_EQ(test::from_json(json::basic_json("0x000000000000000k")), 0); + EXPECT_THROW(test::from_json(json::basic_json("k")), std::invalid_argument); +} + +TEST(json_loader, int64_t) +{ + EXPECT_EQ(test::from_json(json::basic_json("0x00000005")), 5); + EXPECT_EQ(test::from_json(json::basic_json("-0x5")), -5); + EXPECT_EQ(test::from_json(json::basic_json("-5")), -5); + + EXPECT_EQ(test::from_json(json::basic_json(-7)), -7); + EXPECT_EQ(test::from_json(json::basic_json(0xffffffffffffffff)), -1); + + EXPECT_EQ(test::from_json(json::basic_json("0x7fffffffffffffff")), + std::numeric_limits::max()); + EXPECT_EQ(test::from_json(json::basic_json("9223372036854775807")), + std::numeric_limits::max()); + EXPECT_EQ(test::from_json(json::basic_json("-9223372036854775808")), + std::numeric_limits::min()); + EXPECT_THROW( + test::from_json(json::basic_json("0xffffffffffffffff")), std::out_of_range); + EXPECT_THROW( + test::from_json(json::basic_json("9223372036854775808")), std::out_of_range); + EXPECT_THROW( + test::from_json(json::basic_json("-9223372036854775809")), std::out_of_range); + + // TODO: Isn't it a little strange behaviour of std::stoull? + EXPECT_EQ(test::from_json(json::basic_json("0x000000000000000k")), 0); + EXPECT_THROW(test::from_json(json::basic_json("k")), std::invalid_argument); +} diff --git a/test/unittests/statetest_loader_block_info_test.cpp b/test/unittests/statetest_loader_block_info_test.cpp index 9c44642598..09c2cb4b11 100644 --- a/test/unittests/statetest_loader_block_info_test.cpp +++ b/test/unittests/statetest_loader_block_info_test.cpp @@ -23,7 +23,7 @@ TEST(statetest_loader, block_info) const auto bi = test::from_json(json::json::parse(input)); EXPECT_EQ(bi.coinbase, 0x1111111111111111111111111111111111111111_address); EXPECT_EQ( - bi.prev_randao, 0x0000000000000000000000000000000000000000000000000000000000000000_bytes32); + bi.prev_randao, 0x00_bytes32); EXPECT_EQ(bi.gas_limit, 0x0); EXPECT_EQ(bi.base_fee, 7); EXPECT_EQ(bi.timestamp, 0); @@ -55,7 +55,7 @@ TEST(statetest_loader, block_info_hex) const auto bi = test::from_json(json::json::parse(input)); EXPECT_EQ(bi.coinbase, 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba_address); EXPECT_EQ( - bi.prev_randao, 0x0000000000000000000000000000000000000000000000000000000000000000_bytes32); + bi.prev_randao, 0x00_bytes32); EXPECT_EQ(bi.gas_limit, 100000000000000000); EXPECT_EQ(bi.base_fee, 7); EXPECT_EQ(bi.timestamp, 1000); @@ -87,7 +87,7 @@ TEST(statetest_loader, block_info_dec) const auto bi = test::from_json(json::json::parse(input)); EXPECT_EQ(bi.coinbase, 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba_address); EXPECT_EQ( - bi.prev_randao, 0x0000000000000000000000000000000000000000000000000000000000000000_bytes32); + bi.prev_randao, 0x00_bytes32); EXPECT_EQ(bi.gas_limit, 100000000000000000); EXPECT_EQ(bi.base_fee, 7); EXPECT_EQ(bi.timestamp, 1000); @@ -110,7 +110,7 @@ TEST(statetest_loader, block_info_0_random) const auto bi = test::from_json(json::json::parse(input)); EXPECT_EQ(bi.coinbase, 0x1111111111111111111111111111111111111111_address); EXPECT_EQ( - bi.prev_randao, 0x0000000000000000000000000000000000000000000000000000000000000000_bytes32); + bi.prev_randao, 0x00_bytes32); EXPECT_EQ(bi.gas_limit, 0x0); EXPECT_EQ(bi.base_fee, 7); EXPECT_EQ(bi.timestamp, 0); diff --git a/test/unittests/statetest_loader_tx_test.cpp b/test/unittests/statetest_loader_tx_test.cpp index fdad282f6f..07a1c50526 100644 --- a/test/unittests/statetest_loader_tx_test.cpp +++ b/test/unittests/statetest_loader_tx_test.cpp @@ -15,7 +15,7 @@ TEST(statetest_loader, tx_create_legacy) { constexpr std::string_view input = R"({ "input": "b0b1", - "gas": "9091", + "gas": "0x9091", "value": "0xe0e1", "sender": "a0a1", "to": "", @@ -46,7 +46,7 @@ TEST(statetest_loader, tx_eip1559) { constexpr std::string_view input = R"({ "input": "b0b1", - "gas": "9091", + "gas": "0x9091", "value": "0xe0e1", "sender": "a0a1", "to": "c0c1",