Skip to content

Commit

Permalink
Enable state test deployed code EOF verification
Browse files Browse the repository at this point in the history
  • Loading branch information
rodiazet committed Apr 5, 2023
1 parent e47172d commit 203f41a
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 16 deletions.
1 change: 1 addition & 0 deletions test/statetest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_library(evmone-statetestutils STATIC)
add_library(evmone::statetestutils ALIAS evmone-statetestutils)
target_compile_features(evmone-statetestutils PUBLIC cxx_std_20)
target_link_libraries(evmone-statetestutils PRIVATE evmone::state nlohmann_json::nlohmann_json)
target_include_directories(evmone-statetestutils PRIVATE ${evmone_private_include_dir})
target_sources(
evmone-statetestutils PRIVATE
statetest.hpp
Expand Down
4 changes: 4 additions & 0 deletions test/statetest/statetest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ state::Transaction from_json<state::Transaction>(const json::json& j);

StateTransitionTest load_state_test(std::istream& input);

/// Validates deployed EOF containers before running state test.
/// Throws exception on any invalid EOF in state.
void validate_deployed_code(const state::State& state, evmc_revision rev);

void run_state_test(const StateTransitionTest& test, evmc::VM& vm);

/// Computes the hash of the RLP-encoded list of transaction logs.
Expand Down
27 changes: 27 additions & 0 deletions test/statetest/statetest_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

#include "statetest.hpp"
#include <evmone/eof.hpp>
#include <nlohmann/json.hpp>

namespace evmone::test
Expand Down Expand Up @@ -345,4 +346,30 @@ StateTransitionTest load_state_test(std::istream& input)
{
return json::json::parse(input).get<StateTransitionTest>();
}

void validate_deployed_code(const state::State& state, evmc_revision rev)
{
for (const auto& [addr, acc] : state.get_accounts())
{
if (is_eof_container(acc.code))
{
if (rev >= EVMC_CANCUN)
{
if (const auto result = validate_eof(rev, acc.code);
result != EOFValidationError::success)
{
throw std::invalid_argument(
"EOF container at " + hex0x(addr) +
" is invalid: " + std::string(get_error_message(result)));
}
}
else
{
throw std::invalid_argument("EOF container at " + hex0x(addr) +
" is invalid: " + "starts with 0xEFOO for " +
evmc_revision_to_string(rev));
}
}
}
}
} // namespace evmone::test
17 changes: 1 addition & 16 deletions test/statetest/statetest_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "../state/mpt_hash.hpp"
#include "../state/rlp.hpp"
#include "statetest.hpp"
#include <evmone/eof.hpp>
#include <gtest/gtest.h>

namespace evmone::test
Expand All @@ -26,21 +25,7 @@ void run_state_test(const StateTransitionTest& test, evmc::VM& vm)
const auto tx = test.multi_tx.get(expected.indexes);
auto state = test.pre_state;

// Validate deployed EOF containers before running state test.
// Any invalid EOF in state make the test incorrect.
for (const auto& [addr, acc] : state.get_accounts())
{
if (is_eof_container(acc.code))
{
if (const auto result = validate_eof(rev, acc.code);
result != EOFValidationError::success)
{
throw std::invalid_argument(
"EOF container at " + hex0x(addr) +
" is invalid: " + std::string(get_error_message(result)));
}
}
}
validate_deployed_code(state, rev);

const auto res = state::transition(state, test.block, tx, rev, vm);
if (holds_alternative<state::TransactionReceipt>(res))
Expand Down
99 changes: 99 additions & 0 deletions test/unittests/statetest_loader_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,102 @@ TEST(statetest_loader, load_minimal_test)
EXPECT_EQ(st.cases.size(), 0);
EXPECT_EQ(st.input_labels.size(), 0);
}

TEST(statetest_loader, validate_deployed_code_test)
{
{
std::istringstream s{R"({
"test": {
"_info": {},
"pre": {
"0x104f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x00",
"code" : "0xEF0001010000020001000103000100FEDA",
"nonce" : "0x00",
"storage" : {}
}
},
"transaction": {
"gasPrice": "",
"sender": "",
"to": "",
"data": null,
"gasLimit": "0",
"value": null
},
"post": {
"Cancun" : [
{
"hash" : "0x00",
"indexes" : {
"data" : 0,
"gas" : 0,
"value" : 0
},
"logs" : "",
"txbytes" : ""
}
]
},
"env": {
"currentNumber": "0",
"currentTimestamp": "0",
"currentGasLimit": "0",
"currentCoinbase": ""
}
}
})"};

const StateTransitionTest st = load_state_test(s);

EXPECT_THROW(validate_deployed_code(st.pre_state, st.cases[0].rev), std::invalid_argument);
}

{
std::istringstream s{R"({
"test": {
"_info": {},
"pre": {
"0x104f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x00",
"code" : "0xEF000101000402000100010300000000000000FE",
"nonce" : "0x00",
"storage" : {}
}
},
"transaction": {
"gasPrice": "",
"sender": "",
"to": "",
"data": null,
"gasLimit": "0",
"value": null
},
"post": {
"Shanghai" : [
{
"hash" : "0x00",
"indexes" : {
"data" : 0,
"gas" : 0,
"value" : 0
},
"logs" : "",
"txbytes" : ""
}
]
},
"env": {
"currentNumber": "0",
"currentTimestamp": "0",
"currentGasLimit": "0",
"currentCoinbase": ""
}
}
})"};

const StateTransitionTest st = load_state_test(s);

EXPECT_THROW(validate_deployed_code(st.pre_state, st.cases[0].rev), std::invalid_argument);
}
}

0 comments on commit 203f41a

Please sign in to comment.