Merge remote-tracking branch 'upstream/develop' into fixTest

This commit is contained in:
CJentzsch 2015-01-01 17:23:38 +01:00
commit 1cd1fcb6a1
27 changed files with 1798 additions and 627 deletions

View File

@ -3,45 +3,29 @@ cmake_policy(SET CMP0015 NEW)
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp")
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${CRYPTOPP_INCLUDE_DIRS})
include_directories(${JSONCPP_INCLUDE_DIRS})
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
include_directories(..) include_directories(..)
file(GLOB HEADERS "*.h") file(GLOB HEADERS "*.h")
add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(testeth ${SRC_LIST} ${HEADERS})
add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp)
target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(testeth ${CURL_LIBRARIES})
target_link_libraries(testeth ethereum) target_link_libraries(testeth ethereum)
target_link_libraries(testeth ethcore) target_link_libraries(testeth ethcore)
target_link_libraries(testeth secp256k1) target_link_libraries(testeth secp256k1)
target_link_libraries(testeth gmp)
target_link_libraries(testeth solidity) target_link_libraries(testeth solidity)
target_link_libraries(testeth ${CRYPTOPP_LS})
target_link_libraries(testeth webthree) target_link_libraries(testeth webthree)
if(JSONRPC_LS)
target_link_libraries(testeth web3jsonrpc) if (JSONRPC)
target_link_libraries(testeth web3jsonrpc)
target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES})
endif() endif()
target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethereum)
target_link_libraries(createRandomTest ethcore) target_link_libraries(createRandomTest ethcore)
target_link_libraries(createRandomTest boost_chrono)
target_link_libraries(createRandomTest boost_unit_test_framework)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
target_link_libraries(testeth boost_system-mt-s)
target_link_libraries(testeth boost_filesystem-mt-s)
target_link_libraries(testeth boost_thread_win32-mt-s)
target_link_libraries(testeth gcc)
target_link_libraries(testeth gdi32)
target_link_libraries(testeth ws2_32)
target_link_libraries(testeth mswsock)
target_link_libraries(testeth shlwapi)
target_link_libraries(testeth iphlpapi)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
find_package(Boost 1.53 REQUIRED COMPONENTS unit_test_framework)
else ()
target_link_libraries(testeth boost_system)
target_link_libraries(testeth boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(testeth ${CMAKE_THREAD_LIBS_INIT})
endif ()

View File

@ -22,7 +22,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <libsolidity/CompilerStack.h> #include <libsolidity/CompilerStack.h>
#include <jsonrpc/json/json.h> #include <jsoncpp/json/json.h>
#include <libdevcore/Exceptions.h> #include <libdevcore/Exceptions.h>
namespace dev namespace dev
@ -76,6 +76,7 @@ BOOST_AUTO_TEST_CASE(basic_test)
char const* interface = R"([ char const* interface = R"([
{ {
"name": "f", "name": "f",
"constant": false,
"inputs": [ "inputs": [
{ {
"name": "a", "name": "a",
@ -114,6 +115,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
char const* interface = R"([ char const* interface = R"([
{ {
"name": "f", "name": "f",
"constant": false,
"inputs": [ "inputs": [
{ {
"name": "a", "name": "a",
@ -129,6 +131,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
}, },
{ {
"name": "g", "name": "g",
"constant": false,
"inputs": [ "inputs": [
{ {
"name": "b", "name": "b",
@ -156,6 +159,7 @@ BOOST_AUTO_TEST_CASE(multiple_params)
char const* interface = R"([ char const* interface = R"([
{ {
"name": "f", "name": "f",
"constant": false,
"inputs": [ "inputs": [
{ {
"name": "a", "name": "a",
@ -189,6 +193,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
char const* interface = R"([ char const* interface = R"([
{ {
"name": "c", "name": "c",
"constant": false,
"inputs": [ "inputs": [
{ {
"name": "b", "name": "b",
@ -204,6 +209,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
}, },
{ {
"name": "f", "name": "f",
"constant": false,
"inputs": [ "inputs": [
{ {
"name": "a", "name": "a",
@ -222,6 +228,53 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
checkInterface(sourceCode, interface); checkInterface(sourceCode, interface);
} }
BOOST_AUTO_TEST_CASE(const_function)
{
char const* sourceCode = "contract test {\n"
" function foo(uint a, uint b) returns(uint d) { return a + b; }\n"
" function boo(uint32 a) constant returns(uint b) { return a * 4; }\n"
"}\n";
char const* interface = R"([
{
"name": "boo",
"constant": true,
"inputs": [{
"name": "a",
"type": "uint32"
}],
"outputs": [
{
"name": "b",
"type": "uint256"
}
]
},
{
"name": "foo",
"constant": false,
"inputs": [
{
"name": "a",
"type": "uint256"
},
{
"name": "b",
"type": "uint256"
}
],
"outputs": [
{
"name": "d",
"type": "uint256"
}
]
}
])";
checkInterface(sourceCode, interface);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -54,9 +54,18 @@ bytes compileContract(const string& _sourceCode)
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{ {
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
}
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract));
}
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
Compiler compiler; Compiler compiler;
compiler.compileContract(*contract, {}); compiler.compileContract(*contract, {}, map<ContractDefinition const*, bytes const*>{});
// debug // debug
//compiler.streamAssembly(cout); //compiler.streamAssembly(cout);
return compiler.getAssembledBytecode(); return compiler.getAssembledBytecode();

View File

@ -36,7 +36,7 @@ namespace solidity
namespace test namespace test
{ {
BOOST_FIXTURE_TEST_SUITE(SolidityCompilerEndToEndTest, ExecutionFramework) BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, ExecutionFramework)
BOOST_AUTO_TEST_CASE(smoke_test) BOOST_AUTO_TEST_CASE(smoke_test)
{ {
@ -176,6 +176,80 @@ BOOST_AUTO_TEST_CASE(nested_loops)
testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12); testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12);
} }
BOOST_AUTO_TEST_CASE(for_loop)
{
char const* sourceCode = "contract test {\n"
" function f(uint n) returns(uint nfac) {\n"
" nfac = 1;\n"
" for (var i = 2; i <= n; i++)\n"
" nfac *= i;\n"
" }\n"
"}\n";
compileAndRun(sourceCode);
auto for_loop_cpp = [](u256 const& n) -> u256
{
u256 nfac = 1;
for (auto i = 2; i <= n; i++)
nfac *= i;
return nfac;
};
testSolidityAgainstCppOnRange(0, for_loop_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(for_loop_empty)
{
char const* sourceCode = "contract test {\n"
" function f() returns(uint ret) {\n"
" ret = 1;\n"
" for (;;)\n"
" {\n"
" ret += 1;\n"
" if (ret >= 10) break;\n"
" }\n"
" }\n"
"}\n";
compileAndRun(sourceCode);
auto for_loop_empty_cpp = []() -> u256
{
u256 ret = 1;
for (;;)
{
ret += 1;
if (ret >= 10) break;
}
return ret;
};
testSolidityAgainstCpp(0, for_loop_empty_cpp);
}
BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
{
char const* sourceCode = "contract test {\n"
" function f(uint n) returns(uint nfac) {\n"
" nfac = 1;\n"
" uint256 i;\n"
" for (i = 2; i <= n; i++)\n"
" nfac *= i;\n"
" }\n"
"}\n";
compileAndRun(sourceCode);
auto for_loop_simple_init_expr_cpp = [](u256 const& n) -> u256
{
u256 nfac = 1;
u256 i;
for (i = 2; i <= n; i++)
nfac *= i;
return nfac;
};
testSolidityAgainstCppOnRange(0, for_loop_simple_init_expr_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(calling_other_functions) BOOST_AUTO_TEST_CASE(calling_other_functions)
{ {
// note that the index of a function is its index in the sorted sequence of functions // note that the index of a function is its index in the sorted sequence of functions
@ -402,7 +476,7 @@ BOOST_AUTO_TEST_CASE(empty_string_on_stack)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, 'a', 'b', 'c', 0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x02)) == bytes({0x00, 0x02, 0x61/*'a'*/, 0x62/*'b'*/, 0x63/*'c'*/, 0x00}));
} }
BOOST_AUTO_TEST_CASE(state_smoke_test) BOOST_AUTO_TEST_CASE(state_smoke_test)
@ -430,6 +504,41 @@ BOOST_AUTO_TEST_CASE(state_smoke_test)
BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3))); BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3)));
} }
BOOST_AUTO_TEST_CASE(compound_assign)
{
char const* sourceCode = "contract test {\n"
" uint value1;\n"
" uint value2;\n"
" function f(uint x, uint y) returns (uint w) {\n"
" uint value3 = y;"
" value1 += x;\n"
" value3 *= x;"
" value2 *= value3 + value1;\n"
" return value2 += 7;"
" }\n"
"}\n";
compileAndRun(sourceCode);
u256 value1;
u256 value2;
auto f = [&](u256 const& _x, u256 const& _y) -> u256
{
u256 value3 = _y;
value1 += _x;
value3 *= _x;
value2 *= value3 + value1;
return value2 += 7;
};
testSolidityAgainstCpp(0, f, u256(0), u256(6));
testSolidityAgainstCpp(0, f, u256(1), u256(3));
testSolidityAgainstCpp(0, f, u256(2), u256(25));
testSolidityAgainstCpp(0, f, u256(3), u256(69));
testSolidityAgainstCpp(0, f, u256(4), u256(84));
testSolidityAgainstCpp(0, f, u256(5), u256(2));
testSolidityAgainstCpp(0, f, u256(6), u256(51));
testSolidityAgainstCpp(0, f, u256(7), u256(48));
}
BOOST_AUTO_TEST_CASE(simple_mapping) BOOST_AUTO_TEST_CASE(simple_mapping)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"
@ -442,22 +551,23 @@ BOOST_AUTO_TEST_CASE(simple_mapping)
" }\n" " }\n"
"}"; "}";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0x00})); // msvc seems to have problems with initializer-list, when there is only 1 param in the list
BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0x00));
BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0x00));
BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00));
callContractFunction(1, bytes({0x01, 0xa1})); callContractFunction(1, bytes({0x01, 0xa1}));
BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0x00));
BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0xa1})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0xa1));
BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00));
callContractFunction(1, bytes({0x00, 0xef})); callContractFunction(1, bytes({0x00, 0xef}));
BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0xef})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0xef));
BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0xa1})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0xa1));
BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00));
callContractFunction(1, bytes({0x01, 0x05})); callContractFunction(1, bytes({0x01, 0x05}));
BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0xef})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0xef));
BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0x05})); BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0x05));
BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00));
} }
BOOST_AUTO_TEST_CASE(mapping_state) BOOST_AUTO_TEST_CASE(mapping_state)
@ -625,9 +735,9 @@ BOOST_AUTO_TEST_CASE(structs)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction(0) == bytes({0x00})); BOOST_CHECK(callContractFunction(0) == bytes(1, 0x00));
BOOST_CHECK(callContractFunction(1) == bytes()); BOOST_CHECK(callContractFunction(1) == bytes());
BOOST_CHECK(callContractFunction(0) == bytes({0x01})); BOOST_CHECK(callContractFunction(0) == bytes(1, 0x01));
} }
BOOST_AUTO_TEST_CASE(struct_reference) BOOST_AUTO_TEST_CASE(struct_reference)
@ -653,9 +763,9 @@ BOOST_AUTO_TEST_CASE(struct_reference)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction(0) == bytes({0x00})); BOOST_CHECK(callContractFunction(0) == bytes(1, 0x00));
BOOST_CHECK(callContractFunction(1) == bytes()); BOOST_CHECK(callContractFunction(1) == bytes());
BOOST_CHECK(callContractFunction(0) == bytes({0x01})); BOOST_CHECK(callContractFunction(0) == bytes(1, 0x01));
} }
BOOST_AUTO_TEST_CASE(constructor) BOOST_AUTO_TEST_CASE(constructor)
@ -1011,6 +1121,49 @@ BOOST_AUTO_TEST_CASE(strings_in_calls)
BOOST_CHECK(callContractFunction(0, bytes({0, 'a', 1})) == bytes({0, 'a', 0, 0, 0})); BOOST_CHECK(callContractFunction(0, bytes({0, 'a', 1})) == bytes({0, 'a', 0, 0, 0}));
} }
BOOST_AUTO_TEST_CASE(constructor_arguments)
{
char const* sourceCode = R"(
contract Helper {
string3 name;
bool flag;
function Helper(string3 x, bool f) {
name = x;
flag = f;
}
function getName() returns (string3 ret) { return name; }
function getFlag() returns (bool ret) { return flag; }
}
contract Main {
Helper h;
function Main() {
h = new Helper("abc", true);
}
function getFlag() returns (bool ret) { return h.getFlag(); }
function getName() returns (string3 ret) { return h.getName(); }
})";
compileAndRun(sourceCode, 0, "Main");
BOOST_REQUIRE(callContractFunction(0) == bytes({byte(0x01)}));
BOOST_REQUIRE(callContractFunction(1) == bytes({'a', 'b', 'c'}));
}
BOOST_AUTO_TEST_CASE(functions_called_by_constructor)
{
char const* sourceCode = R"(
contract Test {
string3 name;
bool flag;
function Test() {
setName("abc");
}
function getName() returns (string3 ret) { return name; }
private:
function setName(string3 _name) { name = _name; }
})";
compileAndRun(sourceCode);
BOOST_REQUIRE(callContractFunction(0) == bytes({'a', 'b', 'c'}));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -76,8 +76,11 @@ Declaration const& resolveDeclaration(vector<string> const& _namespacedName,
NameAndTypeResolver const& _resolver) NameAndTypeResolver const& _resolver)
{ {
Declaration const* declaration = nullptr; Declaration const* declaration = nullptr;
// bracers are required, cause msvc couldnt handle this macro in for statement
for (string const& namePart: _namespacedName) for (string const& namePart: _namespacedName)
{
BOOST_REQUIRE(declaration = _resolver.resolveName(namePart, declaration)); BOOST_REQUIRE(declaration = _resolver.resolveName(namePart, declaration));
}
BOOST_REQUIRE(declaration); BOOST_REQUIRE(declaration);
return *declaration; return *declaration;
} }
@ -94,6 +97,15 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{ {
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
}
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract));
}
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
FirstExpressionExtractor extractor(*contract); FirstExpressionExtractor extractor(*contract);
BOOST_REQUIRE(extractor.getExpression() != nullptr); BOOST_REQUIRE(extractor.getExpression() != nullptr);

