Browse Source

Merge pull request #161 from autolycus/develop

CmakeLists.txt formatting and additional tests
cl-refactor
Gav Wood 11 years ago
parent
commit
8ba37e38fa
  1. 152
      CMakeLists.txt
  2. 162
      libethereum/Instruction.cpp
  3. 29
      test/crypto.cpp
  4. 52
      test/hexPrefix.cpp
  5. 8
      test/main.cpp
  6. 194
      test/rlp.cpp
  7. 74
      test/trie.cpp
  8. 110
      test/vm.cpp

152
CMakeLists.txt

@ -86,58 +86,106 @@ endif ()
if (${TARGET_PLATFORM} STREQUAL "w64")
else ()
# Look for available Crypto++ version and if it is >= 5.6.2
find_path(ID cryptlib.h
/usr/include/cryptopp
/usr/include/crypto++
/usr/local/include/cryptopp
/usr/local/include/crypto++
/opt/local/include/cryptopp
/opt/local/include/crypto++
)
find_library(LS NAMES cryptoppeth cryptopp
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
)
if(ID AND LS)
message(STATUS "Found Crypto++: ${ID}, ${LS}")
set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h)
if(EXISTS ${_CRYPTOPP_VERSION_HEADER})
file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION})
if(${_CRYPTOPP_VERSION} LESS 562)
message(STATUS "System Crypto++ version found is smaller than 5.6.2.")
else()
set(CRYPTOPP_INCLUDE_DIR ${ID} CACHE FILEPATH "" FORCE)
set(CRYPTOPP_LIBRARIES ${LS} CACHE FILEPATH "" FORCE)
set(CRYPTOPP_FOUND TRUE)
message(STATUS "System Crypto++ found and version greater or equal to 5.6.2")
endif()
endif()
endif()
if(NOT CRYPTOPP_FOUND)
set(CRYPTOPP_INCLUDE_DIR "../cryptopp562" CACHE FILEPATH "" FORCE)
find_library(LSLOC NAMES cryptoppeth cryptopp
PATHS ../cryptopp562
NO_DEFAULT_PATH
)
set(CRYPTOPP_LIBRARIES ${LSLOC} CACHE FILEPATH "" FORCE)
message(STATUS "System Crypto++ not found, broken or too old. We use ${LSLOC}")
endif()
# Not really worth caching. We want to reevaluate anyway.
mark_as_advanced(CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARIES)
# Always "found", given last block.
include_directories(${CRYPTOPP_INCLUDE_DIR})
# Look for available Crypto++ version and if it is >= 5.6.2
find_path(ID cryptlib.h
/usr/include/cryptopp
/usr/include/crypto++
/usr/local/include/cryptopp
/usr/local/include/crypto++
/opt/local/include/cryptopp
/opt/local/include/crypto++
)
find_library(LS NAMES cryptoppeth cryptopp
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
)
if(ID AND LS)
message(STATUS "Found Crypto++: ${ID}, ${LS}")
set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h)
if(EXISTS ${_CRYPTOPP_VERSION_HEADER})
file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$")
string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION})
if(${_CRYPTOPP_VERSION} LESS 562)
message(STATUS "System Crypto++ version found is smaller than 5.6.2.")
else()
set(CRYPTOPP_INCLUDE_DIR ${ID} CACHE FILEPATH "" FORCE)
set(CRYPTOPP_LIBRARIES ${LS} CACHE FILEPATH "" FORCE)
set(CRYPTOPP_FOUND TRUE)
message(STATUS "System Crypto++ found and version greater or equal to 5.6.2")
endif()
endif()
endif()
if(NOT CRYPTOPP_FOUND)
set(CRYPTOPP_INCLUDE_DIR "../cryptopp562" CACHE FILEPATH "" FORCE)
find_library(LSLOC NAMES cryptoppeth cryptopp
PATHS ../cryptopp562
NO_DEFAULT_PATH
)
set(CRYPTOPP_LIBRARIES ${LSLOC} CACHE FILEPATH "" FORCE)
message(STATUS "System Crypto++ not found, broken or too old. We use ${LSLOC}")
endif()
# Not really worth caching. We want to reevaluate anyway.
mark_as_advanced(CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARIES)
# Always "found", given last block.
include_directories(${CRYPTOPP_INCLUDE_DIR})
if(NOT APPLE)
link_directories(${CRYPTOPP_LIBRARIES})
endif()
find_path( LEVELDB_ID leveldb/db.h
/usr/include
/usr/local/include
)
if ( LEVELDB_ID )
message(STATUS "Found LevelDB Headers")
else ()
message(FATAL_ERROR "Failed to find the LevelDB headers")
endif ()
# Check for accessory dev libraries leveldb and miniupnpc
find_library( LEVELDB_LS NAMES leveldb
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
)
if ( LEVELDB_LS )
message(STATUS "Found LevelDB Library: ${LEVELDB_LS}")
else ()
message(FATAL_ERROR "Failed to find the LevelDB Library!")
endif ()
find_path( MINIUPNPC_ID miniupnpc/miniwget.h
/usr/include/miniupnpc
/usr/local/include/miniupnpc
)
if ( MINIUPNPC_ID )
message(STATUS "Found miniupnpc headers")
else ()
message(FATAL_ERROR "Failed to find the miniupnpc headers!")
endif ()
find_library( MINIUPNPC_LS NAMES miniupnpc
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/usr/lib/*/
)
if ( MINIUPNPC_LS )
message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}")
else ()
message(FATAL_ERROR "Failed to find the miniupnpc library!")
endif ()
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
@ -154,12 +202,12 @@ add_subdirectory(test)
add_subdirectory(eth)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
else ()
add_subdirectory(neth)
add_subdirectory(neth)
endif ()
if (NOT HEADLESS)
add_subdirectory(libqethereum)
add_subdirectory(alethzero)
add_subdirectory(walleth)
add_subdirectory(libqethereum)
add_subdirectory(alethzero)
add_subdirectory(walleth)
endif ()
enable_testing()

162
libethereum/Instruction.cpp

@ -115,89 +115,89 @@ const std::map<std::string, Instruction> eth::c_instructions =
};
const std::map<Instruction, InstructionInfo> eth::c_instructionInfo =
{
{ Instruction::STOP, { "STOP", 0, 0, 0 } },
{ Instruction::ADD, { "ADD", 0, 2, 1 } },
{ Instruction::SUB, { "SUB", 0, 2, 1 } },
{ Instruction::MUL, { "MUL", 0, 2, 1 } },
{ Instruction::DIV, { "DIV", 0, 2, 1 } },
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } },
{ Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NEG, { "NEG", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::NOT, { "NOT", 0, 1, 1 } },
{ Instruction::AND, { "AND", 0, 2, 1 } },
{ Instruction::OR, { "OR", 0, 2, 1 } },
{ Instruction::XOR, { "XOR", 0, 2, 1 } },
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } },
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } },
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },
{ Instruction::ORIGIN, { "ORIGIN", 0, 1, 1 } },
{ Instruction::CALLER, { "CALLER", 0, 0, 1 } },
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } },
{ // Add, Args, Ret
{ Instruction::STOP, { "STOP", 0, 0, 0 } },
{ Instruction::ADD, { "ADD", 0, 2, 1 } },
{ Instruction::SUB, { "SUB", 0, 2, 1 } },
{ Instruction::MUL, { "MUL", 0, 2, 1 } },
{ Instruction::DIV, { "DIV", 0, 2, 1 } },
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } },
{ Instruction::MOD, { "MOD", 0, 2, 1 } },
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } },
{ Instruction::EXP, { "EXP", 0, 2, 1 } },
{ Instruction::NEG, { "NEG", 0, 1, 1 } },
{ Instruction::LT, { "LT", 0, 2, 1 } },
{ Instruction::GT, { "GT", 0, 2, 1 } },
{ Instruction::EQ, { "EQ", 0, 2, 1 } },
{ Instruction::NOT, { "NOT", 0, 1, 1 } },
{ Instruction::AND, { "AND", 0, 2, 1 } },
{ Instruction::OR, { "OR", 0, 2, 1 } },
{ Instruction::XOR, { "XOR", 0, 2, 1 } },
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } },
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } },
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },
{ Instruction::ORIGIN, { "ORIGIN", 0, 1, 1 } },
{ Instruction::CALLER, { "CALLER", 0, 0, 1 } },
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } },
{ Instruction::CALLDATALOAD, { "CALLDATALOAD", 0, 1, 1 } },
{ Instruction::CALLDATASIZE, { "CALLDATASIZE", 0, 0, 1 } },
{ Instruction::GASPRICE, { "BASEFEE", 0, 0, 1 } },
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } },
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1 } },
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } },
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1 } },
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } },
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } },
{ Instruction::POP, { "POP", 0, 1, 0 } },
{ Instruction::DUP, { "DUP", 0, 1, 2 } },
{ Instruction::SWAP, { "SWAP", 0, 2, 2 } },
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } },
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } },
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } },
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } },
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } },
{ Instruction::JUMP, { "JUMP", 0, 1, 0 } },
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0 } },
{ Instruction::PC, { "PC", 0, 0, 1 } },
{ Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } },
{ Instruction::GAS, { "GAS", 0, 0, 1 } },
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1 } },
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1 } },
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1 } },
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1 } },
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1 } },
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1 } },
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1 } },
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1 } },
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1 } },
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1 } },
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1 } },
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1 } },
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1 } },
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1 } },
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1 } },
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1 } },
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1 } },
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1 } },
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1 } },
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1 } },
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1 } },
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1 } },
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1 } },
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1 } },
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1 } },
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1 } },
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1 } },
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1 } },
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1 } },
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1 } },
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1 } },
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1 } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } },
{ Instruction::CALL, { "CALL", 0, 7, 1 } },
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }
{ Instruction::GASPRICE, { "BASEFEE", 0, 0, 1 } },
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } },
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1 } },
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } },
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1 } },
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } },
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } },
{ Instruction::POP, { "POP", 0, 1, 0 } },
{ Instruction::DUP, { "DUP", 0, 1, 2 } },
{ Instruction::SWAP, { "SWAP", 0, 2, 2 } },
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } },
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } },
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } },
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } },
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } },
{ Instruction::JUMP, { "JUMP", 0, 1, 0 } },
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0 } },
{ Instruction::PC, { "PC", 0, 0, 1 } },
{ Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } },
{ Instruction::GAS, { "GAS", 0, 0, 1 } },
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1 } },
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1 } },
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1 } },
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1 } },
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1 } },
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1 } },
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1 } },
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1 } },
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1 } },
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1 } },
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1 } },
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1 } },
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1 } },
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1 } },
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1 } },
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1 } },
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1 } },
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1 } },
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1 } },
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1 } },
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1 } },
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1 } },
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1 } },
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1 } },
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1 } },
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1 } },
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1 } },
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1 } },
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1 } },
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1 } },
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1 } },
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1 } },
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } },
{ Instruction::CALL, { "CALL", 0, 7, 1 } },
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }
};
static string readQuoted(char const*& o_d, char const* _e)

29
test/crypto.cpp

@ -26,9 +26,38 @@
#include <RLP.h>
#include <Log.h>
#include <Transaction.h>
#include <boost/test/unit_test.hpp>
using namespace std;
using namespace eth;
BOOST_AUTO_TEST_CASE(crypto_tests)
{
cnote << "Testing Crypto...";
secp256k1_start();
KeyPair p(Secret(fromHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4")));
BOOST_REQUIRE(p.pub() == Public(fromHex("97466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f")));
BOOST_REQUIRE(p.address() == Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075")));
{
Transaction t;
t.nonce = 0;
t.receiveAddress = h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b"));
t.value = 1000;
cnote << RLP(t.rlp(false));
cnote << toHex(t.rlp(false));
cnote << t.sha3(false);
t.sign(p.secret());
cnote << RLP(t.rlp(true));
cnote << toHex(t.rlp(true));
cnote << t.sha3(true);
BOOST_REQUIRE(t.sender() == p.address());
}
}
int cryptoTest()
{
cnote << "Testing Crypto...";

52
test/hexPrefix.cpp

@ -24,47 +24,29 @@
#include "JsonSpiritHeaders.h"
#include "TrieCommon.h"
#include "Log.h"
#include <boost/test/unit_test.hpp>
using namespace std;
using namespace eth;
namespace js = json_spirit;
namespace eth
{
template <> class UnitTest<3>
BOOST_AUTO_TEST_CASE(hexPrefix_test)
{
public:
int operator()()
cnote << "Testing Hex-Prefix-Encode...";
js::mValue v;
string s = asString(contents("../../tests/hexencodetest.json"));
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content from 'hexencodetest.json' is empty. Have you cloned the 'tests' repo branch develop?");
js::read_string(s, v);
for (auto& i: v.get_obj())
{
js::mValue v;
string s = asString(contents("../../tests/hexencodetest.json"));
js::read_string(s, v);
bool passed = true;
for (auto& i: v.get_obj())
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
bytes v;
for (auto& i: o["seq"].get_array())
v.push_back((byte)i.get_int());
auto e = hexPrefixEncode(v, o["term"].get_bool());
if (!o["out"].is_null() && o["out"].get_str() != toHex(e))
{
cwarn << "Test failed.";
cwarn << "Test says:" << o["out"].get_str();
cwarn << "Impl says:" << toHex(e);
passed = false;
}
}
return passed ? 0 : 1;
js::mObject& o = i.second.get_obj();
cnote << i.first;
bytes v;
for (auto& i: o["seq"].get_array())
v.push_back((byte)i.get_int());
auto e = hexPrefixEncode(v, o["term"].get_bool());
BOOST_REQUIRE( ! o["out"].is_null() );
BOOST_CHECK( o["out"].get_str() == toHex(e) );
}
};
}
int hexPrefixTest()
{
cnote << "Testing Hex-Prefix-Encode...";
return UnitTest<3>()();
}

8
test/main.cpp

@ -45,14 +45,10 @@ BOOST_AUTO_TEST_CASE(basic_tests)
std::cout << sha3(s.out()) << std::endl;*/
int r = 0;
r += hexPrefixTest();
r += rlpTest();
r += trieTest();
r += vmTest();
r += cryptoTest(); // TODO: Put in tests repo.
// r += daggerTest();
// r += stateTest();
// r += peerTest(argc, argv);
BOOST_REQUIRE(!r);
// BOOST_REQUIRE(!r);
}

