diff options
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | TestHelper.cpp | 6 | ||||
-rw-r--r-- | createRandomTest.cpp | 4 | ||||
-rw-r--r-- | vm.cpp | 107 |
4 files changed, 87 insertions, 39 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f292361d..8d8430b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") include_directories(..) +link_directories(../libevm) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) @@ -19,11 +20,19 @@ target_link_libraries(testeth webthree) if(JSONRPC_LS) target_link_libraries(testeth web3jsonrpc) endif() +if (EVMJIT) + target_link_libraries(testeth evm) + target_link_libraries(testeth evmjit) +endif() target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) target_link_libraries(createRandomTest boost_chrono) target_link_libraries(createRandomTest boost_unit_test_framework) +if (EVMJIT) + target_link_libraries(createRandomTest evm) + target_link_libraries(createRandomTest evmjit) +endif() if ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") diff --git a/TestHelper.cpp b/TestHelper.cpp index 114399a4..31696da0 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -285,6 +285,12 @@ void checkStorage(map<u256, u256> _expectedStore, map<u256, u256> _resultStore, BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue); } } + + for (auto&& resultStorePair : _resultStore) + { + if (!_expectedStore.count(resultStorePair.first)) + BOOST_ERROR("unexpected result store key " << resultStorePair.first); + } } std::string getTestPath() diff --git a/createRandomTest.cpp b/createRandomTest.cpp index 60a2039c..f22e5c0a 100644 --- a/createRandomTest.cpp +++ b/createRandomTest.cpp @@ -127,7 +127,9 @@ void doMyTests(json_spirit::mValue& v) assert(o.count("pre") > 0); assert(o.count("exec") > 0); - eth::VM vm; + + auto vmObj = eth::VMFace::create(eth::VMFace::Interpreter); + auto& vm = *vmObj; test::FakeExtVM fev; fev.importEnv(o["env"].get_obj()); fev.importState(o["pre"].get_obj()); @@ -20,9 +20,9 @@ * vm test functions. */ +#include <chrono> #include <boost/filesystem.hpp> #include "vm.h" - using namespace std; using namespace json_spirit; using namespace dev; @@ -282,7 +282,15 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) BOOST_REQUIRE(o.count("pre") > 0); BOOST_REQUIRE(o.count("exec") > 0); + auto argc = boost::unit_test::framework::master_test_suite().argc; + auto argv = boost::unit_test::framework::master_test_suite().argv; + auto useJit = false; + for (auto i = 0; i < argc && !useJit; ++i) + useJit |= std::string(argv[i]) == "--jit"; + auto vmKind = useJit ? VMFace::JIT : VMFace::Interpreter; + dev::test::FakeExtVM fev; + fev.importEnv(o["env"].get_obj()); fev.importState(o["pre"].get_obj()); @@ -296,15 +304,22 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) fev.code = fev.thisTxCode; } + auto vm = VMFace::create(vmKind, fev.gas); bytes output; - VM vm(fev.gas); + auto outOfGas = false; + auto startTime = std::chrono::high_resolution_clock::now(); u256 gas; bool vmExceptionOccured = false; try { - output = vm.go(fev, fev.simpleTrace()).toVector(); - gas = vm.gas(); + output = vm->go(fev, fev.simpleTrace()).toVector(); + gas = vm->gas(); + } + catch (OutOfGas const&) + { + outOfGas = true; + gas = 0; } catch (VMException const& _e) { @@ -322,6 +337,19 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) BOOST_ERROR("Failed VM Test with Exception: " << _e.what()); } + auto endTime = std::chrono::high_resolution_clock::now(); + for (auto i = 0; i < argc; ++i) + { + if (std::string(argv[i]) == "--show-times") + { + auto testDuration = endTime - startTime; + cnote << "Execution time: " + << std::chrono::duration_cast<std::chrono::milliseconds>(testDuration).count() + << " ms"; + break; + } + } + // delete null entries in storage for the sake of comparison for (auto &a: fev.addresses) @@ -345,11 +373,11 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) o["exec"] = mValue(fev.exportExec()); if (!vmExceptionOccured) { - o["post"] = mValue(fev.exportState()); - o["callcreates"] = fev.exportCallCreates(); - o["out"] = "0x" + toHex(output); - fev.push(o, "gas", gas); - } + o["post"] = mValue(fev.exportState()); + o["callcreates"] = fev.exportCallCreates(); + o["out"] = "0x" + toHex(output); + fev.push(o, "gas", gas); + } } else { @@ -357,42 +385,45 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) { BOOST_CHECK(!vmExceptionOccured); - BOOST_REQUIRE(o.count("post") > 0); - BOOST_REQUIRE(o.count("callcreates") > 0); - BOOST_REQUIRE(o.count("out") > 0); - BOOST_REQUIRE(o.count("gas") > 0); + BOOST_REQUIRE(o.count("post") > 0); + BOOST_REQUIRE(o.count("callcreates") > 0); + BOOST_REQUIRE(o.count("out") > 0); + BOOST_REQUIRE(o.count("gas") > 0); - dev::test::FakeExtVM test; - test.importState(o["post"].get_obj()); - test.importCallCreates(o["callcreates"].get_array()); + dev::test::FakeExtVM test; + test.importState(o["post"].get_obj()); + test.importCallCreates(o["callcreates"].get_array()); - checkOutput(output, o); + checkOutput(output, o); - BOOST_CHECK_EQUAL(toInt(o["gas"]), gas); + BOOST_CHECK_EQUAL(toInt(o["gas"]), gas); - auto& expectedAddrs = test.addresses; - auto& resultAddrs = fev.addresses; - for (auto&& expectedPair : expectedAddrs) + if (outOfGas) + BOOST_CHECK_MESSAGE(gas == 0, "Remaining gas not 0 in out-of-gas state"); + + auto& expectedAddrs = test.addresses; + auto& resultAddrs = fev.addresses; + for (auto&& expectedPair : expectedAddrs) + { + auto& expectedAddr = expectedPair.first; + auto resultAddrIt = resultAddrs.find(expectedAddr); + if (resultAddrIt == resultAddrs.end()) + BOOST_ERROR("Missing expected address " << expectedAddr); + else { - auto& expectedAddr = expectedPair.first; - auto resultAddrIt = resultAddrs.find(expectedAddr); - if (resultAddrIt == resultAddrs.end()) - BOOST_ERROR("Missing expected address " << expectedAddr); - else - { - auto& expectedState = expectedPair.second; - auto& resultState = resultAddrIt->second; - BOOST_CHECK_MESSAGE(std::get<0>(expectedState) == std::get<0>(resultState), expectedAddr << ": incorrect balance " << std::get<0>(resultState) << ", expected " << std::get<0>(expectedState)); - BOOST_CHECK_MESSAGE(std::get<1>(expectedState) == std::get<1>(resultState), expectedAddr << ": incorrect txCount " << std::get<1>(resultState) << ", expected " << std::get<1>(expectedState)); - BOOST_CHECK_MESSAGE(std::get<3>(expectedState) == std::get<3>(resultState), expectedAddr << ": incorrect code"); - - checkStorage(std::get<2>(expectedState), std::get<2>(resultState), expectedAddr); - } - } + auto& expectedState = expectedPair.second; + auto& resultState = resultAddrIt->second; + BOOST_CHECK_MESSAGE(std::get<0>(expectedState) == std::get<0>(resultState), expectedAddr << ": incorrect balance " << std::get<0>(resultState) << ", expected " << std::get<0>(expectedState)); + BOOST_CHECK_MESSAGE(std::get<1>(expectedState) == std::get<1>(resultState), expectedAddr << ": incorrect txCount " << std::get<1>(resultState) << ", expected " << std::get<1>(expectedState)); + BOOST_CHECK_MESSAGE(std::get<3>(expectedState) == std::get<3>(resultState), expectedAddr << ": incorrect code"); - checkAddresses<std::map<Address, std::tuple<u256, u256, std::map<u256, u256>, bytes> > >(test.addresses, fev.addresses); - BOOST_CHECK(test.callcreates == fev.callcreates); + checkStorage(std::get<2>(expectedState), std::get<2>(resultState), expectedAddr); + } } + + checkAddresses<std::map<Address, std::tuple<u256, u256, std::map<u256, u256>, bytes> > >(test.addresses, fev.addresses); + BOOST_CHECK(test.callcreates == fev.callcreates); + } else // Exception expected BOOST_CHECK(vmExceptionOccured); } |