TLA Line data Source code
1 : // evmone: Fast Ethereum Virtual Machine implementation
2 : // Copyright 2022 The evmone Authors.
3 : // SPDX-License-Identifier: Apache-2.0
4 : #pragma once
5 :
6 : #include "../state/state.hpp"
7 : #include <nlohmann/json.hpp>
8 :
9 : namespace json = nlohmann;
10 :
11 : namespace evmone::test
12 : {
13 :
14 : struct TestMultiTransaction : state::Transaction
15 : {
16 : struct Indexes
17 : {
18 : size_t input = 0;
19 : size_t gas_limit = 0;
20 : size_t value = 0;
21 : };
22 :
23 : std::vector<state::AccessList> access_lists;
24 : std::vector<bytes> inputs;
25 : std::vector<int64_t> gas_limits;
26 : std::vector<intx::uint256> values;
27 :
28 : [[nodiscard]] Transaction get(const Indexes& indexes) const noexcept
29 : {
30 : Transaction tx{*this};
31 : if (!access_lists.empty())
32 : tx.access_list = access_lists.at(indexes.input);
33 : tx.data = inputs.at(indexes.input);
34 : tx.gas_limit = gas_limits.at(indexes.gas_limit);
35 : tx.value = values.at(indexes.value);
36 : return tx;
37 : }
38 : };
39 :
40 : struct StateTransitionTest
41 : {
42 : struct Case
43 : {
44 : struct Expectation
45 : {
46 : TestMultiTransaction::Indexes indexes;
47 : hash256 state_hash;
48 : hash256 logs_hash = EmptyListHash;
49 : bool exception = false;
50 : };
51 :
52 : evmc_revision rev;
53 : std::vector<Expectation> expectations;
54 : };
55 :
56 : state::State pre_state;
57 : state::BlockInfo block;
58 : TestMultiTransaction multi_tx;
59 : std::vector<Case> cases;
60 : std::unordered_map<uint64_t, std::string> input_labels;
61 : };
62 :
63 : template <typename T>
64 : T from_json(const json::json& j) = delete;
65 :
66 : template <>
67 : uint64_t from_json<uint64_t>(const json::json& j);
68 :
69 : template <>
70 : int64_t from_json<int64_t>(const json::json& j);
71 :
72 : template <>
73 : address from_json<address>(const json::json& j);
74 :
75 : template <>
76 : hash256 from_json<hash256>(const json::json& j);
77 :
78 : template <>
79 : bytes from_json<bytes>(const json::json& j);
80 :
81 : template <>
82 : state::BlockInfo from_json<state::BlockInfo>(const json::json& j);
83 :
84 : template <>
85 : state::Withdrawal from_json<state::Withdrawal>(const json::json& j);
86 :
87 : template <>
88 : state::State from_json<state::State>(const json::json& j);
89 :
90 : template <>
91 : state::Transaction from_json<state::Transaction>(const json::json& j);
92 :
93 : /// Exports the State (accounts) to JSON format (aka pre/post/alloc state).
94 : json::json to_json(const std::unordered_map<address, state::Account>& accounts);
95 :
96 : StateTransitionTest load_state_test(std::istream& input);
97 :
98 : /// Validates an Ethereum state:
99 : /// - checks that there are no zero-value storage entries,
100 : /// - checks that there are no invalid EOF codes.
101 : /// Throws std::invalid_argument exception.
102 : void validate_state(const state::State& state, evmc_revision rev);
103 :
104 : /// Execute the state @p test using the @p vm.
105 : ///
106 : /// @param trace_summary Output execution summary to the default trace stream.
107 : void run_state_test(const StateTransitionTest& test, evmc::VM& vm, bool trace_summary);
108 :
109 : /// Computes the hash of the RLP-encoded list of transaction logs.
110 : /// This method is only used in tests.
111 : hash256 logs_hash(const std::vector<state::Log>& logs);
112 :
113 : /// Converts an integer to hex string representation with 0x prefix.
114 : ///
115 : /// This handles also builtin types like uint64_t. Not optimal but works for now.
116 CBC 848 : inline std::string hex0x(const intx::uint256& v)
117 : {
118 1696 : return "0x" + intx::hex(v);
119 : }
120 :
121 : /// Encodes bytes as hex with 0x prefix.
122 1406 : inline std::string hex0x(const bytes_view& v)
123 : {
124 2812 : return "0x" + evmc::hex(v);
125 : }
126 : } // namespace evmone::test
|