194
test/rlp.cpp

@ -21,69 +21,173 @@
*/
#include <fstream>
#include <sstream>
#include "JsonSpiritHeaders.h"
#include <Log.h>
#include <RLP.h>
#include <Common.h>
#include <boost/test/unit_test.hpp>
#include <algorithm>
using namespace std;
using namespace eth;
namespace js = json_spirit;
namespace eth
{
template <> class UnitTest<2>
namespace eth
{
public:
static void buildRLP(js::mValue& _v, RLPStream& _rlp)
namespace test
{
if (_v.type() == js::array_type)
static void buildRLP(js::mValue& _v, RLPStream& _rlp)
{
RLPStream s;
for (auto& i: _v.get_array())
buildRLP(i, s);
_rlp.appendList(s.out());
if (_v.type() == js::array_type)
{
RLPStream s;
for (auto& i: _v.get_array())
buildRLP(i, s);
_rlp.appendList(s.out());
}
else if (_v.type() == js::int_type)
_rlp.append(_v.get_uint64());
else if (_v.type() == js::str_type)
{
auto s = _v.get_str();
if (s.size() && s[0] == '#')
_rlp.append(bigint(s.substr(1)));
else
_rlp.append(s);
}
}
else if (_v.type() == js::int_type)
_rlp.append(_v.get_uint64());
else if (_v.type() == js::str_type)
static void getRLPTestCases(js::mValue& v)
{
auto s = _v.get_str();
if (s.size() && s[0] == '#')
_rlp.append(bigint(s.substr(1)));
else
_rlp.append(s);
}
}
string s = asString(contents("../../tests/rlptest.json"));
BOOST_REQUIRE_MESSAGE( s.length() > 0,
"Contents of 'rlptest.json' is empty. Have you cloned the 'tests' repo branch develop?");
js::read_string(s, v);
}
int operator()()
{
js::mValue v;
string s = asString(contents("../../tests/rlptest.json"));
js::read_string(s, v);
bool passed = true;
for (auto& i: v.get_obj())
static void checkRLPTestCase(js::mObject& o)
{
BOOST_REQUIRE( o.count("in") > 0 );
BOOST_REQUIRE( o.count("out") > 0 );
BOOST_REQUIRE(!o["out"].is_null());
}
static void checkRLPAgainstJson(js::mValue& v, RLP& u)
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
RLPStream s;
buildRLP(o["in"], s);
if (!o["out"].is_null() && o["out"].get_str() != toHex(s.out()))
{
cwarn << "Test failed.";
cwarn << "Test says:" << o["out"].get_str();
cwarn << "Impl says:" << toHex(s.out());
passed = false;
}
}
return passed ? 0 : 1;
if ( v.type() == js::str_type )
{
const std::string& expectedText = v.get_str();
if ( expectedText.front() == '#' )
{
// Deal with bigint instead of a raw string
std::string bigIntStr = expectedText.substr(1,expectedText.length()-1);
std::stringstream bintStream(bigIntStr);
bigint val;
bintStream >> val;
BOOST_CHECK( !u.isList() );
BOOST_CHECK( !u.isNull() );
BOOST_CHECK( u ); // operator bool()
BOOST_CHECK(u == val);
}
else
{
BOOST_CHECK( !u.isList() );
BOOST_CHECK( !u.isNull() );
BOOST_CHECK( u.isData() );
BOOST_CHECK( u );
BOOST_CHECK( u.size() == expectedText.length() );
BOOST_CHECK(u == expectedText);
}
}
else if ( v.type() == js::int_type )
{
const int expectedValue = v.get_int();
BOOST_CHECK( u.isInt() );
BOOST_CHECK( !u.isList() );
BOOST_CHECK( !u.isNull() );
BOOST_CHECK( u ); // operator bool()
BOOST_CHECK(u == expectedValue);
}
else if ( v.type() == js::array_type )
{
BOOST_CHECK( u.isList() );
BOOST_CHECK( !u.isInt() );
BOOST_CHECK( !u.isData() );
js::mArray& arr = v.get_array();
BOOST_CHECK( u.itemCount() == arr.size() );
uint i;
for( i = 0; i < arr.size(); i++ )
{
RLP item = u[i];
checkRLPAgainstJson(arr[i], item);
}
}
else
{
BOOST_ERROR("Invalid Javascript object!");
}
}
}
}
};
BOOST_AUTO_TEST_CASE(rlp_encoding_test)
{
cnote << "Testing RLP Encoding...";
js::mValue v;
eth::test::getRLPTestCases(v);
for (auto& i: v.get_obj())
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
eth::test::checkRLPTestCase(o);
RLPStream s;
eth::test::buildRLP(o["in"], s);
std::string expectedText(o["out"].get_str());
std::transform(expectedText.begin(), expectedText.end(), expectedText.begin(), ::tolower );
const std::string& computedText = toHex(s.out());
std::stringstream msg;
msg << "Encoding Failed: expected: " << expectedText << std::endl;
msg << " But Computed: " << computedText;
BOOST_CHECK_MESSAGE(
expectedText == computedText,
msg.str()
);
}
}
int rlpTest()
BOOST_AUTO_TEST_CASE(rlp_decoding_test)
{
cnote << "Testing RLP...";
return UnitTest<2>()();
cnote << "Testing RLP decoding...";
// Uses the same test cases as encoding but in reverse.
// We read into the string of hex values, convert to bytes,
// and then compare the output structure to the json of the
// input object.
js::mValue v;
eth::test::getRLPTestCases(v);
for (auto& i: v.get_obj())
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
eth::test::checkRLPTestCase(o);
js::mValue& inputData = o["in"];
bytes payloadToDecode = fromHex(o["out"].get_str());
RLP payload(payloadToDecode);
eth::test::checkRLPAgainstJson(inputData, payload);
}
}