View File

@ -47,6 +47,9 @@ void parseTextAndResolveNames(std::string const& _source)
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.resolveNamesAndTypes(*contract); resolver.resolveNamesAndTypes(*contract);
for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
resolver.checkTypeRequirements(*contract);
} }
} }
@ -284,6 +287,40 @@ BOOST_AUTO_TEST_CASE(assignment_to_struct)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
} }
BOOST_AUTO_TEST_CASE(returns_in_constructor)
{
char const* text = "contract test {\n"
" function test() returns (uint a) {\n"
" }\n"
"}\n";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(forward_function_reference)
{
char const* text = "contract First {\n"
" function fun() returns (bool ret) {\n"
" return Second(1).fun(1, true, 3) > 0;\n"
" }\n"
"}\n"
"contract Second {\n"
" function fun(uint a, bool b, uint c) returns (uint ret) {\n"
" if (First(2).fun() == true) return 1;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(comparison_bitop_precedence)
{
char const* text = "contract First {\n"
" function fun() returns (bool ret) {\n"
" return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -21,9 +21,9 @@
*/ */
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <jsoncpp/json/json.h>
#include <libsolidity/CompilerStack.h> #include <libsolidity/CompilerStack.h>
#include <libsolidity/Exceptions.h> #include <libsolidity/Exceptions.h>
#include <jsonrpc/json/json.h>
#include <libdevcore/Exceptions.h> #include <libdevcore/Exceptions.h>
namespace dev namespace dev
@ -394,6 +394,35 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return)
checkNatspec(sourceCode, natspec, false); checkNatspec(sourceCode, natspec, false);
} }
BOOST_AUTO_TEST_CASE(dev_multiline_comment)
{
char const* sourceCode = "contract test {\n"
" /**\n"
" * @dev Multiplies a number by 7 and adds second parameter\n"
" * @param a Documentation for the first parameter starts here.\n"
" * Since it's a really complicated parameter we need 2 lines\n"
" * @param second Documentation for the second parameter\n"
" * @return The result of the multiplication\n"
" * and cookies with nutella\n"
" */"
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
"}\n";
char const* natspec = "{"
"\"methods\":{"
" \"mul\":{ \n"
" \"details\": \"Multiplies a number by 7 and adds second parameter\",\n"
" \"params\": {\n"
" \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n"
" \"second\": \"Documentation for the second parameter\"\n"
" },\n"
" \"return\": \"The result of the multiplication and cookies with nutella\"\n"
" }\n"
"}}";
checkNatspec(sourceCode, natspec, false);
}
BOOST_AUTO_TEST_CASE(dev_contract_no_doc) BOOST_AUTO_TEST_CASE(dev_contract_no_doc)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"

