2014-01-19 14:42:02 +00:00
/*
This file is part of cpp - ethereum .
cpp - ethereum is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2014-02-06 18:53:46 +00:00
the Free Software Foundation , either version 3 of the License , or
2014-01-19 14:42:02 +00:00
( at your option ) any later version .
2014-02-16 10:20:55 +00:00
cpp - ethereum is distributed in the hope that it will be useful ,
2014-01-19 14:42:02 +00:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2014-02-16 10:41:15 +00:00
along with cpp - ethereum . If not , see < http : //www.gnu.org/licenses/>.
2014-01-19 14:42:02 +00:00
*/
/** @file state.cpp
2014-10-29 16:25:02 +00:00
* @ author Christoph Jentzsch < cj @ ethdev . com >
2014-01-19 14:42:02 +00:00
* @ date 2014
* State test functions .
*/
2014-02-19 22:16:20 +00:00
# include <boost/filesystem/operations.hpp>
2014-10-29 16:25:02 +00:00
# include <boost/test/unit_test.hpp>
# include "JsonSpiritHeaders.h"
# include <libdevcore/CommonIO.h>
2014-04-23 14:08:11 +00:00
# include <libethereum/BlockChain.h>
# include <libethereum/State.h>
2014-10-29 16:25:02 +00:00
# include <libethereum/ExtVM.h>
2014-04-23 14:08:11 +00:00
# include <libethereum/Defaults.h>
2014-10-29 16:25:02 +00:00
# include <libevm/VM.h>
# include "TestHelper.h"
2014-01-19 14:42:02 +00:00
using namespace std ;
2014-10-29 16:25:02 +00:00
using namespace json_spirit ;
2014-09-05 15:09:58 +00:00
using namespace dev ;
using namespace dev : : eth ;
2014-10-29 16:25:02 +00:00
using namespace dev : : eth : : test ;
2014-01-19 14:42:02 +00:00
2014-10-29 16:25:02 +00:00
class FakeState : public State
2014-01-19 14:42:02 +00:00
{
2014-01-19 20:15:07 +00:00
2014-10-29 16:25:02 +00:00
} ;
2014-01-19 20:15:07 +00:00
2014-01-21 15:51:57 +00:00
2014-10-29 16:25:02 +00:00
namespace dev { namespace eth { namespace test {
2014-01-21 15:51:57 +00:00
2014-01-20 18:43:11 +00:00
2014-10-29 16:25:02 +00:00
void doStateTests ( json_spirit : : mValue & v , bool _fillin )
{
for ( auto & i : v . get_obj ( ) )
{
cnote < < i . first ;
mObject & o = i . second . get_obj ( ) ;
BOOST_REQUIRE ( o . count ( " env " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " pre " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " exec " ) > 0 ) ;
ImportTest importer ( o , false ) ;
ExtVM evm ( importer . m_statePre , importer . m_environment . myAddress ,
importer . m_environment . caller , importer . m_environment . origin ,
importer . m_environment . value , importer . m_environment . gasPrice ,
importer . m_environment . data , importer . m_environment . code ,
importer . getManifest ( ) ) ;
bytes output ;
VM vm ( importer . gasExec ) ;
try
{
output = vm . go ( evm , Executive : : simpleTrace ( ) ) . toVector ( ) ;
}
catch ( Exception const & _e )
{
cnote < < " VM did throw an exception: " < < diagnostic_information ( _e ) ;
//BOOST_ERROR("Failed VM Test with Exception: " << e.what());
}
catch ( std : : exception const & _e )
{
cnote < < " VM did throw an exception: " < < _e . what ( ) ;
//BOOST_ERROR("Failed VM Test with Exception: " << e.what());
}
BOOST_REQUIRE ( o . count ( " post " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " callcreates " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " out " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " gas " ) > 0 ) ;
// check output
//dev::test::FakeExtVM test;
//test.importState(o["post"].get_obj());
//test.importCallCreates(o["callcreates"].get_array());
int j = 0 ;
if ( o [ " out " ] . type ( ) = = array_type )
for ( auto const & d : o [ " out " ] . get_array ( ) )
{
BOOST_CHECK_MESSAGE ( output [ j ] = = toInt ( d ) , " Output byte [ " < < j < < " ] different! " ) ;
+ + j ;
}
else if ( o [ " out " ] . get_str ( ) . find ( " 0x " ) = = 0 )
BOOST_CHECK ( output = = fromHex ( o [ " out " ] . get_str ( ) . substr ( 2 ) ) ) ;
else
BOOST_CHECK ( output = = fromHex ( o [ " out " ] . get_str ( ) ) ) ;
cout < < " gas check: " < < importer . gas < < " " < < toInt ( o [ " gas " ] ) < < " " < < vm . gas ( ) < < endl ;
BOOST_CHECK_EQUAL ( toInt ( o [ " gas " ] ) , vm . gas ( ) ) ;
// 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& 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");
// auto&& expectedStore = std::get<2>(expectedState);
// auto&& resultStore = std::get<2>(resultState);
// for (auto&& expectedStorePair : expectedStore)
// {
// auto& expectedStoreKey = expectedStorePair.first;
// auto resultStoreIt = resultStore.find(expectedStoreKey);
// if (resultStoreIt == resultStore.end())
// BOOST_ERROR(expectedAddr << ": missing store key " << expectedStoreKey);
// else
// {
// auto& expectedStoreValue = expectedStorePair.second;
// auto& resultStoreValue = resultStoreIt->second;
// BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue);
// }
// }
// }
// }
BOOST_CHECK ( evm . state ( ) . addresses ( ) = = importer . m_statePost . addresses ( ) ) ; // Just to make sure nothing missed
//BOOST_CHECK(evm.callcreates == importer.callcreates);
2014-01-21 15:51:57 +00:00
2014-10-29 16:25:02 +00:00
}
}
2014-01-21 15:51:57 +00:00
2014-01-19 20:15:07 +00:00
2014-10-29 16:25:02 +00:00
void executeStateTests ( const string & _name )
{
const char * ptestPath = getenv ( " ETHEREUM_TEST_PATH " ) ;
string testPath ;
2014-01-20 18:43:11 +00:00
2014-10-29 16:25:02 +00:00
if ( ptestPath = = NULL )
2014-01-19 20:15:07 +00:00
{
2014-10-29 16:25:02 +00:00
cnote < < " could not find environment variable ETHEREUM_TEST_PATH \n " ;
testPath = " ../../../tests " ;
2014-01-19 20:15:07 +00:00
}
2014-10-29 16:25:02 +00:00
else
testPath = ptestPath ;
2014-01-19 20:15:07 +00:00
2014-10-29 16:25:02 +00:00
testPath + = " /vmtests " ;
2014-01-20 18:43:11 +00:00
2014-10-29 16:25:02 +00:00
# ifdef FILL_TESTS
try
{
cnote < < " Populating VM tests... " ;
json_spirit : : mValue v ;
boost : : filesystem : : path p ( __FILE__ ) ;
boost : : filesystem : : path dir = p . parent_path ( ) ;
string s = asString ( dev : : contents ( dir . string ( ) + " / " + _name + " Filler.json " ) ) ;
BOOST_REQUIRE_MESSAGE ( s . length ( ) > 0 , " Contents of " + _name + " Filler.json is empty. " ) ;
json_spirit : : read_string ( s , v ) ;
dev : : test : : doStateTests ( v , true ) ;
writeFile ( testPath + " / " + _name + " .json " , asBytes ( json_spirit : : write_string ( v , true ) ) ) ;
}
catch ( Exception const & _e )
{
BOOST_ERROR ( " Failed VM Test with Exception: " < < diagnostic_information ( _e ) ) ;
}
catch ( std : : exception const & _e )
{
BOOST_ERROR ( " Failed VM Test with Exception: " < < _e . what ( ) ) ;
}
# endif
2014-01-21 15:51:57 +00:00
2014-10-29 16:25:02 +00:00
try
{
cnote < < " Testing VM... " < < _name ;
json_spirit : : mValue v ;
string s = asString ( dev : : contents ( testPath + " / " + _name + " .json " ) ) ;
BOOST_REQUIRE_MESSAGE ( s . length ( ) > 0 , " Contents of " + testPath + " / " + _name + " .json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path? " ) ;
json_spirit : : read_string ( s , v ) ;
doStateTests ( v , false ) ;
}
catch ( Exception const & _e )
{
BOOST_ERROR ( " Failed VM Test with Exception: " < < diagnostic_information ( _e ) ) ;
}
catch ( std : : exception const & _e )
{
BOOST_ERROR ( " Failed VM Test with Exception: " < < _e . what ( ) ) ;
}
2014-01-21 15:51:57 +00:00
2014-10-29 16:25:02 +00:00
}
} } } // Namespace Close
2014-01-19 17:17:05 +00:00
2014-01-20 18:43:11 +00:00
2014-10-29 16:25:02 +00:00
BOOST_AUTO_TEST_CASE ( vmSystemOperationsTest )
{
std : : cout < < " Doing systemoperationsTest in state \n " ;
int currentVerbosity = g_logVerbosity ;
g_logVerbosity = 12 ;
dev : : eth : : test : : executeStateTests ( " vmSystemOperationsTest " ) ;
g_logVerbosity = currentVerbosity ;
2014-01-19 14:42:02 +00:00
}
2014-10-29 16:25:02 +00:00
//BOOST_AUTO_TEST_CASE(tmp)
//{
// std::cout << "Doing systemoperationsTest in state\n";
// int currentVerbosity = g_logVerbosity;
// g_logVerbosity = 12;
// dev::eth::test::executeStateTests("tmp");
// g_logVerbosity = currentVerbosity;
//}