74
test/trie.cpp

@ -26,56 +26,56 @@
#include <TrieDB.h>
#include "TrieHash.h"
#include "MemTrie.h"
#include <boost/test/unit_test.hpp>
using namespace std;
using namespace eth;
namespace js = json_spirit;
namespace eth
{
namespace eth
{
namespace test
{
static unsigned fac(unsigned _i)
{
return _i > 2 ? _i * fac(_i - 1) : _i;
}
unsigned fac(unsigned _i) { return _i > 2 ? _i * fac(_i - 1) : _i; }
}
}
template <> class UnitTest<4>
BOOST_AUTO_TEST_CASE(trie_tests)
{
public:
int operator()()
cnote << "Testing Trie...";
js::mValue v;
string s = asString(contents("../../tests/trietest.json"));
BOOST_REQUIRE_MESSAGE( s.length() > 0, "Contents of 'trietest.json' is empty. Have you cloned the 'tests' repo branch develop?");
js::read_string(s, v);
for (auto& i: v.get_obj())
{
js::mValue v;
string s = asString(contents("../../tests/trietest.json"));
js::read_string(s, v);
bool passed = true;
for (auto& i: v.get_obj())
js::mObject& o = i.second.get_obj();
cnote << i.first;
vector<pair<string, string>> ss;
for (auto& i: o["in"].get_obj())
ss.push_back(make_pair(i.first, i.second.get_str()));
for (unsigned j = 0; j < eth::test::fac((unsigned)ss.size()); ++j)
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
vector<pair<string, string>> ss;
for (auto& i: o["in"].get_obj())
ss.push_back(make_pair(i.first, i.second.get_str()));
for (unsigned j = 0; j < fac((unsigned)ss.size()); ++j)
{
next_permutation(ss.begin(), ss.end());
BasicMap m;
GenericTrieDB<BasicMap> t(&m);
t.init();
for (auto const& k: ss)
t.insert(k.first, k.second);
if (!o["root"].is_null() && o["root"].get_str() != toHex(t.root().asArray()))
{
cwarn << "Test failed on permutation " << j;
cwarn << "Test says:" << o["root"].get_str();
cwarn << "Impl says:" << toHex(t.root().asArray());
passed = false;
}
}
next_permutation(ss.begin(), ss.end());
BasicMap m;
GenericTrieDB<BasicMap> t(&m);
t.init();
for (auto const& k: ss)
t.insert(k.first, k.second);
BOOST_REQUIRE(!o["root"].is_null());
BOOST_CHECK(o["root"].get_str() == toHex(t.root().asArray()) );
}
return passed ? 0 : 1;
}
};
}
inline h256 stringMapHash256(StringMap const& _s)
{
return hash256(_s);
@ -83,8 +83,6 @@ inline h256 stringMapHash256(StringMap const& _s)
int trieTest()
{
cnote << "Testing Trie...";
return UnitTest<4>()();
// More tests...
{

110
test/vm.cpp

@ -27,12 +27,13 @@
#include <Log.h>
#include <Instruction.h>
#include "JsonSpiritHeaders.h"
#include <boost/test/unit_test.hpp>
using namespace std;
using namespace json_spirit;
using namespace eth;
namespace eth
{
namespace eth { namespace test {
class FakeExtVM: public ExtVMFace
{
@ -135,6 +136,12 @@ public:
void importEnv(mObject& _o)
{
BOOST_REQUIRE(_o.count("previousHash") > 0 );
BOOST_REQUIRE(_o.count("previousNonce") > 0 );
BOOST_REQUIRE(_o.count("currentDifficulty") > 0 );
BOOST_REQUIRE(_o.count("currentTimestamp") > 0 );
BOOST_REQUIRE(_o.count("currentCoinbase") > 0 );
previousBlock.hash = h256(_o["previousHash"].get_str());
previousBlock.nonce = h256(_o["previousNonce"].get_str());
currentBlock.difficulty = toInt(_o["currentDifficulty"]);
@ -228,6 +235,10 @@ public:
for (auto const& i: _o)
{
mObject o = i.second.get_obj();
BOOST_REQUIRE(o.count("balance") > 0 );
BOOST_REQUIRE(o.count("nonce") > 0 );
BOOST_REQUIRE(o.count("store") > 0 );
auto& a = addresses[Address(i.first)];
get<0>(a) = toInt(o["balance"]);
get<1>(a) = toInt(o["nonce"]);
@ -249,6 +260,7 @@ public:
mObject exportExec()
{
mObject ret;
ret["address"] = toString(myAddress);
ret["caller"] = toString(caller);
@ -264,6 +276,13 @@ public:
void importExec(mObject& _o)
{
BOOST_REQUIRE(_o.count("address")> 0);
BOOST_REQUIRE(_o.count("caller") > 0);
BOOST_REQUIRE(_o.count("origin") > 0);
BOOST_REQUIRE(_o.count("value") > 0);
BOOST_REQUIRE(_o.count("gasPrice") > 0);
BOOST_REQUIRE(_o.count("data") > 0 );
myAddress = Address(_o["address"].get_str());
caller = Address(_o["caller"].get_str());
origin = Address(_o["origin"].get_str());
@ -297,6 +316,9 @@ public:
for (mValue& v: _txs)
{
auto tx = v.get_obj();
BOOST_REQUIRE(tx.count("destination") > 0);
BOOST_REQUIRE(tx.count("value") > 0 );
BOOST_REQUIRE(tx.count("data") > 0 );
Transaction t;
t.receiveAddress = Address(tx["destination"].get_str());
t.value = toInt(tx["value"]);
@ -311,37 +333,20 @@ public:
bytes thisTxData;
};
#define CREATE_TESTS 0
template <> class UnitTest<1>
{
public:
int operator()()
void doTests(json_spirit::mValue& v, bool _fillin)
{
json_spirit::mValue v;
#if CREATE_TESTS
string s = asString(contents("../../cpp-ethereum/test/vmtests.json"));
json_spirit::read_string(s, v);
bool passed = doTests(v, true);
cout << json_spirit::write_string(v, true) << endl;
#else
string s = asString(contents("../../tests/vmtests.json"));
json_spirit::read_string(s, v);
bool passed = doTests(v, false);
#endif
return passed ? 0 : 1;
}
bool doTests(json_spirit::mValue& v, bool _fillin)
{
bool passed = true;
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 );
VM vm;
FakeExtVM fev;
eth::test::FakeExtVM fev;
fev.importEnv(o["env"].get_obj());
fev.importState(o["pre"].get_obj());
@ -365,37 +370,44 @@ public:
}
else
{
FakeExtVM test;
BOOST_REQUIRE( o.count("post") > 0 );
BOOST_REQUIRE( o.count("txs") > 0 );
BOOST_REQUIRE( o.count("out") > 0 );
eth::test::FakeExtVM test;
test.importState(o["post"].get_obj());
test.importTxs(o["txs"].get_array());
int i = 0;
for (auto const& d: o["out"].get_array())
{
if (output[i] != FakeExtVM::toInt(d))
{
cwarn << "Test failed: output byte" << i << "different.";
passed = false;
}
BOOST_CHECK_MESSAGE( output[i] == FakeExtVM::toInt(d), "Output byte [" << i << "] different!");
++i;
}
if (test.addresses != fev.addresses)
{
cwarn << "Test failed: state different.";
passed = false;
}
if (test.txs != fev.txs)
{
cwarn << "Test failed: tx list different:";
cwarn << test.txs;
cwarn << fev.txs;
passed = false;
}
BOOST_CHECK( test.addresses == fev.addresses);
BOOST_CHECK( test.txs == fev.txs );
}
}
return passed;
}
} } // Namespace Close
BOOST_AUTO_TEST_CASE(vm_tests)
{
try
{
cnote << "Testing VM...";
json_spirit::mValue v;
string s = asString(contents("../../tests/vmtests.json"));
BOOST_REQUIRE_MESSAGE( s.length() > 0, "Contents of 'vmtests.json' is empty. Have you cloned the 'tests' repo branch develop?" );
json_spirit::read_string(s, v);
eth::test::doTests(v, false);
}
catch( std::exception& e)
{
BOOST_ERROR("Failed VM Test with Exception: " << e.what());
}
}
#if 0
string makeTestCase()
{
json_spirit::mObject o;
@ -427,9 +439,5 @@ public:
}
int vmTest()
{
cnote << "Testing VM...";
return UnitTest<1>()();
}
#endif

Loading…
Cancel
Save