View File

@ -71,7 +71,7 @@ protected:
Address m_nonOptimizedContract; Address m_nonOptimizedContract;
}; };
BOOST_FIXTURE_TEST_SUITE(SolidityOptimizerTest, OptimizerTestFramework) BOOST_FIXTURE_TEST_SUITE(SolidityOptimizer, OptimizerTestFramework)
BOOST_AUTO_TEST_CASE(smoke_test) BOOST_AUTO_TEST_CASE(smoke_test)
{ {

View File

@ -49,6 +49,23 @@ ASTPointer<ContractDefinition> parseText(std::string const& _source)
BOOST_FAIL("No contract found in source."); BOOST_FAIL("No contract found in source.");
return ASTPointer<ContractDefinition>(); return ASTPointer<ContractDefinition>();
} }
ASTPointer<ContractDefinition> parseTextExplainError(std::string const& _source)
{
try
{
return parseText(_source);
}
catch (Exception const& exception)
{
// LTODO: Print the error in a kind of a better way?
// In absence of CompilerStack we can't use SourceReferenceFormatter
cout << "Exception while parsing: " << diagnostic_information(exception);
// rethrow to signal test failure
throw exception;
}
}
} }
@ -74,7 +91,7 @@ BOOST_AUTO_TEST_CASE(empty_function)
{ {
char const* text = "contract test {\n" char const* text = "contract test {\n"
" uint256 stateVar;\n" " uint256 stateVar;\n"
" function functionName(hash160 arg1, address addr) const\n" " function functionName(hash160 arg1, address addr) constant\n"
" returns (int id)\n" " returns (int id)\n"
" { }\n" " { }\n"
"}\n"; "}\n";
@ -111,7 +128,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation)
BOOST_REQUIRE_NO_THROW(contract = parseText(text)); BOOST_REQUIRE_NO_THROW(contract = parseText(text));
auto functions = contract->getDefinedFunctions(); auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0)); BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is a test function"); BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is a test function");
} }
BOOST_AUTO_TEST_CASE(function_normal_comments) BOOST_AUTO_TEST_CASE(function_normal_comments)
@ -149,17 +166,17 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
auto functions = contract->getDefinedFunctions(); auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0)); BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 1"); BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is test function 1");
BOOST_REQUIRE_NO_THROW(function = functions.at(1)); BOOST_REQUIRE_NO_THROW(function = functions.at(1));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 2"); BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is test function 2");
BOOST_REQUIRE_NO_THROW(function = functions.at(2)); BOOST_REQUIRE_NO_THROW(function = functions.at(2));
BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr, BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr,
"Should not have gotten natspec comment for functionName3()"); "Should not have gotten natspec comment for functionName3()");
BOOST_REQUIRE_NO_THROW(function = functions.at(3)); BOOST_REQUIRE_NO_THROW(function = functions.at(3));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 4"); BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is test function 4");
} }
BOOST_AUTO_TEST_CASE(multiline_function_documentation) BOOST_AUTO_TEST_CASE(multiline_function_documentation)
@ -177,7 +194,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation)
BOOST_REQUIRE_NO_THROW(function = functions.at(0)); BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), BOOST_CHECK_EQUAL(*function->getDocumentation(),
" This is a test function\n" "This is a test function\n"
" and it has 2 lines"); " and it has 2 lines");
} }
@ -203,11 +220,11 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
auto functions = contract->getDefinedFunctions(); auto functions = contract->getDefinedFunctions();
BOOST_REQUIRE_NO_THROW(function = functions.at(0)); BOOST_REQUIRE_NO_THROW(function = functions.at(0));
BOOST_CHECK_EQUAL(*function->getDocumentation(), " fun1 description"); BOOST_CHECK_EQUAL(*function->getDocumentation(), "fun1 description");
BOOST_REQUIRE_NO_THROW(function = functions.at(1)); BOOST_REQUIRE_NO_THROW(function = functions.at(1));
BOOST_CHECK_EQUAL(*function->getDocumentation(), BOOST_CHECK_EQUAL(*function->getDocumentation(),
" This is a test function\n" "This is a test function\n"
" and it has 2 lines"); " and it has 2 lines");
} }
@ -357,6 +374,53 @@ BOOST_AUTO_TEST_CASE(while_loop)
BOOST_CHECK_NO_THROW(parseText(text)); BOOST_CHECK_NO_THROW(parseText(text));
} }
BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr)
{
char const* text = "contract test {\n"
" function fun(uint256 a) {\n"
" for (uint256 i = 0; i < 10; i++)\n"
" { uint256 x = i; break; continue; }\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr)
{
char const* text = "contract test {\n"
" function fun(uint256 a) {\n"
" uint256 i =0;\n"
" for (i = 0; i < 10; i++)\n"
" { uint256 x = i; break; continue; }\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr)
{
char const* text = "contract test {\n"
" function fun(uint256 a) {\n"
" uint256 i =0;\n"
" for (;;)\n"
" { uint256 x = i; break; continue; }\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body)
{
char const* text = "contract test {\n"
" function fun(uint256 a) {\n"
" uint256 i =0;\n"
" for (i = 0; i < 10; i++)\n"
" continue;\n"
" }\n"
"}\n";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_CASE(if_statement) BOOST_AUTO_TEST_CASE(if_statement)
{ {
char const* text = "contract test {\n" char const* text = "contract test {\n"

View File

@ -157,7 +157,14 @@ BOOST_AUTO_TEST_CASE(documentation_comments_parsed_begin)
{ {
Scanner scanner(CharStream("/// Send $(value / 1000) chocolates to the user")); Scanner scanner(CharStream("/// Send $(value / 1000) chocolates to the user"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS); BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
}
BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed_begin)
{
Scanner scanner(CharStream("/** Send $(value / 1000) chocolates to the user*/"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
} }
BOOST_AUTO_TEST_CASE(documentation_comments_parsed) BOOST_AUTO_TEST_CASE(documentation_comments_parsed)
@ -167,7 +174,43 @@ BOOST_AUTO_TEST_CASE(documentation_comments_parsed)
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
}
BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed)
{
Scanner scanner(CharStream("some other tokens /**\n"
"* Send $(value / 1000) chocolates to the user\n"
"*/"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
}
BOOST_AUTO_TEST_CASE(multiline_documentation_no_stars)
{
Scanner scanner(CharStream("some other tokens /**\n"
" Send $(value / 1000) chocolates to the user\n"
"*/"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
}
BOOST_AUTO_TEST_CASE(multiline_documentation_whitespace_hell)
{
Scanner scanner(CharStream("some other tokens /** \t \r \n"
"\t \r * Send $(value / 1000) chocolates to the user\n"
"*/"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
} }
BOOST_AUTO_TEST_CASE(comment_before_eos) BOOST_AUTO_TEST_CASE(comment_before_eos)
@ -184,6 +227,13 @@ BOOST_AUTO_TEST_CASE(documentation_comment_before_eos)
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), ""); BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "");
} }
BOOST_AUTO_TEST_CASE(empty_multiline_documentation_comment_before_eos)
{
Scanner scanner(CharStream("/***/"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "");
}
BOOST_AUTO_TEST_CASE(comments_mixed_in_sequence) BOOST_AUTO_TEST_CASE(comments_mixed_in_sequence)
{ {
Scanner scanner(CharStream("hello_world ///documentation comment \n" Scanner scanner(CharStream("hello_world ///documentation comment \n"

View File

@ -26,6 +26,7 @@
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <liblll/Compiler.h> #include <liblll/Compiler.h>
#include <libevm/VMFactory.h>
using namespace std; using namespace std;
using namespace dev::eth; using namespace dev::eth;
@ -109,9 +110,6 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state)
Address address = Address(i.first); Address address = Address(i.first);
for (auto const& j: o["storage"].get_obj())
_state.setStorage(address, toInt(j.first), toInt(j.second));
bytes code = importCode(o); bytes code = importCode(o);
if (code.size()) if (code.size())
@ -122,6 +120,9 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state)
else else
_state.m_cache[address] = Account(toInt(o["balance"]), Account::NormalCreation); _state.m_cache[address] = Account(toInt(o["balance"]), Account::NormalCreation);
for (auto const& j: o["storage"].get_obj())
_state.setStorage(address, toInt(j.first), toInt(j.second));
for(int i=0; i<toInt(o["nonce"]); ++i) for(int i=0; i<toInt(o["nonce"]); ++i)
_state.noteSending(address); _state.noteSending(address);
@ -329,10 +330,12 @@ void checkStorage(map<u256, u256> _expectedStore, map<u256, u256> _resultStore,
BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue); BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue);
} }
} }
BOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size());
for (auto&& resultStorePair : _resultStore) for (auto&& resultStorePair: _resultStore)
{
if (!_expectedStore.count(resultStorePair.first)) if (!_expectedStore.count(resultStorePair.first))
BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first);
}
} }
void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs)
@ -470,4 +473,20 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun
} }
} }
void processCommandLineOptions()
{
auto argc = boost::unit_test::framework::master_test_suite().argc;
auto argv = boost::unit_test::framework::master_test_suite().argv;
for (auto i = 0; i < argc; ++i)
{
if (std::string(argv[i]) == "--jit")
{
eth::VMFactory::setKind(eth::VMKind::JIT);
break;
}
}
}
} } // namespaces } } // namespaces

