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>
2015-02-09 16:31:04 +00:00
2014-10-29 16:25:02 +00:00
# include "JsonSpiritHeaders.h"
# include <libdevcore/CommonIO.h>
2015-02-04 18:29:56 +00:00
# include <libethereum/CanonBlockChain.h>
2014-04-23 14:08:11 +00:00
# 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-01-21 15:51:57 +00:00
2014-11-03 15:33:02 +00:00
namespace dev { namespace test {
2014-01-21 15:51:57 +00:00
2014-10-29 16:25:02 +00:00
void doStateTests ( json_spirit : : mValue & v , bool _fillin )
{
2015-03-12 10:55:00 +00:00
Options : : get ( ) ; // process command line options
2014-12-12 10:48:15 +00:00
2014-10-29 16:25:02 +00:00
for ( auto & i : v . get_obj ( ) )
{
2014-12-12 16:22:32 +00:00
cerr < < i . first < < endl ;
2014-10-29 16:25:02 +00:00
mObject & o = i . second . get_obj ( ) ;
BOOST_REQUIRE ( o . count ( " env " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " pre " ) > 0 ) ;
2014-11-03 15:33:02 +00:00
BOOST_REQUIRE ( o . count ( " transaction " ) > 0 ) ;
2014-10-29 16:25:02 +00:00
2014-11-03 16:53:29 +00:00
ImportTest importer ( o , _fillin ) ;
2014-10-31 08:41:02 +00:00
2014-11-03 15:33:02 +00:00
State theState = importer . m_statePre ;
bytes tx = importer . m_transaction . rlp ( ) ;
2014-10-29 16:25:02 +00:00
bytes output ;
2014-11-03 15:33:02 +00:00
2014-10-29 16:25:02 +00:00
try
{
2015-01-06 19:57:33 +00:00
theState . execute ( lastHashes ( importer . m_environment . currentBlock . number ) , tx , & output ) ;
2014-10-29 16:25:02 +00:00
}
catch ( Exception const & _e )
{
2014-11-03 15:33:02 +00:00
cnote < < " state execution did throw an exception: " < < diagnostic_information ( _e ) ;
2015-03-03 16:36:09 +00:00
theState . commit ( ) ;
2014-10-29 16:25:02 +00:00
}
catch ( std : : exception const & _e )
{
2014-11-03 15:33:02 +00:00
cnote < < " state execution did throw an exception: " < < _e . what ( ) ;
2014-10-29 16:25:02 +00:00
}
2014-10-31 08:41:02 +00:00
if ( _fillin )
2015-03-02 19:45:42 +00:00
{
# if ETH_FATDB
2014-11-03 15:33:02 +00:00
importer . exportTest ( output , theState ) ;
2015-03-02 19:45:42 +00:00
# else
BOOST_THROW_EXCEPTION ( Exception ( ) < < errinfo_comment ( " You can not fill tests when FATDB is switched off " ) ) ;
# endif
}
2014-10-31 08:41:02 +00:00
else
{
BOOST_REQUIRE ( o . count ( " post " ) > 0 ) ;
BOOST_REQUIRE ( o . count ( " out " ) > 0 ) ;
// check output
2014-11-03 15:33:02 +00:00
checkOutput ( output , o ) ;
2014-10-31 08:41:02 +00:00
2014-12-01 21:44:31 +00:00
// check logs
checkLog ( theState . pending ( ) . size ( ) ? theState . log ( 0 ) : LogEntries ( ) , importer . m_environment . sub . logs ) ;
2014-12-01 21:04:09 +00:00
2014-11-03 15:33:02 +00:00
// check addresses
2015-03-02 19:45:42 +00:00
# if ETH_FATDB
2014-10-31 08:41:02 +00:00
auto expectedAddrs = importer . m_statePost . addresses ( ) ;
2014-11-03 15:33:02 +00:00
auto resultAddrs = theState . addresses ( ) ;
2014-10-31 08:41:02 +00:00
for ( auto & expectedPair : expectedAddrs )
{
auto & expectedAddr = expectedPair . first ;
auto resultAddrIt = resultAddrs . find ( expectedAddr ) ;
if ( resultAddrIt = = resultAddrs . end ( ) )
BOOST_ERROR ( " Missing expected address " < < expectedAddr ) ;
else
{
2014-11-03 15:33:02 +00:00
BOOST_CHECK_MESSAGE ( importer . m_statePost . balance ( expectedAddr ) = = theState . balance ( expectedAddr ) , expectedAddr < < " : incorrect balance " < < theState . balance ( expectedAddr ) < < " , expected " < < importer . m_statePost . balance ( expectedAddr ) ) ;
BOOST_CHECK_MESSAGE ( importer . m_statePost . transactionsFrom ( expectedAddr ) = = theState . transactionsFrom ( expectedAddr ) , expectedAddr < < " : incorrect txCount " < < theState . transactionsFrom ( expectedAddr ) < < " , expected " < < importer . m_statePost . transactionsFrom ( expectedAddr ) ) ;
BOOST_CHECK_MESSAGE ( importer . m_statePost . code ( expectedAddr ) = = theState . code ( expectedAddr ) , expectedAddr < < " : incorrect code " ) ;
2014-10-29 16:25:02 +00:00
2014-11-03 15:33:02 +00:00
checkStorage ( importer . m_statePost . storage ( expectedAddr ) , theState . storage ( expectedAddr ) , expectedAddr ) ;
}
2014-10-29 16:25:02 +00:00
}
2014-11-03 15:33:02 +00:00
checkAddresses < map < Address , u256 > > ( expectedAddrs , resultAddrs ) ;
2015-03-02 19:45:42 +00:00
# endif
BOOST_CHECK_MESSAGE ( theState . rootHash ( ) = = h256 ( o [ " postStateRoot " ] . get_str ( ) ) , " wrong post state root " ) ;
2014-10-31 08:41:02 +00:00
}
2014-10-29 16:25:02 +00:00
}
}
2014-11-03 15:33:02 +00:00
} } // Namespace Close
2014-01-21 15:51:57 +00:00
2014-11-03 15:33:02 +00:00
BOOST_AUTO_TEST_SUITE ( StateTests )
2014-01-19 20:15:07 +00:00
2014-11-03 15:33:02 +00:00
BOOST_AUTO_TEST_CASE ( stExample )
2014-10-29 16:25:02 +00:00
{
2014-11-03 15:33:02 +00:00
dev : : test : : executeTests ( " stExample " , " /StateTests " , dev : : test : : doStateTests ) ;
2014-10-29 16:25:02 +00:00
}
2014-01-19 17:17:05 +00:00
2014-11-04 22:02:50 +00:00
BOOST_AUTO_TEST_CASE ( stSystemOperationsTest )
{
dev : : test : : executeTests ( " stSystemOperationsTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-10-31 08:41:02 +00:00
2015-03-11 12:44:02 +00:00
BOOST_AUTO_TEST_CASE ( stCallCreateCallCodeTest )
{
dev : : test : : executeTests ( " stCallCreateCallCodeTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-11-06 16:47:03 +00:00
BOOST_AUTO_TEST_CASE ( stPreCompiledContracts )
{
dev : : test : : executeTests ( " stPreCompiledContracts " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-12-05 18:26:32 +00:00
BOOST_AUTO_TEST_CASE ( stLogTests )
{
dev : : test : : executeTests ( " stLogTests " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-12-13 20:39:21 +00:00
BOOST_AUTO_TEST_CASE ( stRecursiveCreate )
{
dev : : test : : executeTests ( " stRecursiveCreate " , " /StateTests " , dev : : test : : doStateTests ) ;
}
BOOST_AUTO_TEST_CASE ( stInitCodeTest )
{
dev : : test : : executeTests ( " stInitCodeTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-12-18 08:06:51 +00:00
BOOST_AUTO_TEST_CASE ( stTransactionTest )
{
dev : : test : : executeTests ( " stTransactionTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-11-19 17:39:53 +00:00
BOOST_AUTO_TEST_CASE ( stSpecialTest )
{
dev : : test : : executeTests ( " stSpecialTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2014-12-18 08:06:51 +00:00
BOOST_AUTO_TEST_CASE ( stRefundTest )
{
dev : : test : : executeTests ( " stRefundTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2015-01-06 19:57:33 +00:00
BOOST_AUTO_TEST_CASE ( stBlockHashTest )
{
dev : : test : : executeTests ( " stBlockHashTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2015-03-05 23:11:24 +00:00
BOOST_AUTO_TEST_CASE ( stQuadraticComplexityTest )
{
2015-03-12 10:55:00 +00:00
if ( test : : Options : : get ( ) . quadratic )
{
auto start = chrono : : steady_clock : : now ( ) ;
2015-03-05 23:11:24 +00:00
2015-03-12 10:55:00 +00:00
dev : : test : : executeTests ( " stQuadraticComplexityTest " , " /StateTests " , dev : : test : : doStateTests ) ;
2015-03-05 23:11:24 +00:00
2015-03-12 10:55:00 +00:00
auto end = chrono : : steady_clock : : now ( ) ;
auto duration ( chrono : : duration_cast < chrono : : milliseconds > ( end - start ) ) ;
cnote < < " test duration: " < < duration . count ( ) < < " milliseconds. \n " ;
}
2015-03-05 23:11:24 +00:00
}
2015-02-24 18:39:47 +00:00
2015-02-28 21:04:43 +00:00
BOOST_AUTO_TEST_CASE ( stMemoryStressTest )
{
2015-03-12 10:55:00 +00:00
if ( test : : Options : : get ( ) . memory )
{
auto start = chrono : : steady_clock : : now ( ) ;
2015-02-28 21:04:43 +00:00
2015-03-12 10:55:00 +00:00
dev : : test : : executeTests ( " stMemoryStressTest " , " /StateTests " , dev : : test : : doStateTests ) ;
2015-02-28 21:04:43 +00:00
2015-03-12 10:55:00 +00:00
auto end = chrono : : steady_clock : : now ( ) ;
auto duration ( chrono : : duration_cast < chrono : : milliseconds > ( end - start ) ) ;
cnote < < " test duration: " < < duration . count ( ) < < " milliseconds. \n " ;
}
2015-02-28 21:04:43 +00:00
}
2015-03-12 10:55:00 +00:00
BOOST_AUTO_TEST_CASE ( stSolidityTest )
{
dev : : test : : executeTests ( " stSolidityTest " , " /StateTests " , dev : : test : : doStateTests ) ;
}
2015-02-12 19:26:10 +00:00
2015-02-25 11:59:23 +00:00
BOOST_AUTO_TEST_CASE ( stMemoryTest )
{
2015-03-12 10:55:00 +00:00
dev : : test : : executeTests ( " stMemoryTest " , " /StateTests " , dev : : test : : doStateTests ) ;
2015-02-25 11:59:23 +00:00
}
2015-03-03 16:36:09 +00:00
2014-11-11 21:25:21 +00:00
BOOST_AUTO_TEST_CASE ( stCreateTest )
{
for ( int i = 1 ; i < boost : : unit_test : : framework : : master_test_suite ( ) . argc ; + + i )
{
string arg = boost : : unit_test : : framework : : master_test_suite ( ) . argv [ i ] ;
if ( arg = = " --createtest " )
{
if ( boost : : unit_test : : framework : : master_test_suite ( ) . argc < = i + 2 )
{
cnote < < " usage: ./testeth --createtest <PathToConstructor> <PathToDestiny> \n " ;
return ;
}
try
{
cnote < < " Populating tests... " ;
json_spirit : : mValue v ;
string s = asString ( dev : : contents ( boost : : unit_test : : framework : : master_test_suite ( ) . argv [ i + 1 ] ) ) ;
BOOST_REQUIRE_MESSAGE ( s . length ( ) > 0 , " Content of " + ( string ) boost : : unit_test : : framework : : master_test_suite ( ) . argv [ i + 1 ] + " is empty. " ) ;
json_spirit : : read_string ( s , v ) ;
dev : : test : : doStateTests ( v , true ) ;
writeFile ( boost : : unit_test : : framework : : master_test_suite ( ) . argv [ i + 2 ] , asBytes ( json_spirit : : write_string ( v , true ) ) ) ;
}
catch ( Exception const & _e )
{
BOOST_ERROR ( " Failed state test with Exception: " < < diagnostic_information ( _e ) ) ;
}
catch ( std : : exception const & _e )
{
BOOST_ERROR ( " Failed state test with Exception: " < < _e . what ( ) ) ;
}
}
}
}
2015-03-12 10:01:06 +00:00
BOOST_AUTO_TEST_CASE ( stRandom )
{
string testPath = dev : : test : : getTestPath ( ) ;
testPath + = " /StateTests/RandomTests " ;
vector < boost : : filesystem : : path > testFiles ;
boost : : filesystem : : directory_iterator iterator ( testPath ) ;
for ( ; iterator ! = boost : : filesystem : : directory_iterator ( ) ; + + iterator )
if ( boost : : filesystem : : is_regular_file ( iterator - > path ( ) ) & & iterator - > path ( ) . extension ( ) = = " .json " )
testFiles . push_back ( iterator - > path ( ) ) ;
for ( auto & path : testFiles )
{
try
{
cnote < < " Testing ... " < < path . filename ( ) ;
json_spirit : : mValue v ;
string s = asString ( dev : : contents ( path . string ( ) ) ) ;
BOOST_REQUIRE_MESSAGE ( s . length ( ) > 0 , " Content of " + path . string ( ) + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path? " ) ;
json_spirit : : read_string ( s , v ) ;
dev : : test : : doStateTests ( v , false ) ;
}
catch ( Exception const & _e )
{
BOOST_ERROR ( " Failed test with Exception: " < < diagnostic_information ( _e ) ) ;
}
catch ( std : : exception const & _e )
{
BOOST_ERROR ( " Failed test with Exception: " < < _e . what ( ) ) ;
}
}
}
2014-11-10 06:12:29 +00:00
BOOST_AUTO_TEST_CASE ( userDefinedFileState )
{
2015-03-02 15:18:28 +00:00
dev : : test : : userDefinedTest ( " --singletest " , dev : : test : : doStateTests ) ;
2014-11-10 06:12:29 +00:00
}
2014-11-03 15:33:02 +00:00
BOOST_AUTO_TEST_SUITE_END ( )