View File

@ -76,6 +76,7 @@ void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs);
void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function<void(json_spirit::mValue&, bool)> doTests); void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function<void(json_spirit::mValue&, bool)> doTests);
std::string getTestPath(); std::string getTestPath();
void userDefinedTest(std::string testTypeFlag, std::function<void(json_spirit::mValue&, bool)> doTests); void userDefinedTest(std::string testTypeFlag, std::function<void(json_spirit::mValue&, bool)> doTests);
void processCommandLineOptions();
template<typename mapType> template<typename mapType>
void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)

View File

@ -1,18 +1,18 @@
/* /*
This file is part of cpp-ethereum. This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful, cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file createRandomTest.cpp /** @file createRandomTest.cpp
* @author Christoph Jentzsch <jentzsch.simulationsoftware@gmail.com> * @author Christoph Jentzsch <jentzsch.simulationsoftware@gmail.com>

View File

@ -44,6 +44,15 @@ static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1());
static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(s_curveOID); static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(s_curveOID);
static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::EllipticCurve s_curve(s_params.GetCurve()); static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::EllipticCurve s_curve(s_params.GetCurve());
BOOST_AUTO_TEST_CASE(emptySHA3Types)
{
h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"));
BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3);
h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3);
}
BOOST_AUTO_TEST_CASE(cryptopp_patch) BOOST_AUTO_TEST_CASE(cryptopp_patch)
{ {
KeyPair k = KeyPair::create(); KeyPair k = KeyPair::create();

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file trie.cpp /** @file genesis.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
* Trie test functions. * Trie test functions.
@ -36,6 +36,15 @@ namespace js = json_spirit;
BOOST_AUTO_TEST_SUITE(BasicTests) BOOST_AUTO_TEST_SUITE(BasicTests)
BOOST_AUTO_TEST_CASE(emptySHA3Types)
{
h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"));
BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3);
h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3);
}
BOOST_AUTO_TEST_CASE(genesis_tests) BOOST_AUTO_TEST_CASE(genesis_tests)
{ {
string testPath = test::getTestPath(); string testPath = test::getTestPath();

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file main.cpp /** @file hexPrefix.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
* Main test functions. * Main test functions.

View File

@ -19,6 +19,9 @@
* @date 2014 * @date 2014
*/ */
// @debris disabled as tests fail with:
// unknown location(0): fatal error in "jsonrpc_setMining": std::exception: Exception -32003 : Client connector error: : libcurl error: 28
// /home/gav/Eth/cpp-ethereum/test/jsonrpc.cpp(169): last checkpoint
#if ETH_JSONRPC && 0 #if ETH_JSONRPC && 0
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -29,8 +32,9 @@
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
#include <libweb3jsonrpc/WebThreeStubServer.h> #include <libweb3jsonrpc/WebThreeStubServer.h>
#include <libweb3jsonrpc/CorsHttpServer.h> #include <libweb3jsonrpc/CorsHttpServer.h>
#include <jsonrpc/connectors/httpserver.h> //#include <json/json.h>
#include <jsonrpc/connectors/httpclient.h> #include <jsonrpccpp/server/connectors/httpserver.h>
#include <jsonrpccpp/client/connectors/httpclient.h>
#include <set> #include <set>
#include "JsonSpiritHeaders.h" #include "JsonSpiritHeaders.h"
#include "TestHelper.h" #include "TestHelper.h"
@ -61,11 +65,12 @@ struct Setup
web3->setIdealPeerCount(5); web3->setIdealPeerCount(5);
web3->ethereum()->setForceMining(true); web3->ethereum()->setForceMining(true);
jsonrpcServer = unique_ptr<WebThreeStubServer>(new WebThreeStubServer(new jsonrpc::CorsHttpServer(8080), *web3, {})); auto server = new jsonrpc::HttpServer(8080);
jsonrpcServer = unique_ptr<WebThreeStubServer>(new WebThreeStubServer(*server, *web3, {}));
jsonrpcServer->setIdentities({}); jsonrpcServer->setIdentities({});
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
auto client = new jsonrpc::HttpClient("http://localhost:8080");
jsonrpcClient = unique_ptr<WebThreeStubClient>(new WebThreeStubClient(new jsonrpc::HttpClient("http://localhost:8080"))); jsonrpcClient = unique_ptr<WebThreeStubClient>(new WebThreeStubClient(*client));
} }
}; };
@ -300,8 +305,11 @@ BOOST_AUTO_TEST_CASE(contract_storage)
Json::Value storage = jsonrpcClient->eth_storageAt(contractAddress); Json::Value storage = jsonrpcClient->eth_storageAt(contractAddress);
BOOST_CHECK_EQUAL(storage.getMemberNames().size(), 1); BOOST_CHECK_EQUAL(storage.getMemberNames().size(), 1);
// bracers are required, cause msvc couldnt handle this macro in for statement
for (auto name: storage.getMemberNames()) for (auto name: storage.getMemberNames())
{
BOOST_CHECK_EQUAL(storage[name].asString(), "0x03"); BOOST_CHECK_EQUAL(storage[name].asString(), "0x03");
}
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -117,7 +117,7 @@ private:
void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0)
{ {
m_state.addBalance(m_sender, _value); // just in case m_state.addBalance(m_sender, _value); // just in case
eth::Executive executive(m_state, 0); eth::Executive executive(m_state, eth::LastHashes(), 0);
eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec()) eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec())
: eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec()); : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec());
bytes transactionRLP = t.rlp(); bytes transactionRLP = t.rlp();

302
stInitCodeTestFiller.json Normal file
View File

@ -0,0 +1,302 @@
{
"TransactionContractCreation" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x600a80600c6000396000f200600160008035811a8100",
"gasLimit" : "599",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "1"
}
},
"NotEnoughCashContractCreation" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "2",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x600a80600c6000396000f200600160008035811a8100",
"gasLimit" : "599",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "1"
}
},
"OutOfGasContractCreation" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x600a80600c6000396000f200600160008035811a8100",
"gasLimit" : "590",
"gasPrice" : "3",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "1"
}
},
"TransactionSuicideInitCode" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x600a80600c6000396000fff2ffff600160008035811a81",
"gasLimit" : "1000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "1"
}
},
"TransactionStopInitCode" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x600a80600c600039600000f20000600160008035811a81",
"gasLimit" : "1000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "1"
}
},
"TransactionCreateSuicideContract" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x600a80600c6000396000f200ff600160008035811a81",
"gasLimit" : "1000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : "1"
}
},
"CallTheContractToCreateEmptyContract" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "0",
"nonce": 0,
"code": "{(CREATE 0 0 32)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "10000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"CallRecursiveContract" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "0",
"nonce": 0,
"code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "10000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"CallTheContractToCreateContractWithInitCode" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"balance": "10000",
"nonce": 0,
"code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}",
"storage": {}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "0x00",
"gasLimit" : "10000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
}
}

308
stRefundTestFiller.json Normal file
View File

@ -0,0 +1,308 @@
{
"refund_getEtherBack" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[ 1 ]] 0 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "850",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund_changeNonZeroStorage" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[ 1 ]] 23 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "850",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "10",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund_OOG" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[ 1 ]] 0 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "500",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "500",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund_NoOOG_1" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[ 1 ]] 0 }",
"storage" : {
"0x01" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "502",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "502",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund50_1" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }",
"storage" : {
"0x01" : "0x01",
"0x02" : "0x01",
"0x03" : "0x01",
"0x04" : "0x01",
"0x05" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "10000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund50_2" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ [[ 10 ]] 1 [[ 11 ]] 1 [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }",
"storage" : {
"0x01" : "0x01",
"0x02" : "0x01",
"0x03" : "0x01",
"0x04" : "0x01",
"0x05" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "10000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund500" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }",
"storage" : {
"0x01" : "0x01",
"0x02" : "0x01",
"0x03" : "0x01",
"0x04" : "0x01",
"0x05" : "0x01",
"0x06" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "10000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"refund600" : {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"currentNumber" : "0",
"currentGasLimit" : "1000000",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"nonce" : 0,
"code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xffff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }",
"storage" : {
"0x01" : "0x01",
"0x02" : "0x01",
"0x03" : "0x01",
"0x04" : "0x01",
"0x05" : "0x01",
"0x06" : "0x01"
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000",
"nonce" : 0,
"code" : "",
"storage": {}
}
},
"transaction" : {
"nonce" : "0",
"gasPrice" : "1",
"gasLimit" : "10000",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
}
}

View File

@ -0,0 +1,191 @@
{
"EmptyTransaction" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "",
"gasPrice" : "",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : ""
}
},
"TransactionSendingToEmpty" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "500",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "",
"value" : ""
}
},
"TransactionSendingToZero" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "5000",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "0000000000000000000000000000000000000000",
"value" : "1"
}
},
"TransactionToItself" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "5000",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "1"
}
},
"TransactionToItselfNotEnoughFounds" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1101",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "600",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "502"
}
},
"TransactionFromCoinbaseNotEnoughFounds" : {
"env" : {
"currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty" : "45678256",
"currentGasLimit" : "1100",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "600",
"gasPrice" : "1",
"nonce" : "",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "502"
}
}
}

View File

@ -43,6 +43,8 @@ namespace dev { namespace test {
void doStateTests(json_spirit::mValue& v, bool _fillin) void doStateTests(json_spirit::mValue& v, bool _fillin)
{ {
processCommandLineOptions();
for (auto& i: v.get_obj()) for (auto& i: v.get_obj())
{ {
cerr << i.first << endl; cerr << i.first << endl;
@ -60,7 +62,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin)
try try
{ {
theState.execute(tx, &output); theState.execute(LastHashes(), tx, &output);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
@ -130,11 +132,31 @@ BOOST_AUTO_TEST_CASE(stLogTests)
dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests); dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests);
} }
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);
}
BOOST_AUTO_TEST_CASE(stTransactionTest)
{
dev::test::executeTests("stTransactionTest", "/StateTests", dev::test::doStateTests);
}
BOOST_AUTO_TEST_CASE(stSpecialTest) BOOST_AUTO_TEST_CASE(stSpecialTest)
{ {
dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests); dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests);
} }
BOOST_AUTO_TEST_CASE(stRefundTest)
{
dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests);
}
BOOST_AUTO_TEST_CASE(stCreateTest) BOOST_AUTO_TEST_CASE(stCreateTest)
{ {
for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)

View File

@ -69,7 +69,7 @@ int stateTest()
assert(t.sender() == myMiner.address()); assert(t.sender() == myMiner.address());
tx = t.rlp(); tx = t.rlp();
} }
s.execute(tx); s.execute(bc, tx);
cout << s; cout << s;

68
vm.cpp
View File

@ -20,6 +20,7 @@
* vm test functions. * vm test functions.
*/ */
#include <chrono>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libethereum/Executive.h> #include <libethereum/Executive.h>
#include <libevm/VMFactory.h> #include <libevm/VMFactory.h>
@ -32,7 +33,7 @@ using namespace dev::eth;
using namespace dev::test; using namespace dev::test;
FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix.
ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, _depth) {} ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, LastHashes(), _depth) {}
h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&) h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&)
{ {
@ -262,12 +263,44 @@ eth::OnOpFunc FakeExtVM::simpleTrace()
dev::LogOutputStream<eth::VMTraceChannel, false>(true) << o.str(); dev::LogOutputStream<eth::VMTraceChannel, false>(true) << o.str();
dev::LogOutputStream<eth::VMTraceChannel, false>(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]"; dev::LogOutputStream<eth::VMTraceChannel, false>(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]";
/*creates json stack trace*/
if (eth::VMTraceChannel::verbosity <= g_logVerbosity) if (eth::VMTraceChannel::verbosity <= g_logVerbosity)
{ {
std::ofstream f; Object o_step;
f.open("./vmtrace.log", std::ofstream::app);
f << o.str(); /*add the stack*/
f << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32"; Array a_stack;
for (auto i: vm.stack())
a_stack.push_back((string)i);
o_step.push_back(Pair( "stack", a_stack ));
/*add the memory*/
Array a_mem;
for(auto i: vm.memory())
a_mem.push_back(i);
o_step.push_back(Pair("memory", a_mem));
/*add the storage*/
Object storage;
for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second))
storage.push_back(Pair( (string)i.first , (string)i.second));
/*add all the other details*/
o_step.push_back(Pair("storage", storage));
o_step.push_back(Pair("depth", to_string(ext.depth)));
o_step.push_back(Pair("gas", (string)vm.gas()));
o_step.push_back(Pair("address", "0x" + toString(ext.myAddress )));
o_step.push_back(Pair("step", steps ));
o_step.push_back(Pair("pc", (int)vm.curPC()));
o_step.push_back(Pair("opcode", instructionInfo(inst).name ));
/*append the JSON object to the log file*/
Value v(o_step);
ofstream os( "./stackTrace.json", ofstream::app);
os << write_string(v, true) << ",";
os.close();
} }
}; };
} }
@ -276,6 +309,8 @@ namespace dev { namespace test {
void doVMTests(json_spirit::mValue& v, bool _fillin) void doVMTests(json_spirit::mValue& v, bool _fillin)
{ {
processCommandLineOptions();
for (auto& i: v.get_obj()) for (auto& i: v.get_obj())
{ {
cnote << i.first; cnote << i.first;
@ -285,7 +320,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
BOOST_REQUIRE(o.count("pre") > 0); BOOST_REQUIRE(o.count("pre") > 0);
BOOST_REQUIRE(o.count("exec") > 0); BOOST_REQUIRE(o.count("exec") > 0);
dev::test::FakeExtVM fev; FakeExtVM fev;
fev.importEnv(o["env"].get_obj()); fev.importEnv(o["env"].get_obj());
fev.importState(o["pre"].get_obj()); fev.importState(o["pre"].get_obj());
@ -300,18 +335,18 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
} }
bytes output; bytes output;
auto vm = eth::VMFactory::create(fev.gas);
u256 gas; u256 gas;
bool vmExceptionOccured = false; bool vmExceptionOccured = false;
auto startTime = std::chrono::high_resolution_clock::now();
try try
{ {
auto vm = eth::VMFactory::create(fev.gas);
output = vm->go(fev, fev.simpleTrace()).toBytes(); output = vm->go(fev, fev.simpleTrace()).toBytes();
gas = vm->gas(); gas = vm->gas();
} }
catch (VMException const& _e) catch (VMException const& _e)
{ {
cnote << "VM did throw an exception: " << diagnostic_information(_e); cnote << "Safe VM Exception";
vmExceptionOccured = true; vmExceptionOccured = true;
} }
catch (Exception const& _e) catch (Exception const& _e)
@ -325,6 +360,21 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
BOOST_ERROR("Failed VM Test with Exception: " << _e.what()); BOOST_ERROR("Failed VM Test with Exception: " << _e.what());
} }
auto endTime = std::chrono::high_resolution_clock::now();
auto argc = boost::unit_test::framework::master_test_suite().argc;
auto argv = boost::unit_test::framework::master_test_suite().argv;
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 // delete null entries in storage for the sake of comparison
for (auto &a: fev.addresses) for (auto &a: fev.addresses)

2
vm.h
View File

@ -26,7 +26,7 @@ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
#include <fstream> #include <fstream>
#include <cstdint> #include <cstdint>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include "JsonSpiritHeaders.h" #include <json_spirit/json_spirit.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libevmcore/Instruction.h> #include <libevmcore/Instruction.h>

File diff suppressed because it is too large Load Diff