Paweł Bylica
9 years ago
135 changed files with 6 additions and 73999 deletions
@ -1,35 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
set(CMAKE_AUTOMOC OFF) |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) |
|||
include_directories(BEFORE ..) |
|||
include_directories(${Boost_INCLUDE_DIRS}) |
|||
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
|||
|
|||
set(EXECUTABLE ethrpctest) |
|||
|
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) |
|||
|
|||
add_dependencies(${EXECUTABLE} BuildInfo.h) |
|||
|
|||
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) |
|||
|
|||
if (READLINE_FOUND) |
|||
target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) |
|||
endif() |
|||
|
|||
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} testutils) |
|||
target_link_libraries(${EXECUTABLE} web3jsonrpc) |
|||
|
|||
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) |
|||
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS) |
|||
endif() |
|||
|
|||
install( TARGETS ${EXECUTABLE} DESTINATION bin ) |
|||
|
@ -1,130 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file CommandLineInterface.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <string> |
|||
#include <iostream> |
|||
#include <fstream> |
|||
#include <csignal> |
|||
#include <thread> |
|||
#include <boost/filesystem.hpp> |
|||
#include <jsonrpccpp/server/connectors/httpserver.h> |
|||
#include <libtestutils/Common.h> |
|||
#include <libtestutils/BlockChainLoader.h> |
|||
#include <libtestutils/FixedClient.h> |
|||
#include <libtestutils/FixedWebThreeServer.h> |
|||
#include "CommandLineInterface.h" |
|||
#include "BuildInfo.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
using namespace dev::test; |
|||
namespace po = boost::program_options; |
|||
|
|||
bool CommandLineInterface::parseArguments(int argc, char** argv) |
|||
{ |
|||
// Declare the supported options.
|
|||
po::options_description desc("Allowed options"); |
|||
desc.add_options() |
|||
("help", "Show help message and exit") |
|||
("json", po::value<vector<string>>()->required(), "input file") |
|||
("test", po::value<vector<string>>()->required(), "test case name"); |
|||
|
|||
// All positional options should be interpreted as input files
|
|||
po::positional_options_description p; |
|||
|
|||
// parse the compiler arguments
|
|||
try |
|||
{ |
|||
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args); |
|||
|
|||
if (m_args.count("help")) |
|||
{ |
|||
cout << desc; |
|||
return false; |
|||
} |
|||
|
|||
po::notify(m_args); |
|||
} |
|||
catch (po::error const& _exception) |
|||
{ |
|||
cout << _exception.what() << endl; |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
bool CommandLineInterface::processInput() |
|||
{ |
|||
string infile = m_args["json"].as<vector<string>>()[0]; |
|||
|
|||
auto path = boost::filesystem::path(infile); |
|||
if (!boost::filesystem::exists(path)) |
|||
{ |
|||
cout << "Non existant input file \"" << infile << "\"" << endl; |
|||
return false; |
|||
} |
|||
|
|||
string test = m_args["test"].as<vector<string>>()[0]; |
|||
Json::Value j = dev::test::loadJsonFromFile(path.string()); |
|||
|
|||
if (j[test].empty()) |
|||
{ |
|||
cout << "Non existant test case \"" << infile << "\"" << endl; |
|||
return false; |
|||
} |
|||
|
|||
if (!j[test].isObject()) |
|||
{ |
|||
cout << "Incorrect JSON file \"" << infile << "\"" << endl; |
|||
return false; |
|||
} |
|||
|
|||
m_json = j[test]; |
|||
|
|||
return true; |
|||
} |
|||
|
|||
bool g_exit = false; |
|||
|
|||
void sighandler(int) |
|||
{ |
|||
g_exit = true; |
|||
} |
|||
|
|||
void CommandLineInterface::actOnInput() |
|||
{ |
|||
BlockChainLoader bcl(m_json); |
|||
cerr << "void CommandLineInterface::actOnInput() FixedClient now accepts eth::Block!!!" << endl; |
|||
FixedClient client(bcl.bc(), eth::Block{}/*bcl.state()*/); |
|||
unique_ptr<FixedWebThreeServer> jsonrpcServer; |
|||
auto server = new jsonrpc::HttpServer(8080, "", "", 2); |
|||
jsonrpcServer.reset(new FixedWebThreeServer(*server, {}, &client)); |
|||
jsonrpcServer->StartListening(); |
|||
|
|||
signal(SIGABRT, &sighandler); |
|||
signal(SIGTERM, &sighandler); |
|||
signal(SIGINT, &sighandler); |
|||
|
|||
while (!g_exit) |
|||
this_thread::sleep_for(chrono::milliseconds(1000)); |
|||
} |
@ -1,46 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** CommandLineInterface.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
#pragma once |
|||
|
|||
#include <json/json.h> |
|||
#include <boost/program_options.hpp> |
|||
|
|||
class CommandLineInterface |
|||
{ |
|||
public: |
|||
CommandLineInterface() {} |
|||
|
|||
/// Parse command line arguments and return false if we should not continue
|
|||
bool parseArguments(int argc, char** argv); |
|||
/// Parse input file and check if test exists
|
|||
bool processInput(); |
|||
/// Start FixedJsonRpcServer
|
|||
void actOnInput(); |
|||
|
|||
private: |
|||
|
|||
/// Compiler arguments variable map
|
|||
boost::program_options::variables_map m_args; |
|||
|
|||
/// loaded json test case
|
|||
Json::Value m_json; |
|||
}; |
|||
|
@ -1,34 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** main.cpp
|
|||
* @author Marek Kotewicz <c@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "CommandLineInterface.h" |
|||
|
|||
int main(int argc, char** argv) |
|||
{ |
|||
CommandLineInterface cli; |
|||
if (!cli.parseArguments(argc, argv)) |
|||
return 1; |
|||
if (!cli.processInput()) |
|||
return 1; |
|||
cli.actOnInput(); |
|||
|
|||
return 0; |
|||
} |
@ -1,53 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file BlockChainLoader.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <json/writer.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include "BlockChainLoader.h" |
|||
#include "Common.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::test; |
|||
using namespace dev::eth; |
|||
|
|||
BlockChainLoader::BlockChainLoader(Json::Value const& _json) |
|||
{ |
|||
// load genesisBlock
|
|||
bytes genesisBl = fromHex(_json["genesisRLP"].asString()); |
|||
|
|||
Json::FastWriter a; |
|||
m_bc.reset(new FullBlockChain<Ethash>(genesisBl, jsonToAccountMap( a.write(_json["pre"])), m_dir.path(), WithExisting::Kill)); |
|||
|
|||
// load pre state
|
|||
m_block = m_bc->genesisBlock(State::openDB(m_dir.path(), m_bc->genesisHash(), WithExisting::Kill)); |
|||
|
|||
assert(m_block.rootHash() == m_bc->info().stateRoot()); |
|||
|
|||
// load blocks
|
|||
for (auto const& block: _json["blocks"]) |
|||
{ |
|||
bytes rlp = fromHex(block["rlp"].asString()); |
|||
m_bc->import(rlp, state().db()); |
|||
} |
|||
|
|||
// sync state
|
|||
m_block.sync(*m_bc); |
|||
} |
@ -1,53 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file BlockChainLoader.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
#include <string> |
|||
#include <json/json.h> |
|||
#include <libdevcore/TransientDirectory.h> |
|||
#include <libethereum/BlockChain.h> |
|||
#include <libethereum/Block.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
/**
|
|||
* @brief Should be used to load test blockchain from json file |
|||
* Loads the blockchain from json, creates temporary directory to store it, removes the directory on dealloc |
|||
*/ |
|||
class BlockChainLoader |
|||
{ |
|||
public: |
|||
BlockChainLoader(Json::Value const& _json); |
|||
eth::BlockChain const& bc() const { return *m_bc; } |
|||
eth::State const& state() const { return m_block.state(); } // TODO remove?
|
|||
eth::Block const& block() const { return m_block; } |
|||
|
|||
private: |
|||
TransientDirectory m_dir; |
|||
std::unique_ptr<eth::BlockChain> m_bc; |
|||
eth::Block m_block; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,32 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
set(CMAKE_AUTOMOC OFF) |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) |
|||
include_directories(BEFORE ..) |
|||
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
|||
include_directories(${Boost_INCLUDE_DIRS}) |
|||
|
|||
set(EXECUTABLE testutils) |
|||
|
|||
file(GLOB HEADERS "*.h") |
|||
|
|||
if (NOT JSONRPC) |
|||
list(REMOVE_ITEM SRC_LIST "./FixedWebThreeServer.cpp") |
|||
list(REMOVE_ITEM HEADERS "./FixedWebThreeServer.h") |
|||
endif() |
|||
|
|||
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) |
|||
|
|||
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) |
|||
target_link_libraries(${EXECUTABLE} ethereum) |
|||
|
|||
if (JSONRPC) |
|||
target_link_libraries(${EXECUTABLE} web3jsonrpc) |
|||
endif() |
|||
|
|||
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) |
|||
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) |
|||
|
@ -1,88 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Common.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <random> |
|||
#include <boost/filesystem.hpp> |
|||
#include <libdevcore/CommonData.h> |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libdevcore/FileSystem.h> |
|||
#include "Common.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::test; |
|||
|
|||
const char* TestChannel::name() { return "TST"; } |
|||
|
|||
std::string dev::test::getTestPath() |
|||
{ |
|||
string testPath; |
|||
const char* ptestPath = getenv("ETHEREUM_TEST_PATH"); |
|||
|
|||
if (ptestPath == NULL) |
|||
{ |
|||
ctest << " could not find environment variable ETHEREUM_TEST_PATH \n"; |
|||
testPath = "../../../tests"; |
|||
} |
|||
else |
|||
testPath = ptestPath; |
|||
|
|||
return testPath; |
|||
} |
|||
|
|||
int dev::test::randomNumber() |
|||
{ |
|||
static std::mt19937 randomGenerator(time(0)); |
|||
randomGenerator.seed(std::random_device()()); |
|||
return std::uniform_int_distribution<int>(1)(randomGenerator); |
|||
} |
|||
|
|||
Json::Value dev::test::loadJsonFromFile(std::string const& _path) |
|||
{ |
|||
Json::Reader reader; |
|||
Json::Value result; |
|||
string s = dev::contentsString(_path); |
|||
if (!s.length()) |
|||
ctest << "Contents of " + _path + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"; |
|||
else |
|||
ctest << "FIXTURE: loaded test from file: " << _path; |
|||
|
|||
reader.parse(s, result); |
|||
return result; |
|||
} |
|||
|
|||
std::string dev::test::toTestFilePath(std::string const& _filename) |
|||
{ |
|||
return getTestPath() + "/" + _filename + ".json"; |
|||
} |
|||
|
|||
std::string dev::test::getFolder(std::string const& _file) |
|||
{ |
|||
return boost::filesystem::path(_file).parent_path().string(); |
|||
} |
|||
|
|||
std::string dev::test::getRandomPath() |
|||
{ |
|||
std::stringstream stream; |
|||
stream << getDataDir("EthereumTests") << "/" << randomNumber(); |
|||
return stream.str(); |
|||
} |
|||
|
@ -1,45 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Common.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <json/json.h> |
|||
#include <libdevcore/Log.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
struct TestChannel: public LogChannel { static const char* name(); }; |
|||
#define ctest dev::LogOutputStream<dev::test::TestChannel, true>() |
|||
|
|||
std::string getTestPath(); |
|||
int randomNumber(); |
|||
Json::Value loadJsonFromFile(std::string const& _path); |
|||
std::string toTestFilePath(std::string const& _filename); |
|||
std::string getFolder(std::string const& _file); |
|||
std::string getRandomPath(); |
|||
|
|||
} |
|||
|
|||
} |
@ -1,34 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file FixedClient.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "FixedClient.h" |
|||
|
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
using namespace dev::test; |
|||
|
|||
Block FixedClient::asOf(h256 const& _h) const |
|||
{ |
|||
ReadGuard l(x_stateDB); |
|||
Block ret(m_block.db()); |
|||
ret.populateFromChain(bc(), _h); |
|||
return ret; |
|||
} |
@ -1,61 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file FixedClient.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libethereum/ClientBase.h> |
|||
#include <libethereum/BlockChain.h> |
|||
#include <libethereum/State.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
/**
|
|||
* @brief mvp implementation of ClientBase |
|||
* Doesn't support mining interface |
|||
*/ |
|||
class FixedClient: public dev::eth::ClientBase |
|||
{ |
|||
public: |
|||
FixedClient(eth::BlockChain const& _bc, eth::Block const& _block) : m_bc(_bc), m_block(_block) {} |
|||
virtual ~FixedClient() {} |
|||
|
|||
// stub
|
|||
virtual void flushTransactions() override {} |
|||
virtual eth::BlockChain& bc() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("FixedClient::bc()")); } |
|||
virtual eth::BlockChain const& bc() const override { return m_bc; } |
|||
using ClientBase::asOf; |
|||
virtual eth::Block asOf(h256 const& _h) const override; |
|||
virtual eth::Block preMine() const override { ReadGuard l(x_stateDB); return m_block; } |
|||
virtual eth::Block postMine() const override { ReadGuard l(x_stateDB); return m_block; } |
|||
virtual void setBeneficiary(Address _us) override { WriteGuard l(x_stateDB); m_block.setBeneficiary(_us); } |
|||
virtual void prepareForTransaction() override {} |
|||
|
|||
private: |
|||
eth::BlockChain const& m_bc; |
|||
eth::Block m_block; |
|||
mutable SharedMutex x_stateDB; ///< Lock on the state DB, effectively a lock on m_postMine.
|
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,27 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file FixedWebThreeStubServer.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "FixedWebThreeServer.h" |
|||
#include <libethereum/Interface.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace eth; |
@ -1,61 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file FixedWebThreeStubServer.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libdevcore/Exceptions.h> |
|||
#include <libweb3jsonrpc/WebThreeStubServerBase.h> |
|||
#include <libweb3jsonrpc/AccountHolder.h> |
|||
|
|||
/**
|
|||
* @brief dummy JSON-RPC api implementation |
|||
* Should be used for test purposes only |
|||
* Supports eth && db interfaces |
|||
* Doesn't support shh && net interfaces |
|||
*/ |
|||
class FixedWebThreeServer: public dev::WebThreeStubServerBase, public dev::WebThreeStubDatabaseFace |
|||
{ |
|||
public: |
|||
FixedWebThreeServer(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _allAccounts, dev::eth::Interface* _client): |
|||
WebThreeStubServerBase(_conn, std::make_shared<dev::eth::FixedAccountHolder>([=](){return _client;}, _allAccounts), _allAccounts), |
|||
m_client(_client) |
|||
{} |
|||
|
|||
private: |
|||
dev::eth::Interface* client() override { return m_client; } |
|||
std::shared_ptr<dev::shh::Interface> face() override { BOOST_THROW_EXCEPTION(dev::InterfaceNotSupported("dev::shh::Interface")); } |
|||
dev::WebThreeNetworkFace* network() override { BOOST_THROW_EXCEPTION(dev::InterfaceNotSupported("dev::WebThreeNetworkFace")); } |
|||
dev::WebThreeStubDatabaseFace* db() override { return this; } |
|||
std::string get(std::string const& _name, std::string const& _key) override |
|||
{ |
|||
std::string k(_name + "/" + _key); |
|||
return m_db[k]; |
|||
} |
|||
void put(std::string const& _name, std::string const& _key, std::string const& _value) override |
|||
{ |
|||
std::string k(_name + "/" + _key); |
|||
m_db[k] = _value; |
|||
} |
|||
|
|||
private: |
|||
dev::eth::Interface* m_client; |
|||
std::map<std::string, std::string> m_db; |
|||
}; |
@ -1,113 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRC_LIST) |
|||
|
|||
macro (add_sources) |
|||
file (RELATIVE_PATH _relPath "${CMAKE_SOURCE_DIR}/test" "${CMAKE_CURRENT_SOURCE_DIR}") |
|||
foreach (_src ${ARGN}) |
|||
if (_relPath) |
|||
list (APPEND SRC "${_relPath}/${_src}") |
|||
else() |
|||
list (APPEND SRC "${_src}") |
|||
endif() |
|||
endforeach() |
|||
if (_relPath) |
|||
# propagate SRCS to parent directory |
|||
set (SRC ${SRC} PARENT_SCOPE) |
|||
endif() |
|||
endmacro() |
|||
|
|||
add_subdirectory(fuzzTesting) |
|||
add_subdirectory(libdevcore) |
|||
add_subdirectory(libdevcrypto) |
|||
add_subdirectory(libethcore) |
|||
add_subdirectory(libethereum) |
|||
add_subdirectory(libevm) |
|||
add_subdirectory(libnatspec) |
|||
add_subdirectory(libp2p) |
|||
add_subdirectory(external-dependencies) |
|||
|
|||
if (JSCONSOLE) |
|||
add_subdirectory(libjsengine) |
|||
endif() |
|||
|
|||
if (JSONRPC) |
|||
add_subdirectory(libweb3jsonrpc) |
|||
endif () |
|||
add_subdirectory(libwhisper) |
|||
|
|||
set(SRC_LIST ${SRC_LIST} ${SRC}) |
|||
|
|||
include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) |
|||
include_directories(BEFORE ..) |
|||
include_directories(${Boost_INCLUDE_DIRS}) |
|||
include_directories(${CRYPTOPP_INCLUDE_DIRS}) |
|||
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
|||
|
|||
if (JSCONSOLE) |
|||
include_directories(${V8_INCLUDE_DIRS}) |
|||
endif() |
|||
|
|||
# search for test names and create ctest tests |
|||
enable_testing() |
|||
foreach(file ${SRC_LIST}) |
|||
file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE)") |
|||
set(TestSuite "DEFAULT") |
|||
foreach(test_raw ${test_list_raw}) |
|||
string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) |
|||
if(test MATCHES "^SUITE .*") |
|||
string(SUBSTRING ${test} 6 -1 TestSuite) |
|||
elseif(test MATCHES "^CASE .*") |
|||
string(SUBSTRING ${test} 5 -1 TestCase) |
|||
add_test(NAME ${TestSuite}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth -t ${TestSuite}/${TestCase}) |
|||
endif(test MATCHES "^SUITE .*") |
|||
endforeach(test_raw) |
|||
endforeach(file) |
|||
|
|||
file(GLOB HEADERS "*.h") |
|||
add_executable(testeth ${SRC_LIST} ${HEADERS}) |
|||
|
|||
target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) |
|||
target_link_libraries(testeth ${CURL_LIBRARIES}) |
|||
target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) |
|||
target_link_libraries(testeth ethereum) |
|||
target_link_libraries(testeth ethcore) |
|||
if (NOT WIN32) |
|||
target_link_libraries(testeth secp256k1) |
|||
endif () |
|||
|
|||
if (JSCONSOLE) |
|||
target_link_libraries(testeth jsengine) |
|||
endif() |
|||
|
|||
target_link_libraries(testeth testutils) |
|||
|
|||
if (GUI AND NOT JUSTTESTS) |
|||
target_link_libraries(testeth webthree) |
|||
target_link_libraries(testeth natspec) |
|||
endif() |
|||
|
|||
if (JSONRPC) |
|||
target_link_libraries(testeth web3jsonrpc) |
|||
target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) |
|||
endif() |
|||
|
|||
enable_testing() |
|||
set(CTEST_OUTPUT_ON_FAILURE TRUE) |
|||
|
|||
include(EthUtils) |
|||
|
|||
eth_add_test(ClientBase |
|||
ARGS --eth_testfile=BlockTests/bcJS_API_Test --eth_threads=1 |
|||
ARGS --eth_testfile=BlockTests/bcJS_API_Test --eth_threads=3 |
|||
ARGS --eth_testfile=BlockTests/bcJS_API_Test --eth_threads=10 |
|||
ARGS --eth_testfile=BlockTests/bcValidBlockTest --eth_threads=1 |
|||
ARGS --eth_testfile=BlockTests/bcValidBlockTest --eth_threads=3 |
|||
ARGS --eth_testfile=BlockTests/bcValidBlockTest --eth_threads=10 |
|||
) |
|||
|
|||
eth_add_test(JsonRpc |
|||
ARGS --eth_testfile=BlockTests/bcJS_API_Test |
|||
ARGS --eth_testfile=BlockTests/bcValidBlockTest |
|||
) |
|||
|
@ -1,120 +0,0 @@ |
|||
contract JSON_Test { |
|||
event Log0(uint value) ; |
|||
event Log0Anonym (uint value) anonymous; |
|||
event Log1(bool indexed aBool, uint value); |
|||
event Log1Anonym(bool indexed aBool, uint value) anonymous; |
|||
event Log2(bool indexed aBool, address indexed aAddress, uint value); |
|||
event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) anonymous; |
|||
event Log3(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value); |
|||
event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) anonymous; |
|||
event Log4(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value); |
|||
event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) anonymous; |
|||
|
|||
function JSON_Test() { |
|||
} |
|||
|
|||
function setBool(bool _bool) { |
|||
myBool = _bool; |
|||
} |
|||
|
|||
function setInt8(int8 _int8) { |
|||
myInt8 = _int8; |
|||
} |
|||
|
|||
function setUint8(uint8 _uint8) { |
|||
myUint8 = _uint8; |
|||
} |
|||
|
|||
function setInt256(int256 _int256) { |
|||
myInt256 = _int256; |
|||
} |
|||
|
|||
function setUint256(uint256 _uint256) { |
|||
myUint256 = _uint256; |
|||
} |
|||
|
|||
function setAddress(address _address) { |
|||
myAddress = _address; |
|||
} |
|||
|
|||
function setBytes32(bytes32 _bytes32) { |
|||
myBytes32 = _bytes32; |
|||
} |
|||
|
|||
function getBool() returns (bool ret) { |
|||
return myBool; |
|||
} |
|||
|
|||
function getInt8() returns (int8 ret) { |
|||
return myInt8; |
|||
} |
|||
|
|||
function getUint8() returns (uint8 ret) { |
|||
return myUint8; |
|||
} |
|||
|
|||
function getInt256() returns (int256 ret) { |
|||
return myInt256; |
|||
} |
|||
|
|||
function getUint256() returns (uint256 ret) { |
|||
return myUint256; |
|||
} |
|||
|
|||
function getAddress() returns (address ret) { |
|||
return myAddress; |
|||
} |
|||
|
|||
function getBytes32() returns (bytes32 ret) { |
|||
return myBytes32; |
|||
} |
|||
|
|||
function fireEventLog0() { |
|||
Log0(42); |
|||
} |
|||
|
|||
function fireEventLog0Anonym() { |
|||
Log0Anonym(42); |
|||
} |
|||
|
|||
function fireEventLog1() { |
|||
Log1(true, 42); |
|||
} |
|||
|
|||
function fireEventLog1Anonym() { |
|||
Log1Anonym(true, 42); |
|||
} |
|||
|
|||
function fireEventLog2() { |
|||
Log2(true, msg.sender, 42); |
|||
} |
|||
|
|||
function fireEventLog2Anonym() { |
|||
Log2Anonym(true, msg.sender, 42); |
|||
} |
|||
|
|||
function fireEventLog3() { |
|||
Log3(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42); |
|||
} |
|||
|
|||
function fireEventLog3Anonym() { |
|||
Log3Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42); |
|||
} |
|||
|
|||
function fireEventLog4() { |
|||
Log4(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42); |
|||
} |
|||
|
|||
function fireEventLog4Anonym() { |
|||
Log4Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42); |
|||
} |
|||
|
|||
bool myBool; |
|||
int8 myInt8; |
|||
uint8 myUint8; |
|||
int256 myInt256; |
|||
uint256 myUint256; |
|||
address myAddress; |
|||
bytes32 myBytes32; |
|||
} |
|||
|
@ -1,100 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "Stats.h" |
|||
|
|||
#include <iterator> |
|||
#include <numeric> |
|||
#include <fstream> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
Stats& Stats::get() |
|||
{ |
|||
static Stats instance; |
|||
return instance; |
|||
} |
|||
|
|||
void Stats::suiteStarted(std::string const& _name) |
|||
{ |
|||
m_currentSuite = _name; |
|||
} |
|||
|
|||
void Stats::testStarted(std::string const& _name) |
|||
{ |
|||
m_currentTest = _name; |
|||
m_tp = clock::now(); |
|||
} |
|||
|
|||
void Stats::testFinished() |
|||
{ |
|||
m_stats.push_back({clock::now() - m_tp, m_currentSuite + "/" + m_currentTest}); |
|||
} |
|||
|
|||
std::ostream& operator<<(std::ostream& out, Stats::clock::duration const& d) |
|||
{ |
|||
return out << std::setw(10) << std::right << std::chrono::duration_cast<std::chrono::microseconds>(d).count() << " us"; |
|||
} |
|||
|
|||
Stats::~Stats() |
|||
{ |
|||
if (m_stats.empty()) |
|||
return; |
|||
|
|||
std::sort(m_stats.begin(), m_stats.end(), [](Stats::Item const& a, Stats::Item const& b){ |
|||
return a.duration < b.duration; |
|||
}); |
|||
|
|||
auto& out = std::cout; |
|||
auto itr = m_stats.begin(); |
|||
auto min = *itr; |
|||
auto max = *m_stats.rbegin(); |
|||
std::advance(itr, m_stats.size() / 2); |
|||
auto med = *itr; |
|||
auto tot = std::accumulate(m_stats.begin(), m_stats.end(), clock::duration{}, [](clock::duration const& a, Stats::Item const& v) |
|||
{ |
|||
return a + v.duration; |
|||
}); |
|||
|
|||
out << "\nSTATS:\n\n" << std::setfill(' '); |
|||
|
|||
if (Options::get().statsOutFile == "out") |
|||
{ |
|||
for (auto&& s: m_stats) |
|||
out << " " << std::setw(40) << std::left << s.name.substr(0, 40) << s.duration << " \n"; |
|||
out << "\n"; |
|||
} |
|||
else if (!Options::get().statsOutFile.empty()) |
|||
{ |
|||
// Output stats to file
|
|||
std::ofstream file{Options::get().statsOutFile}; |
|||
for (auto&& s: m_stats) |
|||
file << s.name << "\t" << std::chrono::duration_cast<std::chrono::microseconds>(s.duration).count() << "\n"; |
|||
} |
|||
|
|||
out << " tot: " << tot << "\n" |
|||
<< " avg: " << (tot / m_stats.size()) << "\n\n" |
|||
<< " min: " << min.duration << " (" << min.name << ")\n" |
|||
<< " med: " << med.duration << " (" << med.name << ")\n" |
|||
<< " max: " << max.duration << " (" << max.name << ")\n"; |
|||
} |
|||
|
|||
} |
|||
} |
@ -1,57 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <chrono> |
|||
#include <vector> |
|||
|
|||
#include "TestHelper.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
class Stats: public Listener |
|||
{ |
|||
public: |
|||
using clock = std::chrono::high_resolution_clock; |
|||
|
|||
struct Item |
|||
{ |
|||
clock::duration duration; |
|||
std::string name; |
|||
}; |
|||
|
|||
static Stats& get(); |
|||
|
|||
~Stats(); |
|||
|
|||
void suiteStarted(std::string const& _name) override; |
|||
void testStarted(std::string const& _name) override; |
|||
void testFinished() override; |
|||
|
|||
private: |
|||
clock::time_point m_tp; |
|||
std::string m_currentSuite; |
|||
std::string m_currentTest; |
|||
std::vector<Item> m_stats; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,894 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TestHelper.cpp
|
|||
* @author Marko Simovic <markobarko@gmail.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "TestHelper.h" |
|||
|
|||
#include <thread> |
|||
#include <chrono> |
|||
#include <libethcore/EthashAux.h> |
|||
#include <libethereum/Client.h> |
|||
#include <libevm/ExtVMFace.h> |
|||
#include <liblll/Compiler.h> |
|||
#include <libevm/VMFactory.h> |
|||
#include "Stats.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
void mine(Client& c, int numBlocks) |
|||
{ |
|||
auto startBlock = c.blockChain().details().number; |
|||
|
|||
c.startMining(); |
|||
while(c.blockChain().details().number < startBlock + numBlocks) |
|||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
|||
c.stopMining(); |
|||
} |
|||
|
|||
void connectClients(Client& c1, Client& c2) |
|||
{ |
|||
(void)c1; |
|||
(void)c2; |
|||
// TODO: Move to WebThree. eth::Client no longer handles networking.
|
|||
#if 0 |
|||
short c1Port = 20000; |
|||
short c2Port = 21000; |
|||
c1.startNetwork(c1Port); |
|||
c2.startNetwork(c2Port); |
|||
c2.connect("127.0.0.1", c1Port); |
|||
#endif |
|||
} |
|||
|
|||
void mine(Block& s, BlockChain const& _bc) |
|||
{ |
|||
std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine()); |
|||
s.commitToSeal(_bc); |
|||
Notified<bytes> sealed; |
|||
sealer->onSealGenerated([&](bytes const& sealedHeader){ sealed = sealedHeader; }); |
|||
sealer->generateSeal(s.info()); |
|||
sealed.waitNot({}); |
|||
sealer.reset(); |
|||
s.sealBlock(sealed); |
|||
} |
|||
|
|||
void mine(Ethash::BlockHeader& _bi) |
|||
{ |
|||
std::unique_ptr<SealEngineFace> sealer(Ethash::createSealEngine()); |
|||
Notified<bytes> sealed; |
|||
sealer->onSealGenerated([&](bytes const& sealedHeader){ sealed = sealedHeader; }); |
|||
sealer->generateSeal(_bi); |
|||
sealed.waitNot({}); |
|||
sealer.reset(); |
|||
_bi = Ethash::BlockHeader(sealed, CheckNothing, h256{}, HeaderData); |
|||
} |
|||
|
|||
} |
|||
|
|||
namespace test |
|||
{ |
|||
|
|||
struct ValueTooLarge: virtual Exception {}; |
|||
struct MissingFields : virtual Exception {}; |
|||
|
|||
bigint const c_max256plus1 = bigint(1) << 256; |
|||
|
|||
ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate): |
|||
m_statePre(OverlayDB(), eth::BaseState::Empty), |
|||
m_statePost(OverlayDB(), eth::BaseState::Empty), |
|||
m_testObject(_o) |
|||
{ |
|||
if (testTemplate == testType::StateTests) |
|||
{ |
|||
importEnv(_o["env"].get_obj()); |
|||
importTransaction(_o["transaction"].get_obj()); |
|||
importState(_o["pre"].get_obj(), m_statePre); |
|||
if (!isFiller) |
|||
{ |
|||
if (_o.count("post")) |
|||
importState(_o["post"].get_obj(), m_statePost); |
|||
else |
|||
importState(_o["postState"].get_obj(), m_statePost); |
|||
m_logsExpected = importLog(_o["logs"].get_array()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
//executes an imported transacton on preState
|
|||
bytes ImportTest::executeTest() |
|||
{ |
|||
ExecutionResult res; |
|||
eth::State tmpState = m_statePre; |
|||
try |
|||
{ |
|||
std::pair<ExecutionResult, TransactionReceipt> execOut = m_statePre.execute(m_envInfo, m_transaction); |
|||
res = execOut.first; |
|||
m_logs = execOut.second.log(); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
cnote << "Exception: " << diagnostic_information(_e); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
cnote << "state execution exception: " << _e.what(); |
|||
} |
|||
|
|||
m_statePre.commit(); |
|||
m_statePost = m_statePre; |
|||
m_statePre = tmpState; |
|||
|
|||
return res.output; |
|||
} |
|||
|
|||
json_spirit::mObject& ImportTest::makeAllFieldsHex(json_spirit::mObject& _o) |
|||
{ |
|||
static const set<string> hashes {"bloom" , "coinbase", "hash", "mixHash", "parentHash", "receiptTrie", |
|||
"stateRoot", "transactionsTrie", "uncleHash", "currentCoinbase", |
|||
"previousHash", "to", "address", "caller", "origin", "secretKey", "data"}; |
|||
|
|||
for (auto& i: _o) |
|||
{ |
|||
std::string key = i.first; |
|||
if (hashes.count(key)) |
|||
continue; |
|||
|
|||
std::string str; |
|||
json_spirit::mValue value = i.second; |
|||
|
|||
if (value.type() == json_spirit::int_type) |
|||
str = toString(value.get_int()); |
|||
else if (value.type() == json_spirit::str_type) |
|||
str = value.get_str(); |
|||
else continue; |
|||
|
|||
_o[key] = (str.substr(0, 2) == "0x") ? str : toCompactHex(toInt(str), HexPrefix::Add, 1); |
|||
} |
|||
return _o; |
|||
} |
|||
|
|||
void ImportTest::importEnv(json_spirit::mObject& _o) |
|||
{ |
|||
assert(_o.count("currentGasLimit") > 0); |
|||
assert(_o.count("currentDifficulty") > 0); |
|||
assert(_o.count("currentNumber") > 0); |
|||
assert(_o.count("currentTimestamp") > 0); |
|||
assert(_o.count("currentCoinbase") > 0); |
|||
m_envInfo.setGasLimit(toInt(_o["currentGasLimit"])); |
|||
m_envInfo.setDifficulty(toInt(_o["currentDifficulty"])); |
|||
m_envInfo.setNumber(toInt(_o["currentNumber"])); |
|||
m_envInfo.setTimestamp(toInt(_o["currentTimestamp"])); |
|||
m_envInfo.setBeneficiary(Address(_o["currentCoinbase"].get_str())); |
|||
m_envInfo.setLastHashes( lastHashes( m_envInfo.number() ) ); |
|||
} |
|||
|
|||
// import state from not fully declared json_spirit::mObject, writing to _stateOptionsMap which fields were defined in json
|
|||
|
|||
void ImportTest::importState(json_spirit::mObject& _o, State& _state, AccountMaskMap& o_mask) |
|||
{ |
|||
std::string jsondata = json_spirit::write_string((json_spirit::mValue)_o, false); |
|||
_state.populateFrom(jsonToAccountMap(jsondata, &o_mask)); |
|||
} |
|||
|
|||
void ImportTest::importState(json_spirit::mObject& _o, State& _state) |
|||
{ |
|||
AccountMaskMap mask; |
|||
importState(_o, _state, mask); |
|||
for (auto const& i: mask) |
|||
//check that every parameter was declared in state object
|
|||
if (!i.second.allSet()) |
|||
BOOST_THROW_EXCEPTION(MissingFields() << errinfo_comment("Import State: Missing state fields!")); |
|||
} |
|||
|
|||
void ImportTest::importTransaction (json_spirit::mObject const& _o, eth::Transaction& o_tr) |
|||
{ |
|||
if (_o.count("secretKey") > 0) |
|||
{ |
|||
assert(_o.count("nonce") > 0); |
|||
assert(_o.count("gasPrice") > 0); |
|||
assert(_o.count("gasLimit") > 0); |
|||
assert(_o.count("to") > 0); |
|||
assert(_o.count("value") > 0); |
|||
assert(_o.count("data") > 0); |
|||
|
|||
if (bigint(_o.at("nonce").get_str()) >= c_max256plus1) |
|||
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); |
|||
if (bigint(_o.at("gasPrice").get_str()) >= c_max256plus1) |
|||
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasPrice' is equal or greater than 2**256") ); |
|||
if (bigint(_o.at("gasLimit").get_str()) >= c_max256plus1) |
|||
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'gasLimit' is equal or greater than 2**256") ); |
|||
if (bigint(_o.at("value").get_str()) >= c_max256plus1) |
|||
BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'value' is equal or greater than 2**256") ); |
|||
|
|||
o_tr = _o.at("to").get_str().empty() ? |
|||
Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), importData(_o), toInt(_o.at("nonce")), Secret(_o.at("secretKey").get_str())) : |
|||
Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), Address(_o.at("to").get_str()), importData(_o), toInt(_o.at("nonce")), Secret(_o.at("secretKey").get_str())); |
|||
} |
|||
else |
|||
{ |
|||
RLPStream transactionRLPStream = createRLPStreamFromTransactionFields(_o); |
|||
RLP transactionRLP(transactionRLPStream.out()); |
|||
try |
|||
{ |
|||
o_tr = Transaction(transactionRLP.data(), CheckTransaction::Everything); |
|||
} |
|||
catch (InvalidSignature) |
|||
{ |
|||
// create unsigned transaction
|
|||
o_tr = _o.at("to").get_str().empty() ? |
|||
Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), importData(_o), toInt(_o.at("nonce"))) : |
|||
Transaction(toInt(_o.at("value")), toInt(_o.at("gasPrice")), toInt(_o.at("gasLimit")), Address(_o.at("to").get_str()), importData(_o), toInt(_o.at("nonce"))); |
|||
} |
|||
catch (Exception& _e) |
|||
{ |
|||
cnote << "invalid transaction" << boost::diagnostic_information(_e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void ImportTest::importTransaction(json_spirit::mObject const& o_tr) |
|||
{ |
|||
importTransaction(o_tr, m_transaction); |
|||
} |
|||
|
|||
int ImportTest::compareStates(State const& _stateExpect, State const& _statePost, AccountMaskMap const _expectedStateOptions, WhenError _throw) |
|||
{ |
|||
#define CHECK(a,b) \ |
|||
{ \ |
|||
if (_throw == WhenError::Throw) \ |
|||
{ \ |
|||
BOOST_CHECK_MESSAGE(a, b); \ |
|||
if (!a) \ |
|||
return 1; \ |
|||
} \ |
|||
else \ |
|||
BOOST_WARN_MESSAGE(a,b); \ |
|||
} |
|||
|
|||
for (auto const& a: _stateExpect.addresses()) |
|||
{ |
|||
CHECK(_statePost.addressInUse(a.first), "Compare States: " << a.first << " missing expected address!"); |
|||
if (_statePost.addressInUse(a.first)) |
|||
{ |
|||
AccountMask addressOptions(true); |
|||
if(_expectedStateOptions.size()) |
|||
{ |
|||
try |
|||
{ |
|||
addressOptions = _expectedStateOptions.at(a.first); |
|||
} |
|||
catch(std::out_of_range const&) |
|||
{ |
|||
BOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (addressOptions.hasBalance()) |
|||
CHECK((_stateExpect.balance(a.first) == _statePost.balance(a.first)), |
|||
"Check State: " << a.first << ": incorrect balance " << _statePost.balance(a.first) << ", expected " << _stateExpect.balance(a.first)); |
|||
|
|||
if (addressOptions.hasNonce()) |
|||
CHECK((_stateExpect.transactionsFrom(a.first) == _statePost.transactionsFrom(a.first)), |
|||
"Check State: " << a.first << ": incorrect nonce " << _statePost.transactionsFrom(a.first) << ", expected " << _stateExpect.transactionsFrom(a.first)); |
|||
|
|||
if (addressOptions.hasStorage()) |
|||
{ |
|||
unordered_map<u256, u256> stateStorage = _statePost.storage(a.first); |
|||
for (auto const& s: _stateExpect.storage(a.first)) |
|||
CHECK((stateStorage[s.first] == s.second), |
|||
"Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(stateStorage[s.first]) << ", expected [" << s.first << "] = " << toHex(s.second)); |
|||
|
|||
//Check for unexpected storage values
|
|||
stateStorage = _stateExpect.storage(a.first); |
|||
for (auto const& s: _statePost.storage(a.first)) |
|||
CHECK((stateStorage[s.first] == s.second), |
|||
"Check State: " << a.first << ": incorrect storage [" << s.first << "] = " << toHex(s.second) << ", expected [" << s.first << "] = " << toHex(stateStorage[s.first])); |
|||
} |
|||
|
|||
if (addressOptions.hasCode()) |
|||
CHECK((_stateExpect.code(a.first) == _statePost.code(a.first)), |
|||
"Check State: " << a.first << ": incorrect code '" << toHex(_statePost.code(a.first)) << "', expected '" << toHex(_stateExpect.code(a.first)) << "'"); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
int ImportTest::exportTest(bytes const& _output) |
|||
{ |
|||
int err = 0; |
|||
// export output
|
|||
m_testObject["out"] = (_output.size() > 4096 && !Options::get().fulloutput) ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add); |
|||
|
|||
// compare expected output with post output
|
|||
if (m_testObject.count("expectOut") > 0) |
|||
{ |
|||
std::string warning = "Check State: Error! Unexpected output: " + m_testObject["out"].get_str() + " Expected: " + m_testObject["expectOut"].get_str(); |
|||
if (Options::get().checkState) |
|||
{ |
|||
bool statement = (m_testObject["out"].get_str() == m_testObject["expectOut"].get_str()); |
|||
BOOST_CHECK_MESSAGE(statement, warning); |
|||
if (!statement) |
|||
err = 1; |
|||
} |
|||
else |
|||
BOOST_WARN_MESSAGE(m_testObject["out"].get_str() == m_testObject["expectOut"].get_str(), warning); |
|||
|
|||
m_testObject.erase(m_testObject.find("expectOut")); |
|||
} |
|||
|
|||
// export logs
|
|||
m_testObject["logs"] = exportLog(m_logs); |
|||
|
|||
// compare expected state with post state
|
|||
if (m_testObject.count("expect") > 0) |
|||
{ |
|||
eth::AccountMaskMap stateMap; |
|||
State expectState(OverlayDB(), eth::BaseState::Empty); |
|||
importState(m_testObject["expect"].get_obj(), expectState, stateMap); |
|||
compareStates(expectState, m_statePost, stateMap, Options::get().checkState ? WhenError::Throw : WhenError::DontThrow); |
|||
m_testObject.erase(m_testObject.find("expect")); |
|||
} |
|||
|
|||
// export post state
|
|||
m_testObject["post"] = fillJsonWithState(m_statePost); |
|||
m_testObject["postStateRoot"] = toHex(m_statePost.rootHash().asBytes()); |
|||
|
|||
// export pre state
|
|||
m_testObject["pre"] = fillJsonWithState(m_statePre); |
|||
m_testObject["env"] = makeAllFieldsHex(m_testObject["env"].get_obj()); |
|||
m_testObject["transaction"] = makeAllFieldsHex(m_testObject["transaction"].get_obj()); |
|||
return err; |
|||
} |
|||
|
|||
json_spirit::mObject fillJsonWithTransaction(Transaction _txn) |
|||
{ |
|||
json_spirit::mObject txObject; |
|||
txObject["nonce"] = toCompactHex(_txn.nonce(), HexPrefix::Add, 1); |
|||
txObject["data"] = toHex(_txn.data(), 2, HexPrefix::Add); |
|||
txObject["gasLimit"] = toCompactHex(_txn.gas(), HexPrefix::Add, 1); |
|||
txObject["gasPrice"] = toCompactHex(_txn.gasPrice(), HexPrefix::Add, 1); |
|||
txObject["r"] = toCompactHex(_txn.signature().r, HexPrefix::Add, 1); |
|||
txObject["s"] = toCompactHex(_txn.signature().s, HexPrefix::Add, 1); |
|||
txObject["v"] = toCompactHex(_txn.signature().v + 27, HexPrefix::Add, 1); |
|||
txObject["to"] = _txn.isCreation() ? "" : toString(_txn.receiveAddress()); |
|||
txObject["value"] = toCompactHex(_txn.value(), HexPrefix::Add, 1); |
|||
return txObject; |
|||
} |
|||
|
|||
json_spirit::mObject fillJsonWithState(State _state) |
|||
{ |
|||
json_spirit::mObject oState; |
|||
for (auto const& a: _state.addresses()) |
|||
{ |
|||
json_spirit::mObject o; |
|||
o["balance"] = toCompactHex(_state.balance(a.first), HexPrefix::Add, 1); |
|||
o["nonce"] = toCompactHex(_state.transactionsFrom(a.first), HexPrefix::Add, 1); |
|||
{ |
|||
json_spirit::mObject store; |
|||
for (auto const& s: _state.storage(a.first)) |
|||
store[toCompactHex(s.first, HexPrefix::Add, 1)] = toCompactHex(s.second, HexPrefix::Add, 1); |
|||
o["storage"] = store; |
|||
} |
|||
o["code"] = toHex(_state.code(a.first), 2, HexPrefix::Add); |
|||
oState[toString(a.first)] = o; |
|||
} |
|||
return oState; |
|||
} |
|||
|
|||
json_spirit::mArray exportLog(eth::LogEntries _logs) |
|||
{ |
|||
json_spirit::mArray ret; |
|||
if (_logs.size() == 0) return ret; |
|||
for (LogEntry const& l: _logs) |
|||
{ |
|||
json_spirit::mObject o; |
|||
o["address"] = toString(l.address); |
|||
json_spirit::mArray topics; |
|||
for (auto const& t: l.topics) |
|||
topics.push_back(toString(t)); |
|||
o["topics"] = topics; |
|||
o["data"] = toHex(l.data, 2, HexPrefix::Add); |
|||
o["bloom"] = toString(l.bloom()); |
|||
ret.push_back(o); |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
u256 toInt(json_spirit::mValue const& _v) |
|||
{ |
|||
switch (_v.type()) |
|||
{ |
|||
case json_spirit::str_type: return u256(_v.get_str()); |
|||
case json_spirit::int_type: return (u256)_v.get_uint64(); |
|||
case json_spirit::bool_type: return (u256)(uint64_t)_v.get_bool(); |
|||
case json_spirit::real_type: return (u256)(uint64_t)_v.get_real(); |
|||
default: cwarn << "Bad type for scalar: " << _v.type(); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
byte toByte(json_spirit::mValue const& _v) |
|||
{ |
|||
switch (_v.type()) |
|||
{ |
|||
case json_spirit::str_type: return (byte)stoi(_v.get_str()); |
|||
case json_spirit::int_type: return (byte)_v.get_uint64(); |
|||
case json_spirit::bool_type: return (byte)_v.get_bool(); |
|||
case json_spirit::real_type: return (byte)_v.get_real(); |
|||
default: cwarn << "Bad type for scalar: " << _v.type(); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
bytes importByteArray(std::string const& _str) |
|||
{ |
|||
return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, WhenError::Throw); |
|||
} |
|||
|
|||
bytes importData(json_spirit::mObject const& _o) |
|||
{ |
|||
bytes data; |
|||
if (_o.at("data").type() == json_spirit::str_type) |
|||
data = importByteArray(_o.at("data").get_str()); |
|||
else |
|||
for (auto const& j: _o.at("data").get_array()) |
|||
data.push_back(toByte(j)); |
|||
return data; |
|||
} |
|||
|
|||
bytes importCode(json_spirit::mObject& _o) |
|||
{ |
|||
bytes code; |
|||
if (_o["code"].type() == json_spirit::str_type) |
|||
if (_o["code"].get_str().find("0x") != 0) |
|||
code = compileLLL(_o["code"].get_str(), false); |
|||
else |
|||
code = fromHex(_o["code"].get_str().substr(2)); |
|||
else if (_o["code"].type() == json_spirit::array_type) |
|||
{ |
|||
code.clear(); |
|||
for (auto const& j: _o["code"].get_array()) |
|||
code.push_back(toByte(j)); |
|||
} |
|||
return code; |
|||
} |
|||
|
|||
LogEntries importLog(json_spirit::mArray& _a) |
|||
{ |
|||
LogEntries logEntries; |
|||
for (auto const& l: _a) |
|||
{ |
|||
json_spirit::mObject o = l.get_obj(); |
|||
// cant use BOOST_REQUIRE, because this function is used outside boost test (createRandomTest)
|
|||
assert(o.count("address") > 0); |
|||
assert(o.count("topics") > 0); |
|||
assert(o.count("data") > 0); |
|||
assert(o.count("bloom") > 0); |
|||
LogEntry log; |
|||
log.address = Address(o["address"].get_str()); |
|||
for (auto const& t: o["topics"].get_array()) |
|||
log.topics.push_back(h256(t.get_str())); |
|||
log.data = importData(o); |
|||
logEntries.push_back(log); |
|||
} |
|||
return logEntries; |
|||
} |
|||
|
|||
void checkOutput(bytes const& _output, json_spirit::mObject& _o) |
|||
{ |
|||
int j = 0; |
|||
|
|||
if (_o["out"].get_str().find("#") == 0) |
|||
BOOST_CHECK((u256)_output.size() == toInt(_o["out"].get_str().substr(1))); |
|||
else if (_o["out"].type() == json_spirit::array_type) |
|||
for (auto const& d: _o["out"].get_array()) |
|||
{ |
|||
BOOST_CHECK_MESSAGE(_output[j] == toInt(d), "Output byte [" << j << "] different!"); |
|||
++j; |
|||
} |
|||
else if (_o["out"].get_str().find("0x") == 0) |
|||
BOOST_CHECK(_output == fromHex(_o["out"].get_str().substr(2))); |
|||
else |
|||
BOOST_CHECK(_output == fromHex(_o["out"].get_str())); |
|||
} |
|||
|
|||
void checkStorage(map<u256, u256> _expectedStore, map<u256, u256> _resultStore, Address _expectedAddr) |
|||
{ |
|||
_expectedAddr = _expectedAddr; //unsed parametr when macro
|
|||
for (auto&& expectedStorePair : _expectedStore) |
|||
{ |
|||
auto& expectedStoreKey = expectedStorePair.first; |
|||
auto resultStoreIt = _resultStore.find(expectedStoreKey); |
|||
if (resultStoreIt == _resultStore.end()) |
|||
BOOST_ERROR(_expectedAddr << ": missing store key " << expectedStoreKey); |
|||
else |
|||
{ |
|||
auto& expectedStoreValue = expectedStorePair.second; |
|||
auto& resultStoreValue = resultStoreIt->second; |
|||
BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue); |
|||
} |
|||
} |
|||
BOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size()); |
|||
for (auto&& resultStorePair: _resultStore) |
|||
{ |
|||
if (!_expectedStore.count(resultStorePair.first)) |
|||
BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); |
|||
} |
|||
} |
|||
|
|||
void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) |
|||
{ |
|||
BOOST_REQUIRE_EQUAL(_resultLogs.size(), _expectedLogs.size()); |
|||
|
|||
for (size_t i = 0; i < _resultLogs.size(); ++i) |
|||
{ |
|||
BOOST_CHECK_EQUAL(_resultLogs[i].address, _expectedLogs[i].address); |
|||
BOOST_CHECK_EQUAL(_resultLogs[i].topics, _expectedLogs[i].topics); |
|||
BOOST_CHECK(_resultLogs[i].data == _expectedLogs[i].data); |
|||
} |
|||
} |
|||
|
|||
void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates) |
|||
{ |
|||
BOOST_REQUIRE_EQUAL(_resultCallCreates.size(), _expectedCallCreates.size()); |
|||
|
|||
for (size_t i = 0; i < _resultCallCreates.size(); ++i) |
|||
{ |
|||
BOOST_CHECK(_resultCallCreates[i].data() == _expectedCallCreates[i].data()); |
|||
BOOST_CHECK(_resultCallCreates[i].receiveAddress() == _expectedCallCreates[i].receiveAddress()); |
|||
BOOST_CHECK(_resultCallCreates[i].gas() == _expectedCallCreates[i].gas()); |
|||
BOOST_CHECK(_resultCallCreates[i].value() == _expectedCallCreates[i].value()); |
|||
} |
|||
} |
|||
|
|||
void userDefinedTest(std::function<void(json_spirit::mValue&, bool)> doTests) |
|||
{ |
|||
if (!Options::get().singleTest) |
|||
return; |
|||
|
|||
if (Options::get().singleTestFile.empty() || Options::get().singleTestName.empty()) |
|||
{ |
|||
cnote << "Missing user test specification\nUsage: testeth --singletest <filename> <testname>\n"; |
|||
return; |
|||
} |
|||
|
|||
auto& filename = Options::get().singleTestFile; |
|||
auto& testname = Options::get().singleTestName; |
|||
|
|||
if (g_logVerbosity != -1) |
|||
VerbosityHolder sentinel(12); |
|||
|
|||
try |
|||
{ |
|||
cnote << "Testing user defined test: " << filename; |
|||
json_spirit::mValue v; |
|||
string s = contentsString(filename); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. "); |
|||
json_spirit::read_string(s, v); |
|||
json_spirit::mObject oSingleTest; |
|||
|
|||
json_spirit::mObject::const_iterator pos = v.get_obj().find(testname); |
|||
if (pos == v.get_obj().end()) |
|||
{ |
|||
cnote << "Could not find test: " << testname << " in " << filename << "\n"; |
|||
return; |
|||
} |
|||
else |
|||
oSingleTest[pos->first] = pos->second; |
|||
|
|||
json_spirit::mValue v_singleTest(oSingleTest); |
|||
doTests(v_singleTest, test::Options::get().fillTests); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed Test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
|
|||
void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function<void(json_spirit::mValue&, bool)> doTests) |
|||
{ |
|||
string testPath = getTestPath(); |
|||
testPath += _testPathAppendix; |
|||
|
|||
if (Options::get().stats) |
|||
Listener::registerListener(Stats::get()); |
|||
|
|||
if (Options::get().fillTests) |
|||
{ |
|||
try |
|||
{ |
|||
cnote << "Populating tests..."; |
|||
json_spirit::mValue v; |
|||
boost::filesystem::path p(__FILE__); |
|||
string s = asString(dev::contents(_pathToFiller.string() + "/" + _name + "Filler.json")); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + _pathToFiller.string() + "/" + _name + "Filler.json is empty."); |
|||
json_spirit::read_string(s, v); |
|||
doTests(v, true); |
|||
writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true))); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed filling test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed filling test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
|
|||
try |
|||
{ |
|||
cnote << "TEST " << _name << ":"; |
|||
json_spirit::mValue v; |
|||
string s = asString(dev::contents(testPath + "/" + _name + ".json")); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + testPath + "/" + _name + ".json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); |
|||
json_spirit::read_string(s, v); |
|||
Listener::notifySuiteStarted(_name); |
|||
doTests(v, false); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
|
|||
RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const& _tObj) |
|||
{ |
|||
//Construct Rlp of the given transaction
|
|||
RLPStream rlpStream; |
|||
rlpStream.appendList(_tObj.size()); |
|||
|
|||
if (_tObj.count("nonce")) |
|||
rlpStream << bigint(_tObj.at("nonce").get_str()); |
|||
|
|||
if (_tObj.count("gasPrice")) |
|||
rlpStream << bigint(_tObj.at("gasPrice").get_str()); |
|||
|
|||
if (_tObj.count("gasLimit")) |
|||
rlpStream << bigint(_tObj.at("gasLimit").get_str()); |
|||
|
|||
if (_tObj.count("to")) |
|||
{ |
|||
if (_tObj.at("to").get_str().empty()) |
|||
rlpStream << ""; |
|||
else |
|||
rlpStream << importByteArray(_tObj.at("to").get_str()); |
|||
} |
|||
|
|||
if (_tObj.count("value")) |
|||
rlpStream << bigint(_tObj.at("value").get_str()); |
|||
|
|||
if (_tObj.count("data")) |
|||
rlpStream << importData(_tObj); |
|||
|
|||
if (_tObj.count("v")) |
|||
rlpStream << bigint(_tObj.at("v").get_str()); |
|||
|
|||
if (_tObj.count("r")) |
|||
rlpStream << bigint(_tObj.at("r").get_str()); |
|||
|
|||
if (_tObj.count("s")) |
|||
rlpStream << bigint(_tObj.at("s").get_str()); |
|||
|
|||
if (_tObj.count("extrafield")) |
|||
rlpStream << bigint(_tObj.at("extrafield").get_str()); |
|||
|
|||
return rlpStream; |
|||
} |
|||
|
|||
Options::Options() |
|||
{ |
|||
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) |
|||
{ |
|||
auto arg = std::string{argv[i]}; |
|||
if (arg == "--vm" && i + 1 < argc) |
|||
{ |
|||
string vmKind = argv[++i]; |
|||
if (vmKind == "interpreter") |
|||
VMFactory::setKind(VMKind::Interpreter); |
|||
else if (vmKind == "jit") |
|||
VMFactory::setKind(VMKind::JIT); |
|||
else if (vmKind == "smart") |
|||
VMFactory::setKind(VMKind::Smart); |
|||
else |
|||
cerr << "Unknown VM kind: " << vmKind << endl; |
|||
} |
|||
else if (arg == "--jit") // TODO: Remove deprecated option "--jit"
|
|||
VMFactory::setKind(VMKind::JIT); |
|||
else if (arg == "--vmtrace") |
|||
vmtrace = true; |
|||
else if (arg == "--filltests") |
|||
fillTests = true; |
|||
else if (arg == "--stats" && i + 1 < argc) |
|||
{ |
|||
stats = true; |
|||
statsOutFile = argv[i + 1]; |
|||
} |
|||
else if (arg == "--performance") |
|||
performance = true; |
|||
else if (arg == "--quadratic") |
|||
quadratic = true; |
|||
else if (arg == "--memory") |
|||
memory = true; |
|||
else if (arg == "--inputlimits") |
|||
inputLimits = true; |
|||
else if (arg == "--bigdata") |
|||
bigData = true; |
|||
else if (arg == "--checkstate") |
|||
checkState = true; |
|||
else if (arg == "--wallet") |
|||
wallet = true; |
|||
else if (arg == "--nonetwork") |
|||
nonetwork = true; |
|||
else if (arg == "--network") |
|||
nonetwork = false; |
|||
else if (arg == "--nodag") |
|||
nodag = true; |
|||
else if (arg == "--all") |
|||
{ |
|||
performance = true; |
|||
quadratic = true; |
|||
memory = true; |
|||
inputLimits = true; |
|||
bigData = true; |
|||
wallet = true; |
|||
} |
|||
else if (arg == "--singletest" && i + 1 < argc) |
|||
{ |
|||
singleTest = true; |
|||
auto name1 = std::string{argv[i + 1]}; |
|||
if (i + 1 < argc) // two params
|
|||
{ |
|||
auto name2 = std::string{argv[i + 2]}; |
|||
if (name2[0] == '-') // not param, another option
|
|||
singleTestName = std::move(name1); |
|||
else |
|||
{ |
|||
singleTestFile = std::move(name1); |
|||
singleTestName = std::move(name2); |
|||
} |
|||
} |
|||
else |
|||
singleTestName = std::move(name1); |
|||
} |
|||
else if (arg == "--fulloutput") |
|||
fulloutput = true; |
|||
else if (arg == "--verbosity" && i + 1 < argc) |
|||
{ |
|||
static std::ostringstream strCout; //static string to redirect logs to
|
|||
std::string indentLevel = std::string{argv[i + 1]}; |
|||
if (indentLevel == "0") |
|||
{ |
|||
logVerbosity = Verbosity::None; |
|||
std::cout.rdbuf(strCout.rdbuf()); |
|||
std::cerr.rdbuf(strCout.rdbuf()); |
|||
} |
|||
else if (indentLevel == "1") |
|||
logVerbosity = Verbosity::NiceReport; |
|||
else |
|||
logVerbosity = Verbosity::Full; |
|||
} |
|||
else if (arg == "--createRandomTest") |
|||
createRandomTest = true; |
|||
} |
|||
|
|||
//Default option
|
|||
if (logVerbosity == Verbosity::NiceReport) |
|||
g_logVerbosity = -1; //disable cnote but leave cerr and cout
|
|||
} |
|||
|
|||
Options const& Options::get() |
|||
{ |
|||
static Options instance; |
|||
return instance; |
|||
} |
|||
|
|||
LastHashes lastHashes(u256 _currentBlockNumber) |
|||
{ |
|||
LastHashes ret; |
|||
for (u256 i = 1; i <= 256 && i <= _currentBlockNumber; ++i) |
|||
ret.push_back(sha3(toString(_currentBlockNumber - i))); |
|||
return ret; |
|||
} |
|||
|
|||
dev::eth::Ethash::BlockHeader constructHeader( |
|||
h256 const& _parentHash, |
|||
h256 const& _sha3Uncles, |
|||
Address const& _coinbaseAddress, |
|||
h256 const& _stateRoot, |
|||
h256 const& _transactionsRoot, |
|||
h256 const& _receiptsRoot, |
|||
dev::eth::LogBloom const& _logBloom, |
|||
u256 const& _difficulty, |
|||
u256 const& _number, |
|||
u256 const& _gasLimit, |
|||
u256 const& _gasUsed, |
|||
u256 const& _timestamp, |
|||
bytes const& _extraData) |
|||
{ |
|||
RLPStream rlpStream; |
|||
rlpStream.appendList(Ethash::BlockHeader::Fields); |
|||
|
|||
rlpStream << _parentHash << _sha3Uncles << _coinbaseAddress << _stateRoot << _transactionsRoot << _receiptsRoot << _logBloom |
|||
<< _difficulty << _number << _gasLimit << _gasUsed << _timestamp << _extraData << h256{} << Nonce{}; |
|||
|
|||
return Ethash::BlockHeader(rlpStream.out(), CheckNothing, h256{}, HeaderData); |
|||
} |
|||
|
|||
void updateEthashSeal(dev::eth::Ethash::BlockHeader& _header, h256 const& _mixHash, dev::eth::Nonce const& _nonce) |
|||
{ |
|||
RLPStream source; |
|||
_header.streamRLP(source); |
|||
RLP sourceRlp(source.out()); |
|||
RLPStream header; |
|||
header.appendList(Ethash::BlockHeader::Fields); |
|||
for (size_t i = 0; i < BlockInfo::BasicFields; i++) |
|||
header << sourceRlp[i]; |
|||
|
|||
header << _mixHash << _nonce; |
|||
_header = Ethash::BlockHeader(header.out(), CheckNothing, h256{}, HeaderData); |
|||
} |
|||
|
|||
namespace |
|||
{ |
|||
Listener* g_listener; |
|||
} |
|||
|
|||
void Listener::registerListener(Listener& _listener) |
|||
{ |
|||
g_listener = &_listener; |
|||
} |
|||
|
|||
void Listener::notifySuiteStarted(std::string const& _name) |
|||
{ |
|||
if (g_listener) |
|||
g_listener->suiteStarted(_name); |
|||
} |
|||
|
|||
void Listener::notifyTestStarted(std::string const& _name) |
|||
{ |
|||
if (g_listener) |
|||
g_listener->testStarted(_name); |
|||
} |
|||
|
|||
void Listener::notifyTestFinished() |
|||
{ |
|||
if (g_listener) |
|||
g_listener->testFinished(); |
|||
} |
|||
|
|||
} } // namespaces
|
@ -1,259 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TestHelper.h
|
|||
* @author Marko Simovic <markobarko@gmail.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <functional> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <boost/filesystem.hpp> |
|||
|
|||
#include "JsonSpiritHeaders.h" |
|||
#include <libethcore/Ethash.h> |
|||
#include <libethereum/State.h> |
|||
#include <libevm/ExtVMFace.h> |
|||
#include <libtestutils/Common.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace eth |
|||
{ |
|||
|
|||
class Client; |
|||
class State; |
|||
|
|||
void mine(Client& c, int numBlocks); |
|||
void connectClients(Client& c1, Client& c2); |
|||
void mine(Block& _s, BlockChain const& _bc); |
|||
void mine(Ethash::BlockHeader& _bi); |
|||
|
|||
} |
|||
|
|||
namespace test |
|||
{ |
|||
|
|||
/// Make sure that no Exception is thrown during testing. If one is thrown show its info and fail the test.
|
|||
/// Our version of BOOST_REQUIRE_NO_THROW()
|
|||
/// @param _statenent The statement for which to make sure no exceptions are thrown
|
|||
/// @param _message A message to act as a prefix to the expression's error information
|
|||
#define ETH_TEST_REQUIRE_NO_THROW(_statement, _message) \ |
|||
do \ |
|||
{ \ |
|||
try \ |
|||
{ \ |
|||
BOOST_TEST_PASSPOINT(); \ |
|||
_statement; \ |
|||
} \ |
|||
catch (boost::exception const& _e) \ |
|||
{ \ |
|||
auto msg = std::string(_message " due to an exception thrown by " \ |
|||
BOOST_STRINGIZE(_statement) "\n") + boost::diagnostic_information(_e); \ |
|||
BOOST_CHECK_IMPL(false, msg, REQUIRE, CHECK_MSG); \ |
|||
} \ |
|||
catch (...) \ |
|||
{ \ |
|||
BOOST_CHECK_IMPL(false, "Unknown exception thrown by " \ |
|||
BOOST_STRINGIZE(_statement), REQUIRE, CHECK_MSG); \ |
|||
} \ |
|||
} \ |
|||
while (0) |
|||
|
|||
/// Check if an Exception is thrown during testing. If one is thrown show its info and continue the test
|
|||
/// Our version of BOOST_CHECK_NO_THROW()
|
|||
/// @param _statement The statement for which to make sure no exceptions are thrown
|
|||
/// @param _message A message to act as a prefix to the expression's error information
|
|||
#define ETH_TEST_CHECK_NO_THROW(_statement, _message) \ |
|||
do \ |
|||
{ \ |
|||
try \ |
|||
{ \ |
|||
BOOST_TEST_PASSPOINT(); \ |
|||
_statement; \ |
|||
} \ |
|||
catch (boost::exception const& _e) \ |
|||
{ \ |
|||
auto msg = std::string(_message " due to an exception thrown by " \ |
|||
BOOST_STRINGIZE(_statement) "\n") + boost::diagnostic_information(_e); \ |
|||
BOOST_CHECK_IMPL(false, msg, CHECK, CHECK_MSG); \ |
|||
} \ |
|||
catch (...) \ |
|||
{ \ |
|||
BOOST_CHECK_IMPL(false, "Unknown exception thrown by " \ |
|||
BOOST_STRINGIZE(_statement), CHECK, CHECK_MSG ); \ |
|||
} \ |
|||
} \ |
|||
while (0) |
|||
|
|||
enum class testType |
|||
{ |
|||
StateTests, |
|||
BlockChainTests, |
|||
Other |
|||
}; |
|||
|
|||
class ImportTest |
|||
{ |
|||
public: |
|||
ImportTest(json_spirit::mObject& _o, bool isFiller, testType testTemplate = testType::StateTests); |
|||
|
|||
// imports
|
|||
void importEnv(json_spirit::mObject& _o); |
|||
static void importState(json_spirit::mObject& _o, eth::State& _state); |
|||
static void importState(json_spirit::mObject& _o, eth::State& _state, eth::AccountMaskMap& o_mask); |
|||
static void importTransaction (json_spirit::mObject const& _o, eth::Transaction& o_tr); |
|||
void importTransaction(json_spirit::mObject const& _o); |
|||
static json_spirit::mObject& makeAllFieldsHex(json_spirit::mObject& _o); |
|||
|
|||
bytes executeTest(); |
|||
int exportTest(bytes const& _output); |
|||
static int compareStates(eth::State const& _stateExpect, eth::State const& _statePost, eth::AccountMaskMap const _expectedStateOptions = eth::AccountMaskMap(), WhenError _throw = WhenError::Throw); |
|||
|
|||
eth::State m_statePre; |
|||
eth::State m_statePost; |
|||
eth::EnvInfo m_envInfo; |
|||
eth::Transaction m_transaction; |
|||
eth::LogEntries m_logs; |
|||
eth::LogEntries m_logsExpected; |
|||
|
|||
private: |
|||
json_spirit::mObject& m_testObject; |
|||
}; |
|||
|
|||
class ZeroGasPricer: public eth::GasPricer |
|||
{ |
|||
protected: |
|||
u256 ask(eth::Block const&) const override { return 0; } |
|||
u256 bid(eth::TransactionPriority = eth::TransactionPriority::Medium) const override { return 0; } |
|||
}; |
|||
|
|||
// helping functions
|
|||
u256 toInt(json_spirit::mValue const& _v); |
|||
byte toByte(json_spirit::mValue const& _v); |
|||
bytes importCode(json_spirit::mObject& _o); |
|||
bytes importData(json_spirit::mObject const& _o); |
|||
bytes importByteArray(std::string const& _str); |
|||
eth::LogEntries importLog(json_spirit::mArray& _o); |
|||
json_spirit::mArray exportLog(eth::LogEntries _logs); |
|||
void checkOutput(bytes const& _output, json_spirit::mObject& _o); |
|||
void checkStorage(std::map<u256, u256> _expectedStore, std::map<u256, u256> _resultStore, Address _expectedAddr); |
|||
void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs); |
|||
void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates); |
|||
dev::eth::Ethash::BlockHeader constructHeader( |
|||
h256 const& _parentHash, |
|||
h256 const& _sha3Uncles, |
|||
Address const& _coinbaseAddress, |
|||
h256 const& _stateRoot, |
|||
h256 const& _transactionsRoot, |
|||
h256 const& _receiptsRoot, |
|||
dev::eth::LogBloom const& _logBloom, |
|||
u256 const& _difficulty, |
|||
u256 const& _number, |
|||
u256 const& _gasLimit, |
|||
u256 const& _gasUsed, |
|||
u256 const& _timestamp, |
|||
bytes const& _extraData); |
|||
void updateEthashSeal(dev::eth::Ethash::BlockHeader& _header, h256 const& _mixHash, dev::eth::Nonce const& _nonce); |
|||
void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function<void(json_spirit::mValue&, bool)> doTests); |
|||
void userDefinedTest(std::function<void(json_spirit::mValue&, bool)> doTests); |
|||
RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject const& _tObj); |
|||
eth::LastHashes lastHashes(u256 _currentBlockNumber); |
|||
json_spirit::mObject fillJsonWithState(eth::State _state); |
|||
json_spirit::mObject fillJsonWithTransaction(eth::Transaction _txn); |
|||
|
|||
//Fill Test Functions
|
|||
int createRandomTest(std::vector<char*> const& args); |
|||
void doTransactionTests(json_spirit::mValue& _v, bool _fillin); |
|||
void doStateTests(json_spirit::mValue& v, bool _fillin); |
|||
void doVMTests(json_spirit::mValue& v, bool _fillin); |
|||
void doBlockchainTests(json_spirit::mValue& _v, bool _fillin); |
|||
void doRlpTests(json_spirit::mValue& v, bool _fillin); |
|||
|
|||
enum class Verbosity |
|||
{ |
|||
Full, |
|||
NiceReport, |
|||
None |
|||
}; |
|||
|
|||
class Options |
|||
{ |
|||
public: |
|||
bool vmtrace = false; ///< Create EVM execution tracer // TODO: Link with log verbosity?
|
|||
bool fillTests = false; ///< Create JSON test files from execution results
|
|||
bool stats = false; ///< Execution time stats
|
|||
std::string statsOutFile; ///< Stats output file. "out" for standard output
|
|||
bool checkState = false;///< Throw error when checking test states
|
|||
bool fulloutput = false;///< Replace large output to just it's length
|
|||
bool createRandomTest = false; ///< Generate random test
|
|||
Verbosity logVerbosity = Verbosity::NiceReport; |
|||
|
|||
/// Test selection
|
|||
/// @{
|
|||
bool singleTest = false; |
|||
std::string singleTestFile; |
|||
std::string singleTestName; |
|||
bool performance = false; |
|||
bool quadratic = false; |
|||
bool memory = false; |
|||
bool inputLimits = false; |
|||
bool bigData = false; |
|||
bool wallet = false; |
|||
bool nonetwork = true; |
|||
bool nodag = true; |
|||
/// @}
|
|||
|
|||
/// Get reference to options
|
|||
/// The first time used, options are parsed
|
|||
static Options const& get(); |
|||
|
|||
private: |
|||
Options(); |
|||
Options(Options const&) = delete; |
|||
}; |
|||
|
|||
/// Allows observing test execution process.
|
|||
/// This class also provides methods for registering and notifying the listener
|
|||
class Listener |
|||
{ |
|||
public: |
|||
virtual ~Listener() = default; |
|||
|
|||
virtual void suiteStarted(std::string const&) {} |
|||
virtual void testStarted(std::string const& _name) = 0; |
|||
virtual void testFinished() = 0; |
|||
|
|||
static void registerListener(Listener& _listener); |
|||
static void notifySuiteStarted(std::string const& _name); |
|||
static void notifyTestStarted(std::string const& _name); |
|||
static void notifyTestFinished(); |
|||
|
|||
/// Test started/finished notification RAII helper
|
|||
class ExecTimeGuard |
|||
{ |
|||
public: |
|||
ExecTimeGuard(std::string const& _testName) { notifyTestStarted(_testName); } |
|||
~ExecTimeGuard() { notifyTestFinished(); } |
|||
ExecTimeGuard(ExecTimeGuard const&) = delete; |
|||
ExecTimeGuard& operator=(ExecTimeGuard) = delete; |
|||
}; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,122 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TestUtils.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <thread> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <boost/filesystem.hpp> |
|||
#include <libdevcrypto/Common.h> |
|||
#include <libtestutils/Common.h> |
|||
#include <libtestutils/BlockChainLoader.h> |
|||
#include <libtestutils/FixedClient.h> |
|||
#include "TestUtils.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
using namespace dev::test; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
bool getCommandLineOption(std::string const& _name); |
|||
std::string getCommandLineArgument(std::string const& _name, bool _require = false); |
|||
|
|||
} |
|||
} |
|||
|
|||
bool dev::test::getCommandLineOption(string const& _name) |
|||
{ |
|||
auto argc = boost::unit_test::framework::master_test_suite().argc; |
|||
auto argv = boost::unit_test::framework::master_test_suite().argv; |
|||
bool result = false; |
|||
for (auto i = 0; !result && i < argc; ++i) |
|||
result = _name == argv[i]; |
|||
return result; |
|||
} |
|||
|
|||
std::string dev::test::getCommandLineArgument(string const& _name, bool _require) |
|||
{ |
|||
auto argc = boost::unit_test::framework::master_test_suite().argc; |
|||
auto argv = boost::unit_test::framework::master_test_suite().argv; |
|||
for (auto i = 1; i < argc; ++i) |
|||
{ |
|||
string str = argv[i]; |
|||
if (_name == str.substr(0, _name.size())) |
|||
return str.substr(str.find("=") + 1); |
|||
} |
|||
if (_require) |
|||
BOOST_ERROR("Failed getting command line argument: " << _name << " from: " << argv); |
|||
return ""; |
|||
} |
|||
|
|||
LoadTestFileFixture::LoadTestFileFixture() |
|||
{ |
|||
m_json = loadJsonFromFile(toTestFilePath(getCommandLineArgument("--eth_testfile"))); |
|||
} |
|||
|
|||
void ParallelFixture::enumerateThreads(std::function<void()> callback) const |
|||
{ |
|||
size_t threadsCount = std::stoul(getCommandLineArgument("--eth_threads"), nullptr, 10); |
|||
|
|||
vector<thread> workers; |
|||
for (size_t i = 0; i < threadsCount; i++) |
|||
workers.emplace_back(callback); |
|||
|
|||
for_each(workers.begin(), workers.end(), [](thread &t) |
|||
{ |
|||
t.join(); |
|||
}); |
|||
} |
|||
|
|||
void BlockChainFixture::enumerateBlockchains(std::function<void(Json::Value const&, dev::eth::BlockChain const&, State state)> callback) const |
|||
{ |
|||
for (string const& name: m_json.getMemberNames()) |
|||
{ |
|||
BlockChainLoader bcl(m_json[name]); |
|||
callback(m_json[name], bcl.bc(), bcl.state()); |
|||
} |
|||
} |
|||
|
|||
void ClientBaseFixture::enumerateClients(std::function<void(Json::Value const&, dev::eth::ClientBase&)> callback) const |
|||
{ |
|||
enumerateBlockchains([&callback](Json::Value const& _json, BlockChain const& _bc, State _state) -> void |
|||
{ |
|||
cerr << "void ClientBaseFixture::enumerateClients. FixedClient now accepts block not sate!" << endl; |
|||
_state.commit(); //unused variable. remove this line
|
|||
FixedClient client(_bc, eth::Block {}); |
|||
callback(_json, client); |
|||
}); |
|||
} |
|||
|
|||
void ParallelClientBaseFixture::enumerateClients(std::function<void(Json::Value const&, dev::eth::ClientBase&)> callback) const |
|||
{ |
|||
ClientBaseFixture::enumerateClients([this, &callback](Json::Value const& _json, dev::eth::ClientBase& _client) -> void |
|||
{ |
|||
// json is being copied here
|
|||
enumerateThreads([callback, _json, &_client]() -> void |
|||
{ |
|||
callback(_json, _client); |
|||
}); |
|||
}); |
|||
} |
|||
|
@ -1,83 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TestUtils.h
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <functional> |
|||
#include <string> |
|||
#include <json/json.h> |
|||
#include <libdevcore/TransientDirectory.h> |
|||
#include <libethereum/BlockChain.h> |
|||
#include <libethereum/ClientBase.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
// should be used for multithread tests
|
|||
static SharedMutex x_boostTest; |
|||
#define ETH_CHECK_EQUAL(x, y) { dev::WriteGuard(x_boostTest); BOOST_CHECK_EQUAL(x, y); } |
|||
#define ETH_CHECK_EQUAL_COLLECTIONS(xb, xe, yb, ye) { dev::WriteGuard(x_boostTest); BOOST_CHECK_EQUAL_COLLECTIONS(xb, xe, yb, ye); } |
|||
#define ETH_REQUIRE(x) { dev::WriteGuard(x_boostTest); BOOST_REQUIRE(x); } |
|||
|
|||
struct LoadTestFileFixture |
|||
{ |
|||
LoadTestFileFixture(); |
|||
|
|||
protected: |
|||
Json::Value m_json; |
|||
}; |
|||
|
|||
struct ParallelFixture |
|||
{ |
|||
void enumerateThreads(std::function<void()> callback) const; |
|||
}; |
|||
|
|||
struct BlockChainFixture: public LoadTestFileFixture |
|||
{ |
|||
void enumerateBlockchains(std::function<void(Json::Value const&, dev::eth::BlockChain const&, dev::eth::State state)> callback) const; |
|||
}; |
|||
|
|||
struct ClientBaseFixture: public BlockChainFixture |
|||
{ |
|||
void enumerateClients(std::function<void(Json::Value const&, dev::eth::ClientBase&)> callback) const; |
|||
}; |
|||
|
|||
// important BOOST TEST do have problems with thread safety!!!
|
|||
// BOOST_CHECK is not thread safe
|
|||
// BOOST_MESSAGE is not thread safe
|
|||
// http://boost.2283326.n4.nabble.com/Is-boost-test-thread-safe-td3471644.html
|
|||
// http://lists.boost.org/boost-users/2010/03/57691.php
|
|||
// worth reading
|
|||
// https://codecrafter.wordpress.com/2012/11/01/c-unit-test-framework-adapter-part-3/
|
|||
struct ParallelClientBaseFixture: public ClientBaseFixture, public ParallelFixture |
|||
{ |
|||
void enumerateClients(std::function<void(Json::Value const&, dev::eth::ClientBase&)> callback) const; |
|||
}; |
|||
|
|||
struct JsonRpcFixture: public ClientBaseFixture |
|||
{ |
|||
|
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,118 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file boostTest.cpp
|
|||
* @author Dimitry Khokhlov <dimitry@ethdev.com> |
|||
* @date 2015 |
|||
* Stub for generating main boost.test module. |
|||
* Original code taken from boost sources. |
|||
*/ |
|||
|
|||
#define BOOST_TEST_MODULE EthereumTests |
|||
#pragma GCC diagnostic push |
|||
#pragma GCC diagnostic ignored "-Wunused-parameter" |
|||
//#define BOOST_DISABLE_WIN32 //disables SEH warning
|
|||
#define BOOST_TEST_NO_MAIN |
|||
#include <boost/test/included/unit_test.hpp> |
|||
#pragma GCC diagnostic pop |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace boost::unit_test; |
|||
|
|||
std::vector<char*> originalArgs; |
|||
static std::ostringstream strCout; |
|||
std::streambuf* oldCoutStreamBuf; |
|||
|
|||
//Custom Boost Initialization
|
|||
test_suite* init_func(int argc, char* argv[]) |
|||
{ |
|||
//Required for boost. -nowarning
|
|||
(void) argc; |
|||
(void) argv; |
|||
|
|||
//restore output for creating test
|
|||
std::cout.rdbuf(oldCoutStreamBuf); |
|||
std::cerr.rdbuf(oldCoutStreamBuf); |
|||
const auto& opt = dev::test::Options::get(); |
|||
if (opt.createRandomTest) |
|||
{ |
|||
//For no reason BOOST tend to remove valuable arg -t "TestSuiteName", so using original parametrs instead
|
|||
if (dev::test::createRandomTest(originalArgs)) |
|||
throw framework::internal_error("Create Random Test Error!"); |
|||
else |
|||
{ |
|||
//disable post output so the test json would be clean
|
|||
std::cout.rdbuf(strCout.rdbuf()); |
|||
std::cerr.rdbuf(strCout.rdbuf()); |
|||
throw framework::nothing_to_test(); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
//Custom Boost Unit Test Main
|
|||
int main( int argc, char* argv[] ) |
|||
{ |
|||
for (int i = 0; i < argc; i++) |
|||
originalArgs.push_back(argv[i]); |
|||
|
|||
//disable initial output
|
|||
oldCoutStreamBuf = std::cout.rdbuf(); |
|||
std::cout.rdbuf(strCout.rdbuf()); |
|||
std::cerr.rdbuf(strCout.rdbuf()); |
|||
|
|||
try |
|||
{ |
|||
framework::init(init_func, argc, argv); |
|||
|
|||
if( !runtime_config::test_to_run().is_empty() ) |
|||
{ |
|||
test_case_filter filter(runtime_config::test_to_run()); |
|||
|
|||
traverse_test_tree(framework::master_test_suite().p_id, filter); |
|||
} |
|||
|
|||
framework::run(); |
|||
|
|||
results_reporter::make_report(); |
|||
|
|||
return runtime_config::no_result_code() |
|||
? boost::exit_success |
|||
: results_collector.results(framework::master_test_suite().p_id).result_code(); |
|||
} |
|||
catch (framework::nothing_to_test const&) |
|||
{ |
|||
return boost::exit_success; |
|||
} |
|||
catch (framework::internal_error const& ex) |
|||
{ |
|||
results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl; |
|||
|
|||
return boost::exit_exception_failure; |
|||
} |
|||
catch (framework::setup_error const& ex) |
|||
{ |
|||
results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl; |
|||
|
|||
return boost::exit_exception_failure; |
|||
} |
|||
catch (...) |
|||
{ |
|||
results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl; |
|||
|
|||
return boost::exit_exception_failure; |
|||
} |
|||
} |
@ -1,61 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file fork.cpp
|
|||
* @author Marko Simovic <markobarko@gmail.com> |
|||
* @date 2014 |
|||
* Tests for different forking behavior |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <boost/filesystem/operations.hpp> |
|||
|
|||
#include <libethereum/Client.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <libethereum/EthereumHost.h> |
|||
#include "TestHelper.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
// Disabled since tests shouldn't block. Need a short cut to avoid real mining.
|
|||
/*
|
|||
BOOST_AUTO_TEST_CASE(simple_chain_fork) |
|||
{ |
|||
//start a client and mine a short chain
|
|||
Client c1("TestClient1", KeyPair::create().address(), |
|||
(boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
mine(c1, 4); |
|||
|
|||
//start another client and mine a longer chain
|
|||
Client c2("TestClient2", KeyPair::create().address(), |
|||
(boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
mine(c2, 6); |
|||
|
|||
//connect the two clients up to resolve chain
|
|||
c1.startNetwork(20000); |
|||
c2.startNetwork(21000); |
|||
c2.connect("127.0.0.1", 20000); |
|||
|
|||
//mine an extra block to cement it
|
|||
mine(c1, 1); |
|||
|
|||
//check the balances are where they should be
|
|||
//c1's chain should have been clobbered by c2
|
|||
BOOST_REQUIRE(c1.state().balance(c1.address()) == 0); |
|||
BOOST_REQUIRE(c2.state().balance(c2.address()) > 0); |
|||
} |
|||
*/ |
@ -1,21 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file kademlia.cpp
|
|||
* @author Alex Leverington <nessence@gmail.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
@ -1,54 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file main.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Main test functions. |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
|
|||
int trieTest(); |
|||
int rlpTest(); |
|||
int daggerTest(); |
|||
int cryptoTest(); |
|||
int stateTest(); |
|||
int vmTest(); |
|||
int hexPrefixTest(); |
|||
int peerTest(int argc, char** argv); |
|||
|
|||
#include <libdevcore/Log.h> |
|||
#include <libethcore/BlockInfo.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
//BOOST_AUTO_TEST_CASE(basic_tests)
|
|||
//{
|
|||
/* RLPStream s;
|
|||
BlockInfo::genesis().streamRLP(s, false); |
|||
std::cout << RLP(s.out()) << std::endl; |
|||
std::cout << toHex(s.out()) << std::endl; |
|||
std::cout << sha3(s.out()) << std::endl;*/ |
|||
|
|||
// int r = 0;
|
|||
// r += daggerTest();
|
|||
// r += stateTest();
|
|||
// r += peerTest(argc, argv);
|
|||
// BOOST_REQUIRE(!r);
|
|||
//}
|
|||
|
@ -1,122 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file txTest.cpp
|
|||
* @author Marko Simovic <markobarko@gmail.com> |
|||
* @date 2014 |
|||
* Simple peer transaction send test. |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <boost/filesystem/operations.hpp> |
|||
|
|||
#include <libethereum/Client.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <libethereum/EthereumHost.h> |
|||
#include "TestHelper.h" |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
// Disabled since tests shouldn't block. Need a short cut to avoid real mining.
|
|||
/*
|
|||
BOOST_AUTO_TEST_CASE(mine_local_simple_tx) |
|||
{ |
|||
KeyPair kp1 = KeyPair::create(); |
|||
KeyPair kp2 = KeyPair::create(); |
|||
|
|||
Client c1("TestClient1", kp1.address(), (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
|
|||
//mine some blocks so that client 1 has a balance
|
|||
mine(c1, 1); |
|||
auto c1bal = c1.state().balance(kp1.address()); |
|||
BOOST_REQUIRE(c1bal > 0); |
|||
|
|||
//send c2 some eth from c1
|
|||
auto txAmount = c1bal / 2u; |
|||
auto gasPrice = 10 * szabo; |
|||
auto gas = dev::eth::c_callGas; |
|||
c1.submitTransaction(kp1.secret(), txAmount, kp2.address(), bytes(), gas, gasPrice); |
|||
|
|||
//mine some more to include the transaction on chain
|
|||
mine(c1, 1); |
|||
auto c2bal = c1.state().balance(kp2.address()); |
|||
BOOST_REQUIRE(c2bal > 0); |
|||
BOOST_REQUIRE(c2bal == txAmount); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(mine_and_send_to_peer) |
|||
{ |
|||
KeyPair kp1 = KeyPair::create(); |
|||
KeyPair kp2 = KeyPair::create(); |
|||
|
|||
Client c1("TestClient1", kp1.address(), (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
Client c2("TestClient2", kp2.address(), (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
|
|||
connectClients(c1, c2); |
|||
|
|||
//mine some blocks so that client 1 has a balance
|
|||
mine(c1, 1); |
|||
auto c1bal = c1.state().balance(kp1.address()); |
|||
BOOST_REQUIRE(c1bal > 0); |
|||
|
|||
//send c2 some eth from c1
|
|||
auto txAmount = c1bal / 2u; |
|||
auto gasPrice = 10 * szabo; |
|||
auto gas = dev::eth::c_callGas; |
|||
c1.submitTransaction(kp1.secret(), txAmount, kp2.address(), bytes(), gas, gasPrice); |
|||
|
|||
//mine some more to include the transaction on chain
|
|||
mine(c1, 1); |
|||
auto c2bal = c2.state().balance(kp2.address()); |
|||
BOOST_REQUIRE(c2bal > 0); |
|||
BOOST_REQUIRE(c2bal == txAmount); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(mine_and_send_to_peer_fee_check) |
|||
{ |
|||
KeyPair kp1 = KeyPair::create(); |
|||
KeyPair kp2 = KeyPair::create(); |
|||
|
|||
Client c1("TestClient1", kp1.address(), (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
Client c2("TestClient2", kp2.address(), (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path()).string()); |
|||
|
|||
connectClients(c1, c2); |
|||
|
|||
//mine some blocks so that client 1 has a balance
|
|||
mine(c1, 1); |
|||
|
|||
auto c1StartBalance = c1.state().balance(kp1.address()); |
|||
auto c2StartBalance = c2.state().balance(kp2.address()); |
|||
BOOST_REQUIRE(c1StartBalance > 0); |
|||
BOOST_REQUIRE(c2StartBalance == 0); |
|||
|
|||
//send c2 some eth from c1
|
|||
auto txAmount = c1StartBalance / 2u; |
|||
auto gasPrice = 10 * szabo; |
|||
auto gas = dev::eth::c_callGas; |
|||
c1.submitTransaction(kp1.secret(), txAmount, c2.address(), bytes(), gas, gasPrice); |
|||
|
|||
//mine some more, this time with second client (so he can get fees from first client's tx)
|
|||
mine(c2, 1); |
|||
|
|||
auto c1EndBalance = c1.state().balance(kp1.address()); |
|||
auto c2EndBalance = c2.state().balance(kp2.address()); |
|||
BOOST_REQUIRE(c1EndBalance > 0); |
|||
BOOST_REQUIRE(c1EndBalance == c1StartBalance - txAmount - gasPrice * gas); |
|||
BOOST_REQUIRE(c2EndBalance > 0); |
|||
} |
|||
*/ |
@ -1,5 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRCS) |
|||
|
|||
add_sources(${SRCS}) |
@ -1,37 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file boost.cpp
|
|||
* @author Lefteris Karapetsas <lefteris@ethdev.com> |
|||
* @date 2015 |
|||
* Tests for external dependencies: Boost |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/Common.h> |
|||
|
|||
BOOST_AUTO_TEST_SUITE(ExtDepBoost) |
|||
|
|||
// test that reproduces issue https://github.com/ethereum/cpp-ethereum/issues/1977
|
|||
BOOST_AUTO_TEST_CASE(u256_overflow_test) |
|||
{ |
|||
dev::u256 a = 14; |
|||
dev::bigint b = dev::bigint("115792089237316195423570985008687907853269984665640564039457584007913129639948"); |
|||
// to fix cast `a` to dev::bigint
|
|||
BOOST_CHECK(a < b); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,5 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRCS) |
|||
|
|||
add_sources(${SRCS}) |
@ -1,463 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file createRandomTest.cpp
|
|||
* @author Dimitry Khokhlov <winsvega@mail.ru> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <string> |
|||
#include <iostream> |
|||
|
|||
#include <test/TestHelper.h> |
|||
#include <test/fuzzTesting/fuzzHelper.h> |
|||
#include <libevm/VMFactory.h> |
|||
#include <libdevcore/Common.h> |
|||
|
|||
//String Variables
|
|||
extern std::string const c_testExampleStateTest; |
|||
extern std::string const c_testExampleTransactionTest; |
|||
extern std::string const c_testExampleVMTest; |
|||
extern std::string const c_testExampleBlockchainTest; |
|||
extern std::string const c_testExampleRLPTest; |
|||
|
|||
//Main Test functinos
|
|||
void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, std::string const& _testString, bool _debug = false); |
|||
int checkRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, json_spirit::mValue& _value, bool _debug = false); |
|||
|
|||
//Helper Functions
|
|||
std::vector<std::string> getTypes(); |
|||
void parseTestWithTypes(std::string& test); |
|||
|
|||
namespace dev { namespace test { |
|||
int createRandomTest(std::vector<char*> const& args) |
|||
{ |
|||
std::string testSuite; |
|||
std::string testFillString; |
|||
json_spirit::mValue testmValue; |
|||
bool checktest = false; |
|||
bool filldebug = false; |
|||
bool debug = false; |
|||
bool filltest = false; |
|||
|
|||
for (unsigned i = 0; i < args.size(); ++i) |
|||
{ |
|||
auto arg = std::string{args.at(i)}; |
|||
dev::test::Options& options = const_cast<dev::test::Options&>(dev::test::Options::get()); |
|||
if (arg == "--fulloutput") |
|||
options.fulloutput = true; |
|||
else |
|||
if (arg == "-t" && i + 1 < args.size()) |
|||
{ |
|||
testSuite = args.at(i+1); |
|||
if (testSuite != "BlockChainTests" && testSuite != "TransactionTests" && testSuite != "StateTests" |
|||
&& testSuite != "VMTests" && testSuite != "RLPTests") |
|||
testSuite = ""; |
|||
} |
|||
else |
|||
if ((arg == "-checktest" || arg == "-filltest") && i + 1 < args.size()) |
|||
{ |
|||
std::string s; |
|||
for (unsigned j = i+1; j < args.size(); ++j) |
|||
s += args.at(j); |
|||
if (asserts(s.length() > 0)) |
|||
{ |
|||
std::cerr << "Error! Content of argument is empty! (Usage -checktest textstream)" << std::endl; |
|||
return 1; |
|||
} |
|||
if (arg == "-filltest") |
|||
{ |
|||
testFillString = s; |
|||
filltest = true; |
|||
} |
|||
else |
|||
{ |
|||
read_string(s, testmValue); |
|||
checktest = true; |
|||
} |
|||
} |
|||
else |
|||
if (arg == "--debug") |
|||
debug = true; |
|||
else |
|||
if (arg == "--filldebug") |
|||
filldebug = true; |
|||
} |
|||
|
|||
if (testSuite == "") |
|||
{ |
|||
std::cerr << "Error! Test suite not supported! (Usage -t TestSuite)" << std::endl; |
|||
return 1; |
|||
} |
|||
else |
|||
{ |
|||
if (checktest) |
|||
std::cout << "Testing: " << testSuite.substr(0, testSuite.length() - 1) << std::endl; |
|||
|
|||
if (testSuite == "BlockChainTests") |
|||
{ |
|||
if (checktest) |
|||
return checkRandomTest(dev::test::doBlockchainTests, testmValue, debug); |
|||
else |
|||
fillRandomTest(dev::test::doBlockchainTests, (filltest) ? testFillString : c_testExampleBlockchainTest, filldebug); |
|||
} |
|||
else |
|||
if (testSuite == "TransactionTests") |
|||
{ |
|||
if (checktest) |
|||
return checkRandomTest(dev::test::doTransactionTests, testmValue, debug); |
|||
else |
|||
fillRandomTest(dev::test::doTransactionTests, (filltest) ? testFillString : c_testExampleTransactionTest, filldebug); |
|||
} |
|||
else |
|||
if (testSuite == "StateTests") |
|||
{ |
|||
if (checktest) |
|||
return checkRandomTest(dev::test::doStateTests, testmValue, debug); |
|||
else |
|||
fillRandomTest(dev::test::doStateTests, (filltest) ? testFillString : c_testExampleStateTest, filldebug); |
|||
} |
|||
else |
|||
if (testSuite == "VMTests") |
|||
{ |
|||
if (checktest) |
|||
{ |
|||
dev::eth::VMFactory::setKind(dev::eth::VMKind::JIT); |
|||
return checkRandomTest(dev::test::doVMTests, testmValue, debug); |
|||
} |
|||
else |
|||
fillRandomTest(dev::test::doVMTests, (filltest) ? testFillString : c_testExampleVMTest, filldebug); |
|||
} |
|||
else |
|||
if (testSuite == "RLPTests") |
|||
{ |
|||
if (checktest) |
|||
return checkRandomTest(dev::test::doRlpTests, testmValue, debug); |
|||
else |
|||
fillRandomTest(dev::test::doRlpTests, (filltest) ? testFillString : c_testExampleRLPTest, filldebug); |
|||
} |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
}} //namespaces
|
|||
|
|||
int checkRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, json_spirit::mValue& _value, bool _debug) |
|||
{ |
|||
bool ret = 0; |
|||
try |
|||
{ |
|||
//redirect all output to the stream
|
|||
std::ostringstream strCout; |
|||
std::streambuf* oldCoutStreamBuf = std::cout.rdbuf(); |
|||
if (!_debug) |
|||
{ |
|||
std::cout.rdbuf( strCout.rdbuf() ); |
|||
std::cerr.rdbuf( strCout.rdbuf() ); |
|||
} |
|||
|
|||
_doTests(_value, false); |
|||
|
|||
//restroe output
|
|||
if (!_debug) |
|||
{ |
|||
std::cout.rdbuf(oldCoutStreamBuf); |
|||
std::cerr.rdbuf(oldCoutStreamBuf); |
|||
} |
|||
} |
|||
catch (dev::Exception const& _e) |
|||
{ |
|||
std::cout << "Failed test with Exception: " << diagnostic_information(_e) << std::endl; |
|||
ret = 1; |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
std::cout << "Failed test with Exception: " << _e.what() << std::endl; |
|||
ret = 1; |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
void fillRandomTest(std::function<void(json_spirit::mValue&, bool)> _doTests, std::string const& _testString, bool _debug) |
|||
{ |
|||
//redirect all output to the stream
|
|||
std::ostringstream strCout; |
|||
std::streambuf* oldCoutStreamBuf = std::cout.rdbuf(); |
|||
if (!_debug) |
|||
{ |
|||
std::cout.rdbuf( strCout.rdbuf() ); |
|||
std::cerr.rdbuf( strCout.rdbuf() ); |
|||
} |
|||
|
|||
json_spirit::mValue v; |
|||
try |
|||
{ |
|||
std::string newTest = _testString; |
|||
parseTestWithTypes(newTest); |
|||
json_spirit::read_string(newTest, v); |
|||
_doTests(v, true); |
|||
} |
|||
catch(...) |
|||
{ |
|||
std::cerr << "Test fill exception!"; |
|||
} |
|||
|
|||
//restroe output
|
|||
if (!_debug) |
|||
{ |
|||
std::cout.rdbuf(oldCoutStreamBuf); |
|||
std::cerr.rdbuf(oldCoutStreamBuf); |
|||
} |
|||
std::cout << json_spirit::write_string(v, true); |
|||
} |
|||
|
|||
/// Parse Test string replacing keywords to fuzzed values
|
|||
void parseTestWithTypes(std::string& _test) |
|||
{ |
|||
dev::test::RandomCodeOptions options; |
|||
options.setWeight(dev::eth::Instruction::STOP, 10); //default 50
|
|||
options.setWeight(dev::eth::Instruction::SSTORE, 70); |
|||
options.setWeight(dev::eth::Instruction::CALL, 75); |
|||
options.setWeight(dev::eth::Instruction::CALLCODE, 55); |
|||
options.addAddress(dev::Address("0xffffffffffffffffffffffffffffffffffffffff")); |
|||
options.addAddress(dev::Address("0x1000000000000000000000000000000000000000")); |
|||
options.addAddress(dev::Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87")); |
|||
options.addAddress(dev::Address("0x945304eb96065b2a98b57a48a06ae28d285a71b5")); |
|||
options.addAddress(dev::Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")); |
|||
options.addAddress(dev::Address("0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6")); |
|||
options.addAddress(dev::Address("0x0000000000000000000000000000000000000001")); |
|||
options.addAddress(dev::Address("0x0000000000000000000000000000000000000002")); |
|||
options.addAddress(dev::Address("0x0000000000000000000000000000000000000003")); |
|||
options.addAddress(dev::Address("0x0000000000000000000000000000000000000004")); |
|||
options.smartCodeProbability = 60; |
|||
|
|||
std::vector<std::string> types = getTypes(); |
|||
for (unsigned i = 0; i < types.size(); i++) |
|||
{ |
|||
std::size_t pos = _test.find(types.at(i)); |
|||
while (pos != std::string::npos) |
|||
{ |
|||
if (types.at(i) == "[RLP]") |
|||
{ |
|||
std::string debug; |
|||
int randomDepth = 1 + dev::test::RandomCode::randomUniInt() % 10; |
|||
_test.replace(pos, 5, dev::test::RandomCode::rndRLPSequence(randomDepth, debug)); |
|||
cnote << debug; |
|||
} |
|||
else |
|||
if (types.at(i) == "[CODE]") |
|||
_test.replace(pos, 6, "0x"+dev::test::RandomCode::generate(10, options)); |
|||
else |
|||
if (types.at(i) == "[HEX]") |
|||
_test.replace(pos, 5, dev::test::RandomCode::randomUniIntHex()); |
|||
else |
|||
if (types.at(i) == "[HEX32]") |
|||
_test.replace(pos, 7, dev::test::RandomCode::randomUniIntHex(std::numeric_limits<uint32_t>::max())); |
|||
else |
|||
if (types.at(i) == "[GASLIMIT]") |
|||
_test.replace(pos, 10, dev::test::RandomCode::randomUniIntHex(dev::u256("3000000000"))); |
|||
else |
|||
if (types.at(i) == "[HASH20]") |
|||
_test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(20)); |
|||
else |
|||
if (types.at(i) == "[0xHASH32]") |
|||
_test.replace(pos, 10, "0x" + dev::test::RandomCode::rndByteSequence(32)); |
|||
else |
|||
if (types.at(i) == "[HASH32]") |
|||
_test.replace(pos, 8, dev::test::RandomCode::rndByteSequence(32)); |
|||
else |
|||
if (types.at(i) == "[V]") |
|||
{ |
|||
int random = dev::test::RandomCode::randomUniInt() % 100; |
|||
if (random < 30) |
|||
_test.replace(pos, 3, "0x1c"); |
|||
else |
|||
if (random < 60) |
|||
_test.replace(pos, 3, "0x1d"); |
|||
else |
|||
_test.replace(pos, 3, "0x" + dev::test::RandomCode::rndByteSequence(1)); |
|||
} |
|||
|
|||
pos = _test.find(types.at(i)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
std::vector<std::string> getTypes() |
|||
{ |
|||
return {"[RLP]", "[CODE]", "[HEX]", "[HEX32]", "[HASH20]", "[HASH32]", "[0xHASH32]", "[V]", "[GASLIMIT]"}; |
|||
} |
|||
|
|||
std::string const c_testExampleTransactionTest = R"( |
|||
{ |
|||
"randomTransactionTest" : { |
|||
"transaction" : |
|||
{ |
|||
"data" : "[CODE]", |
|||
"gasLimit" : "[HEX]", |
|||
"gasPrice" : "[HEX]", |
|||
"nonce" : "[HEX]", |
|||
"to" : "[HASH20]", |
|||
"value" : "[HEX]", |
|||
"v" : "[V]", |
|||
"r" : "[0xHASH32]", |
|||
"s" : "[0xHASH32]" |
|||
} |
|||
} |
|||
} |
|||
)"; |
|||
|
|||
std::string const c_testExampleStateTest = R"( |
|||
{ |
|||
"randomStatetest" : { |
|||
"env" : { |
|||
"currentCoinbase" : "[HASH20]", |
|||
"currentDifficulty" : "[HEX]", |
|||
"currentGasLimit" : "[GASLIMIT]", |
|||
"currentNumber" : "[HEX32]", |
|||
"currentTimestamp" : "[HEX]", |
|||
"previousHash" : "[HASH32]" |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "[HEX]", |
|||
"code" : "[CODE]", |
|||
"nonce" : "[V]", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"945304eb96065b2a98b57a48a06ae28d285a71b5" : { |
|||
"balance" : "[HEX]", |
|||
"code" : "[CODE]", |
|||
"nonce" : "[V]", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "[HEX]", |
|||
"code" : "0x", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"data" : "[CODE]", |
|||
"gasLimit" : "[HEX]", |
|||
"gasPrice" : "[HEX32]", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "[HEX]" |
|||
} |
|||
} |
|||
} |
|||
)"; |
|||
|
|||
std::string const c_testExampleVMTest = R"( |
|||
{ |
|||
"randomVMTest": { |
|||
"env" : { |
|||
"previousHash" : "[HASH32]", |
|||
"currentNumber" : "[HEX]", |
|||
"currentGasLimit" : "[GASLIMIT]", |
|||
"currentDifficulty" : "[HEX]", |
|||
"currentTimestamp" : "[HEX]", |
|||
"currentCoinbase" : "[HASH20]" |
|||
}, |
|||
"pre" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"balance" : "[HEX]", |
|||
"nonce" : "[HEX]", |
|||
"code" : "[CODE]", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"exec" : { |
|||
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", |
|||
"origin" : "[HASH20]", |
|||
"caller" : "[HASH20]", |
|||
"value" : "[HEX]", |
|||
"data" : "[CODE]", |
|||
"gasPrice" : "[V]", |
|||
"gas" : "[HEX]" |
|||
} |
|||
} |
|||
} |
|||
)"; |
|||
|
|||
std::string const c_testExampleRLPTest = R"( |
|||
{ |
|||
"randomRLPTest" : { |
|||
"out" : "[RLP]" |
|||
} |
|||
} |
|||
)"; |
|||
|
|||
std::string const c_testExampleBlockchainTest = R"( |
|||
{ |
|||
"randomBlockTest" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "[HASH20]", |
|||
"difficulty" : "131072", |
|||
"extraData" : "[CODE]", |
|||
"gasLimit" : "3141592", |
|||
"gasUsed" : "0", |
|||
"mixHash" : "[0xHASH32]", |
|||
"nonce" : "0x0102030405060708", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "[0xHASH32]", |
|||
"stateRoot" : "[0xHASH32]", |
|||
"timestamp" : "[HEX]", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "[HEX]", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
}, |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "[HEX]", |
|||
"nonce" : "0", |
|||
"code" : "[CODE]", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "[CODE]", |
|||
"gasLimit" : "[HEX]", |
|||
"gasPrice" : "[V]", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "[V]" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
} |
|||
} |
|||
)"; |
@ -1,425 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file fuzzHelper.cpp
|
|||
* @author Dimitry Khokhlov <winsvega@mail.ru> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include "fuzzHelper.h" |
|||
|
|||
#include <chrono> |
|||
#include <boost/random.hpp> |
|||
#include <boost/filesystem/path.hpp> |
|||
#include <libevmcore/Instruction.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
boost::random::mt19937 RandomCode::gen; |
|||
boostIntDistrib RandomCode::opCodeDist = boostIntDistrib (0, 255); |
|||
boostIntDistrib RandomCode::opLengDist = boostIntDistrib (1, 32); |
|||
boostIntDistrib RandomCode::uniIntDist = boostIntDistrib (0, 0x7fffffff); |
|||
boostUint64Distrib RandomCode::uInt64Dist = boostUint64Distrib (0, std::numeric_limits<uint64_t>::max()); |
|||
|
|||
boostIntGenerator RandomCode::randOpCodeGen = boostIntGenerator(gen, opCodeDist); |
|||
boostIntGenerator RandomCode::randOpLengGen = boostIntGenerator(gen, opLengDist); |
|||
boostIntGenerator RandomCode::randUniIntGen = boostIntGenerator(gen, uniIntDist); |
|||
boostUInt64Generator RandomCode::randUInt64Gen = boostUInt64Generator(gen, uInt64Dist); |
|||
|
|||
int RandomCode::recursiveRLP(std::string& _result, int _depth, std::string& _debug) |
|||
{ |
|||
bool genValidRlp = true; |
|||
int bugProbability = randUniIntGen() % 100; |
|||
if (bugProbability < 80) |
|||
genValidRlp = false; |
|||
|
|||
if (_depth > 1) |
|||
{ |
|||
//create rlp blocks
|
|||
int size = 1 + randUniIntGen() % 4; |
|||
for (auto i = 0; i < size; i++) |
|||
{ |
|||
std::string blockstr; |
|||
std::string blockDebug; |
|||
recursiveRLP(blockstr, _depth - 1, blockDebug); |
|||
_result += blockstr; |
|||
_debug += blockDebug; |
|||
} |
|||
|
|||
//make rlp header
|
|||
int length = _result.size() / 2; |
|||
std::string header; |
|||
int rtype = 0; |
|||
int rnd = randUniIntGen() % 100; |
|||
if (rnd < 10) |
|||
{ |
|||
//make header as array
|
|||
if (length <= 55) |
|||
{ |
|||
header = toCompactHex(128 + length); |
|||
rtype = 1; |
|||
} |
|||
else |
|||
{ |
|||
std::string hexlength = toCompactHex(length); |
|||
header = toCompactHex(183 + hexlength.size() / 2) + hexlength; |
|||
rtype = 2; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
//make header as list
|
|||
if (length <= 55) |
|||
{ |
|||
header = toCompactHex(192 + length); |
|||
rtype = 3; |
|||
} |
|||
else |
|||
{ |
|||
std::string hexlength = toCompactHex(length, HexPrefix::DontAdd, 1); |
|||
header = toCompactHex(247 + hexlength.size() / 2) + hexlength; |
|||
rtype = 4; |
|||
} |
|||
} |
|||
_result = header + _result; |
|||
_debug = "[" + header + "(" + toString(length) + "){" + toString(rtype) + "}]" + _debug; |
|||
return _result.size() / 2; |
|||
} |
|||
if (_depth == 1) |
|||
{ |
|||
bool genbug = false; |
|||
bool genbug2 = false; |
|||
int bugProbability = randUniIntGen() % 100; |
|||
if (bugProbability < 50 && !genValidRlp) |
|||
genbug = true; |
|||
bugProbability = randUniIntGen() % 100; //more randomness
|
|||
if (bugProbability < 50 && !genValidRlp) |
|||
genbug2 = true; |
|||
|
|||
std::string emptyZeros = genValidRlp ? "" : genbug ? "00" : ""; |
|||
std::string emptyZeros2 = genValidRlp ? "" : genbug2 ? "00" : ""; |
|||
|
|||
int rnd = randUniIntGen() % 5; |
|||
switch (rnd) |
|||
{ |
|||
case 0: |
|||
{ |
|||
//single byte [0x00, 0x7f]
|
|||
std::string rlp = emptyZeros + toCompactHex(genbug ? randUniIntGen() % 255 : randUniIntGen() % 128, HexPrefix::DontAdd, 1); |
|||
_result.insert(0, rlp); |
|||
_debug.insert(0, "[" + rlp + "]"); |
|||
return 1; |
|||
} |
|||
case 1: |
|||
{ |
|||
//string 0-55 [0x80, 0xb7] + string
|
|||
int len = genbug ? randUniIntGen() % 255 : randUniIntGen() % 55; |
|||
std::string hex = rndByteSequence(len); |
|||
if (len == 1) |
|||
if (genValidRlp && fromHex(hex)[0] < 128) |
|||
hex = toCompactHex((u64)128); |
|||
|
|||
_result.insert(0, toCompactHex(128 + len) + emptyZeros + hex); |
|||
_debug.insert(0, "[" + toCompactHex(128 + len) + "(" + toString(len) + ")]" + emptyZeros + hex); |
|||
return len + 1; |
|||
} |
|||
case 2: |
|||
{ |
|||
//string more 55 [0xb8, 0xbf] + length + string
|
|||
int len = randUniIntGen() % 100; |
|||
if (len < 56 && genValidRlp) |
|||
len = 56; |
|||
|
|||
std::string hex = rndByteSequence(len); |
|||
std::string hexlen = emptyZeros2 + toCompactHex(len, HexPrefix::DontAdd, 1); |
|||
std::string rlpblock = toCompactHex(183 + hexlen.size() / 2) + hexlen + emptyZeros + hex; |
|||
_debug.insert(0, "[" + toCompactHex(183 + hexlen.size() / 2) + hexlen + "(" + toString(len) + "){2}]" + emptyZeros + hex); |
|||
_result.insert(0, rlpblock); |
|||
return rlpblock.size() / 2; |
|||
} |
|||
case 3: |
|||
{ |
|||
//list 0-55 [0xc0, 0xf7] + data
|
|||
int len = genbug ? randUniIntGen() % 255 : randUniIntGen() % 55; |
|||
std::string hex = emptyZeros + rndByteSequence(len); |
|||
_result.insert(0, toCompactHex(192 + len) + hex); |
|||
_debug.insert(0, "[" + toCompactHex(192 + len) + "(" + toString(len) + "){3}]" + hex); |
|||
return len + 1; |
|||
} |
|||
case 4: |
|||
{ |
|||
//list more 55 [0xf8, 0xff] + length + data
|
|||
int len = randUniIntGen() % 100; |
|||
if (len < 56 && genValidRlp) |
|||
len = 56; |
|||
std::string hexlen = emptyZeros2 + toCompactHex(len, HexPrefix::DontAdd, 1); |
|||
std::string rlpblock = toCompactHex(247 + hexlen.size() / 2) + hexlen + emptyZeros + rndByteSequence(len); |
|||
_debug.insert(0, "[" + toCompactHex(247 + hexlen.size() / 2) + hexlen + "(" + toString(len) + "){4}]" + emptyZeros + rndByteSequence(len)); |
|||
_result.insert(0, rlpblock); |
|||
return rlpblock.size() / 2; |
|||
} |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
std::string RandomCode::rndRLPSequence(int _depth, std::string& _debug) |
|||
{ |
|||
refreshSeed(); |
|||
std::string hash; |
|||
_depth = std::min(std::max(1, _depth), 7); //limit depth to avoid overkill
|
|||
recursiveRLP(hash, _depth, _debug); |
|||
return hash; |
|||
} |
|||
|
|||
std::string RandomCode::rndByteSequence(int _length, SizeStrictness _sizeType) |
|||
{ |
|||
refreshSeed(); |
|||
std::string hash = ""; |
|||
_length = (_sizeType == SizeStrictness::Strict) ? std::max(0, _length) : randomUniInt() % _length; |
|||
for (auto i = 0; i < _length; i++) |
|||
{ |
|||
uint8_t byte = randOpCodeGen(); |
|||
hash += toCompactHex(byte, HexPrefix::DontAdd, 1); |
|||
} |
|||
return hash; |
|||
} |
|||
|
|||
//generate smart random code
|
|||
std::string RandomCode::generate(int _maxOpNumber, RandomCodeOptions _options) |
|||
{ |
|||
refreshSeed(); |
|||
std::string code; |
|||
|
|||
//random opCode amount
|
|||
boostIntDistrib sizeDist (0, _maxOpNumber); |
|||
boostIntGenerator rndSizeGen(gen, sizeDist); |
|||
int size = (int)rndSizeGen(); |
|||
|
|||
boostWeightGenerator randOpCodeWeight (gen, _options.opCodeProbability); |
|||
bool weightsDefined = _options.opCodeProbability.probabilities().size() == 255; |
|||
|
|||
for (auto i = 0; i < size; i++) |
|||
{ |
|||
uint8_t opcode = weightsDefined ? randOpCodeWeight() : randOpCodeGen(); |
|||
dev::eth::InstructionInfo info = dev::eth::instructionInfo((dev::eth::Instruction) opcode); |
|||
|
|||
if (info.name.find("INVALID_INSTRUCTION") != std::string::npos) |
|||
{ |
|||
//Byte code is yet not implemented
|
|||
if (_options.useUndefinedOpCodes == false) |
|||
{ |
|||
i--; |
|||
continue; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (info.name.find("PUSH") != std::string::npos) |
|||
code += toCompactHex(opcode); |
|||
code += fillArguments((dev::eth::Instruction) opcode, _options); |
|||
} |
|||
|
|||
if (info.name.find("PUSH") == std::string::npos) |
|||
{ |
|||
std::string byte = toCompactHex(opcode); |
|||
code += (byte == "") ? "00" : byte; |
|||
} |
|||
} |
|||
return code; |
|||
} |
|||
|
|||
std::string RandomCode::randomUniIntHex(u256 _maxVal) |
|||
{ |
|||
if (_maxVal == 0) |
|||
_maxVal = std::numeric_limits<uint64_t>::max(); |
|||
refreshSeed(); |
|||
int rand = randUniIntGen() % 100; |
|||
if (rand < 50) |
|||
return "0x" + toCompactHex((u256)randUniIntGen() % _maxVal); |
|||
return "0x" + toCompactHex((u256)randUInt64Gen() % _maxVal); |
|||
} |
|||
|
|||
int RandomCode::randomUniInt() |
|||
{ |
|||
refreshSeed(); |
|||
return (int)randUniIntGen(); |
|||
} |
|||
|
|||
void RandomCode::refreshSeed() |
|||
{ |
|||
auto now = std::chrono::steady_clock::now().time_since_epoch(); |
|||
auto timeSinceEpoch = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count(); |
|||
gen.seed(static_cast<unsigned int>(timeSinceEpoch)); |
|||
} |
|||
|
|||
std::string RandomCode::getPushCode(std::string const& _hex) |
|||
{ |
|||
int length = _hex.length() / 2; |
|||
int pushCode = 96 + length - 1; |
|||
return toCompactHex(pushCode) + _hex; |
|||
} |
|||
|
|||
std::string RandomCode::getPushCode(int _value) |
|||
{ |
|||
std::string hexString = toCompactHex(_value); |
|||
return getPushCode(hexString); |
|||
} |
|||
|
|||
std::string RandomCode::fillArguments(dev::eth::Instruction _opcode, RandomCodeOptions const& _options) |
|||
{ |
|||
dev::eth::InstructionInfo info = dev::eth::instructionInfo(_opcode); |
|||
|
|||
std::string code; |
|||
bool smart = false; |
|||
unsigned num = info.args; |
|||
int rand = randUniIntGen() % 100; |
|||
if (rand < _options.smartCodeProbability) |
|||
smart = true; |
|||
|
|||
if (smart) |
|||
{ |
|||
//PUSH1 ... PUSH32
|
|||
if (dev::eth::Instruction::PUSH1 <= _opcode && _opcode <= dev::eth::Instruction::PUSH32) |
|||
{ |
|||
code += rndByteSequence(int(_opcode) - int(dev::eth::Instruction::PUSH1) + 1); |
|||
return code; |
|||
} |
|||
|
|||
//SWAP1 ... SWAP16 || DUP1 ... DUP16
|
|||
bool isSWAP = (dev::eth::Instruction::SWAP1 <= _opcode && _opcode <= dev::eth::Instruction::SWAP16); |
|||
bool isDUP = (dev::eth::Instruction::DUP1 <= _opcode && _opcode <= dev::eth::Instruction::DUP16); |
|||
|
|||
if (isSWAP || isDUP) |
|||
{ |
|||
int times = 0; |
|||
if (isSWAP) |
|||
times = int(_opcode) - int(dev::eth::Instruction::SWAP1) + 2; |
|||
else |
|||
if (isDUP) |
|||
times = int(_opcode) - int(dev::eth::Instruction::DUP1) + 1; |
|||
|
|||
for (int i = 0; i < times; i ++) |
|||
code += getPushCode(randUniIntGen() % 32); |
|||
|
|||
return code; |
|||
} |
|||
|
|||
switch (_opcode) |
|||
{ |
|||
case dev::eth::Instruction::CREATE: |
|||
//(CREATE value mem1 mem2)
|
|||
code += getPushCode(randUniIntGen() % 128); //memlen1
|
|||
code += getPushCode(randUniIntGen() % 32); //memlen1
|
|||
code += getPushCode(randUniIntGen()); //value
|
|||
break; |
|||
case dev::eth::Instruction::CALL: |
|||
case dev::eth::Instruction::CALLCODE: |
|||
//(CALL gaslimit address value memstart1 memlen1 memstart2 memlen2)
|
|||
//(CALLCODE gaslimit address value memstart1 memlen1 memstart2 memlen2)
|
|||
code += getPushCode(randUniIntGen() % 128); //memlen2
|
|||
code += getPushCode(randUniIntGen() % 32); //memstart2
|
|||
code += getPushCode(randUniIntGen() % 128); //memlen1
|
|||
code += getPushCode(randUniIntGen() % 32); //memlen1
|
|||
code += getPushCode(randUniIntGen()); //value
|
|||
code += getPushCode(toString(_options.getRandomAddress()));//address
|
|||
code += getPushCode(randUniIntGen()); //gaslimit
|
|||
break; |
|||
case dev::eth::Instruction::SUICIDE: //(SUICIDE address)
|
|||
code += getPushCode(toString(_options.getRandomAddress())); |
|||
break; |
|||
case dev::eth::Instruction::RETURN: //(RETURN memlen1 memlen2)
|
|||
code += getPushCode(randUniIntGen() % 128); //memlen1
|
|||
code += getPushCode(randUniIntGen() % 32); //memlen1
|
|||
break; |
|||
default: |
|||
smart = false; |
|||
} |
|||
} |
|||
|
|||
if (smart == false) |
|||
for (unsigned i = 0; i < num; i++) |
|||
{ |
|||
//generate random parameters
|
|||
int length = randOpLengGen(); |
|||
code += getPushCode(rndByteSequence(length)); |
|||
} |
|||
return code; |
|||
} |
|||
|
|||
|
|||
//Ramdom Code Options
|
|||
RandomCodeOptions::RandomCodeOptions() : useUndefinedOpCodes(false), smartCodeProbability(50) |
|||
{ |
|||
//each op code with same weight-probability
|
|||
for (auto i = 0; i < 255; i++) |
|||
mapWeights.insert(std::pair<int, int>(i, 50)); |
|||
setWeights(); |
|||
} |
|||
|
|||
void RandomCodeOptions::setWeight(dev::eth::Instruction _opCode, int _weight) |
|||
{ |
|||
mapWeights.at((int)_opCode) = _weight; |
|||
setWeights(); |
|||
} |
|||
|
|||
void RandomCodeOptions::addAddress(dev::Address const& _address) |
|||
{ |
|||
addressList.push_back(_address); |
|||
} |
|||
|
|||
dev::Address RandomCodeOptions::getRandomAddress() const |
|||
{ |
|||
if (addressList.size() > 0) |
|||
{ |
|||
int index = RandomCode::randomUniInt() % addressList.size(); |
|||
return addressList[index]; |
|||
} |
|||
return Address(RandomCode::rndByteSequence(20)); |
|||
} |
|||
|
|||
void RandomCodeOptions::setWeights() |
|||
{ |
|||
std::vector<int> weights; |
|||
for (auto const& element: mapWeights) |
|||
weights.push_back(element.second); |
|||
opCodeProbability = boostDescreteDistrib(weights); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE(RandomCodeTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(rndCode) |
|||
{ |
|||
std::string code; |
|||
cnote << "Testing Random Code: "; |
|||
try |
|||
{ |
|||
code = dev::test::RandomCode::generate(10); |
|||
} |
|||
catch(...) |
|||
{ |
|||
BOOST_ERROR("Exception thrown when generating random code!"); |
|||
} |
|||
cnote << code; |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
|||
} |
|||
} |
@ -1,118 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file fuzzHelper.h
|
|||
* @author Dimitry Khokhlov <winsvega@mail.ru> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <string> |
|||
#include <boost/random.hpp> |
|||
#include <boost/filesystem/path.hpp> |
|||
|
|||
#include <test/TestHelper.h> |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libdevcore/CommonData.h> |
|||
#include <libevmcore/Instruction.h> |
|||
|
|||
#pragma once |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
typedef boost::random::uniform_int_distribution<> boostIntDistrib; |
|||
typedef boost::random::discrete_distribution<> boostDescreteDistrib; |
|||
typedef boost::uniform_int<uint64_t> boostUint64Distrib; |
|||
|
|||
typedef boost::random::variate_generator<boost::mt19937&, boostIntDistrib > boostIntGenerator; |
|||
typedef boost::random::variate_generator<boost::mt19937&, boostDescreteDistrib > boostWeightGenerator; |
|||
typedef boost::random::variate_generator<boost::mt19937&, boostUint64Distrib > boostUInt64Generator; |
|||
|
|||
struct RandomCodeOptions |
|||
{ |
|||
public: |
|||
RandomCodeOptions(); |
|||
void setWeight(dev::eth::Instruction _opCode, int _weight); |
|||
void addAddress(dev::Address const& _address); |
|||
dev::Address getRandomAddress() const; |
|||
|
|||
bool useUndefinedOpCodes; |
|||
int smartCodeProbability; |
|||
boostDescreteDistrib opCodeProbability; |
|||
private: |
|||
void setWeights(); |
|||
std::map<int, int> mapWeights; |
|||
std::vector<dev::Address> addressList; |
|||
}; |
|||
|
|||
enum class SizeStrictness |
|||
{ |
|||
Strict, |
|||
Random |
|||
}; |
|||
|
|||
struct RlpDebug |
|||
{ |
|||
std::string rlp; |
|||
int insertions; |
|||
}; |
|||
|
|||
class RandomCode |
|||
{ |
|||
public: |
|||
/// Generate random vm code
|
|||
static std::string generate(int _maxOpNumber = 1, RandomCodeOptions _options = RandomCodeOptions()); |
|||
|
|||
/// Generate random byte string of a given length
|
|||
static std::string rndByteSequence(int _length = 1, SizeStrictness _sizeType = SizeStrictness::Strict); |
|||
|
|||
/// Generate random rlp byte sequence of a given depth (e.g [[[]],[]]). max depth level = 20.
|
|||
/// The _debug string contains returned rlp string with analysed sections
|
|||
/// [] - length section/ or single byte rlp encoding
|
|||
/// () - decimal representation of length
|
|||
/// {1} - Array
|
|||
/// {2} - Array more than 55
|
|||
/// {3} - List
|
|||
/// {4} - List more than 55
|
|||
static std::string rndRLPSequence(int _depth, std::string& _debug); |
|||
|
|||
/// Generate random int64
|
|||
static std::string randomUniIntHex(u256 _maxVal = 0); |
|||
static int randomUniInt(); |
|||
|
|||
private: |
|||
static std::string fillArguments(dev::eth::Instruction _opcode, RandomCodeOptions const& _options); |
|||
static std::string getPushCode(int _value); |
|||
static std::string getPushCode(std::string const& _hex); |
|||
static int recursiveRLP(std::string& _result, int _depth, std::string& _debug); |
|||
static void refreshSeed(); |
|||
|
|||
static boost::random::mt19937 gen; ///< Random generator
|
|||
static boostIntDistrib opCodeDist; ///< 0..255 opcodes
|
|||
static boostIntDistrib opLengDist; ///< 1..32 byte string
|
|||
static boostIntDistrib uniIntDist; ///< 0..0x7fffffff
|
|||
static boostUint64Distrib uInt64Dist; ///< 0..2**64
|
|||
|
|||
static boostIntGenerator randUniIntGen; ///< Generate random UniformInt from uniIntDist
|
|||
static boostIntGenerator randOpCodeGen; ///< Generate random value from opCodeDist
|
|||
static boostIntGenerator randOpLengGen; ///< Generate random length from opLengDist
|
|||
static boostUInt64Generator randUInt64Gen; ///< Generate random uInt64
|
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,54 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Base36.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/Base64.h> |
|||
#include <libethcore/ICAP.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(Base36Tests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicEncoding) |
|||
{ |
|||
FixedHash<2> value("0x0048"); |
|||
string encoded = toBase36<2>(value); |
|||
BOOST_CHECK_EQUAL(encoded, "20"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicEncoding2) |
|||
{ |
|||
FixedHash<2> value("0x0072"); |
|||
string encoded = toBase36<2>(value); |
|||
BOOST_CHECK_EQUAL(encoded, "36"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicEncoding3) |
|||
{ |
|||
FixedHash<2> value("0xffff"); |
|||
string encoded = toBase36<2>(value); |
|||
BOOST_CHECK_EQUAL(encoded, "1EKF"); |
|||
} |
|||
|
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,5 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRCS) |
|||
|
|||
add_sources(${SRCS}) |
@ -1,146 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file FixedHash.cpp
|
|||
* @author Lefterus <lefteris@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <libdevcore/FixedHash.h> |
|||
#include "../TestHelper.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
BOOST_AUTO_TEST_SUITE(FixedHashTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashComparisons) |
|||
{ |
|||
FixedHash<4> h1(sha3("abcd")); |
|||
FixedHash<4> h2(sha3("abcd")); |
|||
FixedHash<4> h3(sha3("aadd")); |
|||
FixedHash<4> h4(0xBAADF00D); |
|||
FixedHash<4> h5(0xAAAAAAAA); |
|||
FixedHash<4> h6(0xBAADF00D); |
|||
|
|||
BOOST_CHECK(h1 == h2); |
|||
BOOST_CHECK(h2 != h3); |
|||
|
|||
BOOST_CHECK(h4 > h5); |
|||
BOOST_CHECK(h5 < h4); |
|||
BOOST_CHECK(h6 <= h4); |
|||
BOOST_CHECK(h6 >= h4); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashXOR) |
|||
{ |
|||
FixedHash<2> h1("0xAAAA"); |
|||
FixedHash<2> h2("0xBBBB"); |
|||
|
|||
BOOST_CHECK((h1 ^ h2) == FixedHash<2>("0x1111")); |
|||
h1 ^= h2; |
|||
BOOST_CHECK(h1 == FixedHash<2>("0x1111")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashOR) |
|||
{ |
|||
FixedHash<4> h1("0xD3ADB33F"); |
|||
FixedHash<4> h2("0xBAADF00D"); |
|||
FixedHash<4> res("0xFBADF33F"); |
|||
|
|||
BOOST_CHECK((h1 | h2) == res); |
|||
h1 |= h2; |
|||
BOOST_CHECK(h1 == res); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashAND) |
|||
{ |
|||
FixedHash<4> h1("0xD3ADB33F"); |
|||
FixedHash<4> h2("0xBAADF00D"); |
|||
FixedHash<4> h3("0x92aDB00D"); |
|||
|
|||
BOOST_CHECK((h1 & h2) == h3); |
|||
h1 &= h2; |
|||
BOOST_CHECK(h1 = h3); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashInvert) |
|||
{ |
|||
FixedHash<4> h1("0xD3ADB33F"); |
|||
FixedHash<4> h2("0x2C524CC0"); |
|||
|
|||
BOOST_CHECK(~h1 == h2); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashContains) |
|||
{ |
|||
FixedHash<4> h1("0xD3ADB331"); |
|||
FixedHash<4> h2("0x0000B331"); |
|||
FixedHash<4> h3("0x0000000C"); |
|||
|
|||
BOOST_CHECK(h1.contains(h2)); |
|||
BOOST_CHECK(!h1.contains(h3)); |
|||
} |
|||
|
|||
void incrementSingleIteration(unsigned seed) |
|||
{ |
|||
unsigned next = seed + 1; |
|||
|
|||
FixedHash<4> h1(seed); |
|||
FixedHash<4> h2 = h1; |
|||
FixedHash<4> h3(next); |
|||
|
|||
FixedHash<32> hh1(seed); |
|||
FixedHash<32> hh2 = hh1; |
|||
FixedHash<32> hh3(next); |
|||
|
|||
BOOST_CHECK_EQUAL(++h2, h3); |
|||
BOOST_CHECK_EQUAL(++hh2, hh3); |
|||
|
|||
BOOST_CHECK(h2 > h1); |
|||
BOOST_CHECK(hh2 > hh1); |
|||
|
|||
unsigned reverse1 = ((FixedHash<4>::Arith)h2).convert_to<unsigned>(); |
|||
unsigned reverse2 = ((FixedHash<32>::Arith)hh2).convert_to<unsigned>(); |
|||
|
|||
BOOST_CHECK_EQUAL(next, reverse1); |
|||
BOOST_CHECK_EQUAL(next, reverse2); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(FixedHashIncrement) |
|||
{ |
|||
incrementSingleIteration(0); |
|||
incrementSingleIteration(1); |
|||
incrementSingleIteration(0xBAD); |
|||
incrementSingleIteration(0xBEEF); |
|||
incrementSingleIteration(0xFFFF); |
|||
incrementSingleIteration(0xFEDCBA); |
|||
incrementSingleIteration(0x7FFFFFFF); |
|||
|
|||
FixedHash<4> h(0xFFFFFFFF); |
|||
FixedHash<4> zero; |
|||
BOOST_CHECK_EQUAL(++h, zero); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
|||
} |
|||
} |
@ -1,148 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file RangeMask.cpp
|
|||
* @author Christian <c@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <libdevcore/RangeMask.h> |
|||
#include "../TestHelper.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
BOOST_AUTO_TEST_SUITE(RangeMaskTest) |
|||
|
|||
BOOST_AUTO_TEST_CASE(constructor) |
|||
{ |
|||
using RM = RangeMask<unsigned>; |
|||
using Range = pair<unsigned, unsigned>; |
|||
for (RM r: {RM(), RM(1, 10), RM(Range(2, 10))}) |
|||
{ |
|||
BOOST_CHECK(r.empty()); |
|||
BOOST_CHECK(!r.contains(0)); |
|||
BOOST_CHECK(!r.contains(1)); |
|||
BOOST_CHECK_EQUAL(0, r.size()); |
|||
} |
|||
BOOST_CHECK(RM().full()); |
|||
BOOST_CHECK(!RM(1, 10).full()); |
|||
BOOST_CHECK(!RM(Range(2, 10)).full()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(simple_unions) |
|||
{ |
|||
using RM = RangeMask<unsigned>; |
|||
using Range = pair<unsigned, unsigned>; |
|||
RM m(Range(0, 2000)); |
|||
m.unionWith(Range(1, 2)); |
|||
BOOST_CHECK_EQUAL(m.size(), 1); |
|||
m.unionWith(Range(50, 250)); |
|||
BOOST_CHECK_EQUAL(m.size(), 201); |
|||
m.unionWith(Range(10, 16)); |
|||
BOOST_CHECK_EQUAL(m.size(), 207); |
|||
BOOST_CHECK(m.contains(1)); |
|||
BOOST_CHECK(m.contains(11)); |
|||
BOOST_CHECK(m.contains(51)); |
|||
BOOST_CHECK(m.contains(200)); |
|||
BOOST_CHECK(!m.contains(2)); |
|||
BOOST_CHECK(!m.contains(7)); |
|||
BOOST_CHECK(!m.contains(17)); |
|||
BOOST_CHECK(!m.contains(258)); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(empty_union) |
|||
{ |
|||
using RM = RangeMask<unsigned>; |
|||
using Range = pair<unsigned, unsigned>; |
|||
RM m(Range(0, 2000)); |
|||
m.unionWith(Range(3, 6)); |
|||
BOOST_CHECK_EQUAL(m.size(), 3); |
|||
m.unionWith(Range(50, 50)); |
|||
BOOST_CHECK_EQUAL(m.size(), 3); |
|||
m.unionWith(Range(0, 0)); |
|||
BOOST_CHECK_EQUAL(m.size(), 3); |
|||
m.unionWith(Range(1, 1)); |
|||
BOOST_CHECK_EQUAL(m.size(), 3); |
|||
m.unionWith(Range(2, 2)); |
|||
BOOST_CHECK_EQUAL(m.size(), 3); |
|||
m.unionWith(Range(3, 3)); |
|||
BOOST_CHECK_EQUAL(m.size(), 3); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(overlapping_unions) |
|||
{ |
|||
using RM = RangeMask<unsigned>; |
|||
using Range = pair<unsigned, unsigned>; |
|||
RM m(Range(0, 2000)); |
|||
m.unionWith(Range(10, 20)); |
|||
BOOST_CHECK_EQUAL(10, m.size()); |
|||
m.unionWith(Range(30, 40)); |
|||
BOOST_CHECK_EQUAL(20, m.size()); |
|||
m.unionWith(Range(15, 30)); |
|||
BOOST_CHECK_EQUAL(40 - 10, m.size()); |
|||
m.unionWith(Range(50, 60)); |
|||
m.unionWith(Range(45, 55)); |
|||
// [40, 45) still missing here
|
|||
BOOST_CHECK_EQUAL(60 - 10 - 5, m.size()); |
|||
m.unionWith(Range(15, 56)); |
|||
BOOST_CHECK_EQUAL(60 - 10, m.size()); |
|||
m.unionWith(Range(15, 65)); |
|||
BOOST_CHECK_EQUAL(65 - 10, m.size()); |
|||
m.unionWith(Range(5, 70)); |
|||
BOOST_CHECK_EQUAL(70 - 5, m.size()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(complement) |
|||
{ |
|||
using RM = RangeMask<unsigned>; |
|||
using Range = pair<unsigned, unsigned>; |
|||
RM m(Range(0, 2000)); |
|||
m.unionWith(7).unionWith(9); |
|||
m = ~m; |
|||
m.unionWith(7).unionWith(9); |
|||
m = ~m; |
|||
BOOST_CHECK(m.empty()); |
|||
|
|||
m += Range(0, 10); |
|||
m += Range(1000, 2000); |
|||
m.invert(); |
|||
BOOST_CHECK_EQUAL(m.size(), 1000 - 10); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(iterator) |
|||
{ |
|||
using RM = RangeMask<unsigned>; |
|||
using Range = pair<unsigned, unsigned>; |
|||
RM m(Range(0, 2000)); |
|||
m.unionWith(Range(7, 9)); |
|||
m.unionWith(11); |
|||
m.unionWith(Range(200, 205)); |
|||
|
|||
vector<unsigned> elements; |
|||
copy(m.begin(), m.end(), back_inserter(elements)); |
|||
BOOST_CHECK(elements == (vector<unsigned>{7, 8, 11, 200, 201, 202, 203, 204})); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
|||
} |
|||
} |
@ -1,41 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file core.cpp
|
|||
* @author Dimitry Khokhlov <winsvega@mail.ru> |
|||
* @date 2014 |
|||
* CORE test functions. |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <test/TestHelper.h> |
|||
|
|||
BOOST_AUTO_TEST_SUITE(CoreLibTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(byteRef) |
|||
{ |
|||
cnote << "bytesRef copyTo and toString..."; |
|||
dev::bytes originalSequence = dev::fromHex("0102030405060708091011121314151617181920212223242526272829303132"); |
|||
dev::bytesRef out(&originalSequence.at(0), 32); |
|||
dev::h256 hash32("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); |
|||
hash32.ref().copyTo(out); |
|||
|
|||
BOOST_CHECK_MESSAGE(out.size() == 32, "Error wrong result size when h256::ref().copyTo(dev::bytesRef out)"); |
|||
BOOST_CHECK_MESSAGE(out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,314 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file rlp.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* RLP test functions. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
#include <sstream> |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
|
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcore/RLP.h> |
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <algorithm> |
|||
#include "test/JsonSpiritHeaders.h" |
|||
#include "test/TestHelper.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
namespace js = json_spirit; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
void buildRLP(js::mValue& _v, RLPStream& _rlp); |
|||
void checkRLPAgainstJson(js::mValue& v, RLP& u); |
|||
enum class RlpType |
|||
{ |
|||
Valid, |
|||
Invalid, |
|||
Test |
|||
}; |
|||
|
|||
void doRlpTests(json_spirit::mValue& v, bool _fillin) |
|||
{ |
|||
string testname; |
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
js::mObject& o = i.second.get_obj(); |
|||
if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) |
|||
{ |
|||
o.clear(); |
|||
continue; |
|||
} |
|||
|
|||
cnote << " " << i.first; |
|||
testname = "(" + i.first + ") "; |
|||
|
|||
BOOST_REQUIRE_MESSAGE(o.count("out") > 0, testname + "out not set!"); |
|||
BOOST_REQUIRE_MESSAGE(!o["out"].is_null(), testname + "out is set to null!"); |
|||
|
|||
if (_fillin) |
|||
{ |
|||
try |
|||
{ |
|||
bytes payloadToDecode = fromHex(o["out"].get_str()); |
|||
RLP payload(payloadToDecode); |
|||
ostringstream() << payload; |
|||
o["in"] = "VALID"; |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
cnote << "Exception: " << diagnostic_information(_e); |
|||
o["in"] = "INVALID"; |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
cnote << "rlp exception: " << _e.what(); |
|||
o["in"] = "INVALID"; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
//Check Encode
|
|||
BOOST_REQUIRE_MESSAGE(o.count("in") > 0, testname + "in not set!"); |
|||
RlpType rlpType = RlpType::Test; |
|||
if (o["in"].type() == js::str_type) |
|||
{ |
|||
if (o["in"].get_str() == "INVALID") |
|||
rlpType = RlpType::Invalid; |
|||
else if (o["in"].get_str() == "VALID") |
|||
rlpType = RlpType::Valid; |
|||
} |
|||
|
|||
if (rlpType == RlpType::Test) |
|||
{ |
|||
RLPStream s; |
|||
dev::test::buildRLP(o["in"], s); |
|||
string computedText = toHex(s.out()); |
|||
|
|||
string expectedText(o["out"].get_str()); |
|||
transform(expectedText.begin(), expectedText.end(), expectedText.begin(), ::tolower ); |
|||
|
|||
stringstream msg; |
|||
msg << "Encoding Failed: expected: " << expectedText << std::endl; |
|||
msg << " But Computed: " << computedText; |
|||
BOOST_CHECK_MESSAGE(expectedText == computedText, testname + msg.str()); |
|||
} |
|||
|
|||
//Check Decode
|
|||
// 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.
|
|||
bool was_exception = false; |
|||
js::mValue& inputData = o["in"]; |
|||
try |
|||
{ |
|||
bytes payloadToDecode = fromHex(o["out"].get_str()); |
|||
RLP payload(payloadToDecode); |
|||
|
|||
//attempt to read all the contents of RLP
|
|||
ostringstream() << payload; |
|||
|
|||
if (rlpType == RlpType::Test) |
|||
dev::test::checkRLPAgainstJson(inputData, payload); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
cnote << "Exception: " << diagnostic_information(_e); |
|||
was_exception = true; |
|||
} |
|||
catch (exception const& _e) |
|||
{ |
|||
cnote << "rlp exception: " << _e.what(); |
|||
was_exception = true; |
|||
} |
|||
catch (...) |
|||
{ |
|||
was_exception = true; |
|||
} |
|||
|
|||
//Expect exception as input is INVALID
|
|||
if (rlpType == RlpType::Invalid && was_exception) |
|||
continue; |
|||
|
|||
//Check that there was an exception as input is INVALID
|
|||
if (rlpType == RlpType::Invalid && !was_exception) |
|||
BOOST_ERROR(testname + "Expected RLP Exception as rlp should be invalid!"); |
|||
|
|||
//input is VALID check that there was no exceptions
|
|||
if (was_exception) |
|||
BOOST_ERROR(testname + "Unexpected RLP Exception!"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void buildRLP(js::mValue& _v, RLPStream& _rlp) |
|||
{ |
|||
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); |
|||
} |
|||
} |
|||
|
|||
void checkRLPAgainstJson(js::mValue& v, RLP& u) |
|||
{ |
|||
if ( v.type() == js::str_type ) |
|||
{ |
|||
const string& expectedText = v.get_str(); |
|||
if ( !expectedText.empty() && expectedText.front() == '#' ) |
|||
{ |
|||
// Deal with bigint instead of a raw string
|
|||
string bigIntStr = expectedText.substr(1,expectedText.length()-1); |
|||
stringstream bintStream(bigIntStr); |
|||
bigint val; |
|||
bintStream >> val; |
|||
BOOST_CHECK( !u.isList() ); |
|||
BOOST_CHECK( !u.isNull() ); |
|||
BOOST_CHECK( u == val ); |
|||
} |
|||
else |
|||
{ |
|||
BOOST_CHECK( !u.isList() ); |
|||
BOOST_CHECK( !u.isNull() ); |
|||
BOOST_CHECK( u.isData() ); |
|||
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 == 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() ); |
|||
unsigned 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_SUITE(RlpTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(EmptyArrayList) |
|||
{ |
|||
try |
|||
{ |
|||
bytes payloadToDecode = fromHex("80"); |
|||
RLP payload(payloadToDecode); |
|||
ostringstream() << payload; |
|||
|
|||
payloadToDecode = fromHex("с0"); |
|||
RLP payload2(payloadToDecode); |
|||
ostringstream() << payload2; |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("(EmptyArrayList) Failed test with Exception: " << _e.what()); |
|||
} |
|||
catch (exception const& _e) |
|||
{ |
|||
BOOST_ERROR("(EmptyArrayList) Failed test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(invalidRLPtest) |
|||
{ |
|||
dev::test::executeTests("invalidRLPTest", "/RLPTests", dev::test::getFolder(__FILE__) + "/RLPTestsFiller", dev::test::doRlpTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(rlptest) |
|||
{ |
|||
dev::test::executeTests("rlptest", "/RLPTests", dev::test::getFolder(__FILE__) + "/RLPTestsFiller", dev::test::doRlpTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(rlpRandom) |
|||
{ |
|||
test::Options::get(); |
|||
|
|||
string testPath = dev::test::getTestPath(); |
|||
testPath += "/RLPTests/RandomRLPTests"; |
|||
|
|||
vector<boost::filesystem::path> testFiles; |
|||
boost::filesystem::directory_iterator iterator(testPath); |
|||
for(; iterator != boost::filesystem::directory_iterator(); ++iterator) |
|||
if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() == ".json") |
|||
testFiles.push_back(iterator->path()); |
|||
|
|||
for (auto& path: testFiles) |
|||
{ |
|||
try |
|||
{ |
|||
cnote << "Testing ..." << path.filename(); |
|||
json_spirit::mValue v; |
|||
string s = asString(dev::contents(path.string())); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); |
|||
json_spirit::read_string(s, v); |
|||
test::Listener::notifySuiteStarted(path.filename().string()); |
|||
dev::test::doRlpTests(v, false); |
|||
} |
|||
|
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR(path.filename().string() + "Failed test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR(path.filename().string() + "Failed test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,80 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file AES.cpp
|
|||
* @author Christoph Jentzsch <cj@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcrypto/Common.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libdevcrypto/AES.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(AES) |
|||
|
|||
BOOST_AUTO_TEST_CASE(AesDecrypt) |
|||
{ |
|||
cnote << "AesDecrypt"; |
|||
bytes seed = fromHex("2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621"); |
|||
KeyPair kp(sha3Secure(aesDecrypt(&seed, "test"))); |
|||
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") == kp.address()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(AesDecryptWrongSeed) |
|||
{ |
|||
cnote << "AesDecryptWrongSeed"; |
|||
bytes seed = fromHex("badaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621"); |
|||
KeyPair kp(sha3Secure(aesDecrypt(&seed, "test"))); |
|||
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") != kp.address()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(AesDecryptWrongPassword) |
|||
{ |
|||
cnote << "AesDecryptWrongPassword"; |
|||
bytes seed = fromHex("2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621"); |
|||
KeyPair kp(sha3Secure(aesDecrypt(&seed, "badtest"))); |
|||
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") != kp.address()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(AesDecryptFailInvalidSeed) |
|||
{ |
|||
cnote << "AesDecryptFailInvalidSeed"; |
|||
bytes seed = fromHex("xdbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621"); |
|||
BOOST_CHECK(bytes() == aesDecrypt(&seed, "test")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(AesDecryptFailInvalidSeedSize) |
|||
{ |
|||
cnote << "AesDecryptFailInvalidSeedSize"; |
|||
bytes seed = fromHex("000102030405060708090a0b0c0d0e0f"); |
|||
BOOST_CHECK(bytes() == aesDecrypt(&seed, "test")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(AesDecryptFailInvalidSeed2) |
|||
{ |
|||
cnote << "AesDecryptFailInvalidSeed2"; |
|||
bytes seed = fromHex("000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"); |
|||
BOOST_CHECK(bytes() == aesDecrypt(&seed, "test")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,5 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRCS) |
|||
|
|||
add_sources(${SRCS}) |
@ -1,482 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file MemTrie.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "MemTrie.h" |
|||
|
|||
#include <libdevcore/TrieCommon.h> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libethcore/Common.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
#define ENABLE_DEBUG_PRINT 0 |
|||
|
|||
/*/
|
|||
#define APPEND_CHILD appendData |
|||
/*/
|
|||
#define APPEND_CHILD appendRaw |
|||
/**/ |
|||
|
|||
class MemTrieNode |
|||
{ |
|||
public: |
|||
MemTrieNode() {} |
|||
virtual ~MemTrieNode() {} |
|||
|
|||
virtual std::string const& at(bytesConstRef _key) const = 0; |
|||
virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) = 0; |
|||
virtual MemTrieNode* remove(bytesConstRef _key) = 0; |
|||
void putRLP(RLPStream& _parentStream) const; |
|||
|
|||
#if ENABLE_DEBUG_PRINT |
|||
void debugPrint(std::string const& _indent = "") const { std::cerr << std::hex << hash256() << ":" << std::dec << std::endl; debugPrintBody(_indent); } |
|||
#endif |
|||
|
|||
/// 256-bit hash of the node - this is a SHA-3/256 hash of the RLP of the node.
|
|||
h256 hash256() const { RLPStream s; makeRLP(s); return dev::sha3(s.out()); } |
|||
bytes rlp() const { RLPStream s; makeRLP(s); return s.out(); } |
|||
void mark() { m_hash256 = h256(); } |
|||
|
|||
protected: |
|||
virtual void makeRLP(RLPStream& _intoStream) const = 0; |
|||
|
|||
#if ENABLE_DEBUG_PRINT |
|||
virtual void debugPrintBody(std::string const& _indent = "") const = 0; |
|||
#endif |
|||
|
|||
static MemTrieNode* newBranch(bytesConstRef _k1, std::string const& _v1, bytesConstRef _k2, std::string const& _v2); |
|||
|
|||
private: |
|||
mutable h256 m_hash256; |
|||
}; |
|||
|
|||
static const std::string c_nullString; |
|||
|
|||
class TrieExtNode: public MemTrieNode |
|||
{ |
|||
public: |
|||
TrieExtNode(bytesConstRef _bytes): m_ext(_bytes.begin(), _bytes.end()) {} |
|||
|
|||
bytes m_ext; |
|||
}; |
|||
|
|||
class TrieBranchNode: public MemTrieNode |
|||
{ |
|||
public: |
|||
TrieBranchNode(std::string const& _value): m_value(_value) |
|||
{ |
|||
memset(m_nodes.data(), 0, sizeof(MemTrieNode*) * 16); |
|||
} |
|||
|
|||
TrieBranchNode(byte _i1, MemTrieNode* _n1, std::string const& _value = std::string()): m_value(_value) |
|||
{ |
|||
memset(m_nodes.data(), 0, sizeof(MemTrieNode*) * 16); |
|||
m_nodes[_i1] = _n1; |
|||
} |
|||
|
|||
TrieBranchNode(byte _i1, MemTrieNode* _n1, byte _i2, MemTrieNode* _n2) |
|||
{ |
|||
memset(m_nodes.data(), 0, sizeof(MemTrieNode*) * 16); |
|||
m_nodes[_i1] = _n1; |
|||
m_nodes[_i2] = _n2; |
|||
} |
|||
|
|||
virtual ~TrieBranchNode() |
|||
{ |
|||
for (auto i: m_nodes) |
|||
delete i; |
|||
} |
|||
|
|||
#if ENABLE_DEBUG_PRINT |
|||
virtual void debugPrintBody(std::string const& _indent) const |
|||
{ |
|||
|
|||
if (m_value.size()) |
|||
std::cerr << _indent << "@: " << m_value << std::endl; |
|||
for (auto i = 0; i < 16; ++i) |
|||
if (m_nodes[i]) |
|||
{ |
|||
std::cerr << _indent << std::hex << i << ": " << std::dec; |
|||
m_nodes[i]->debugPrint(_indent + " "); |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
virtual std::string const& at(bytesConstRef _key) const override; |
|||
virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) override; |
|||
virtual MemTrieNode* remove(bytesConstRef _key) override; |
|||
virtual void makeRLP(RLPStream& _parentStream) const override; |
|||
|
|||
private: |
|||
/// @returns (byte)-1 when no active branches, 16 when multiple active and the index of the active branch otherwise.
|
|||
byte activeBranch() const; |
|||
|
|||
MemTrieNode* rejig(); |
|||
|
|||
std::array<MemTrieNode*, 16> m_nodes; |
|||
std::string m_value; |
|||
}; |
|||
|
|||
class TrieLeafNode: public TrieExtNode |
|||
{ |
|||
public: |
|||
TrieLeafNode(bytesConstRef _key, std::string const& _value): TrieExtNode(_key), m_value(_value) {} |
|||
|
|||
#if ENABLE_DEBUG_PRINT |
|||
virtual void debugPrintBody(std::string const& _indent) const |
|||
{ |
|||
assert(m_value.size()); |
|||
std::cerr << _indent; |
|||
if (m_ext.size()) |
|||
std::cerr << toHex(m_ext, 1) << ": "; |
|||
else |
|||
std::cerr << "@: "; |
|||
std::cerr << m_value << std::endl; |
|||
} |
|||
#endif |
|||
|
|||
virtual std::string const& at(bytesConstRef _key) const override { return contains(_key) ? m_value : c_nullString; } |
|||
virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) override; |
|||
virtual MemTrieNode* remove(bytesConstRef _key) override; |
|||
virtual void makeRLP(RLPStream& _parentStream) const override; |
|||
|
|||
private: |
|||
bool contains(bytesConstRef _key) const { return _key.size() == m_ext.size() && !memcmp(_key.data(), m_ext.data(), _key.size()); } |
|||
|
|||
std::string m_value; |
|||
}; |
|||
|
|||
class TrieInfixNode: public TrieExtNode |
|||
{ |
|||
public: |
|||
TrieInfixNode(bytesConstRef _key, MemTrieNode* _next): TrieExtNode(_key), m_next(_next) {} |
|||
virtual ~TrieInfixNode() { delete m_next; } |
|||
|
|||
#if ENABLE_DEBUG_PRINT |
|||
virtual void debugPrintBody(std::string const& _indent) const |
|||
{ |
|||
std::cerr << _indent << toHex(m_ext, 1) << ": "; |
|||
m_next->debugPrint(_indent + " "); |
|||
} |
|||
#endif |
|||
|
|||
virtual std::string const& at(bytesConstRef _key) const override { assert(m_next); return contains(_key) ? m_next->at(_key.cropped(m_ext.size())) : c_nullString; } |
|||
virtual MemTrieNode* insert(bytesConstRef _key, std::string const& _value) override; |
|||
virtual MemTrieNode* remove(bytesConstRef _key) override; |
|||
virtual void makeRLP(RLPStream& _parentStream) const override; |
|||
|
|||
private: |
|||
bool contains(bytesConstRef _key) const { return _key.size() >= m_ext.size() && !memcmp(_key.data(), m_ext.data(), m_ext.size()); } |
|||
|
|||
MemTrieNode* m_next; |
|||
}; |
|||
|
|||
void MemTrieNode::putRLP(RLPStream& _parentStream) const |
|||
{ |
|||
RLPStream s; |
|||
makeRLP(s); |
|||
if (s.out().size() < 32) |
|||
_parentStream.APPEND_CHILD(s.out()); |
|||
else |
|||
_parentStream << dev::sha3(s.out()); |
|||
} |
|||
|
|||
void TrieBranchNode::makeRLP(RLPStream& _intoStream) const |
|||
{ |
|||
_intoStream.appendList(17); |
|||
for (auto i: m_nodes) |
|||
if (i) |
|||
i->putRLP(_intoStream); |
|||
else |
|||
_intoStream << ""; |
|||
_intoStream << m_value; |
|||
} |
|||
|
|||
void TrieLeafNode::makeRLP(RLPStream& _intoStream) const |
|||
{ |
|||
_intoStream.appendList(2) << hexPrefixEncode(m_ext, true) << m_value; |
|||
} |
|||
|
|||
void TrieInfixNode::makeRLP(RLPStream& _intoStream) const |
|||
{ |
|||
assert(m_next); |
|||
_intoStream.appendList(2); |
|||
_intoStream << hexPrefixEncode(m_ext, false); |
|||
m_next->putRLP(_intoStream); |
|||
} |
|||
|
|||
MemTrieNode* MemTrieNode::newBranch(bytesConstRef _k1, std::string const& _v1, bytesConstRef _k2, std::string const& _v2) |
|||
{ |
|||
unsigned prefix = commonPrefix(_k1, _k2); |
|||
|
|||
MemTrieNode* ret; |
|||
if (_k1.size() == prefix) |
|||
ret = new TrieBranchNode(_k2[prefix], new TrieLeafNode(_k2.cropped(prefix + 1), _v2), _v1); |
|||
else if (_k2.size() == prefix) |
|||
ret = new TrieBranchNode(_k1[prefix], new TrieLeafNode(_k1.cropped(prefix + 1), _v1), _v2); |
|||
else // both continue after split
|
|||
ret = new TrieBranchNode(_k1[prefix], new TrieLeafNode(_k1.cropped(prefix + 1), _v1), _k2[prefix], new TrieLeafNode(_k2.cropped(prefix + 1), _v2)); |
|||
|
|||
if (prefix) |
|||
// have shared prefix - split.
|
|||
ret = new TrieInfixNode(_k1.cropped(0, prefix), ret); |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
std::string const& TrieBranchNode::at(bytesConstRef _key) const |
|||
{ |
|||
if (_key.empty()) |
|||
return m_value; |
|||
else if (m_nodes[_key[0]] != nullptr) |
|||
return m_nodes[_key[0]]->at(_key.cropped(1)); |
|||
return c_nullString; |
|||
} |
|||
|
|||
MemTrieNode* TrieBranchNode::insert(bytesConstRef _key, std::string const& _value) |
|||
{ |
|||
assert(_value.size()); |
|||
mark(); |
|||
if (_key.empty()) |
|||
m_value = _value; |
|||
else |
|||
if (!m_nodes[_key[0]]) |
|||
m_nodes[_key[0]] = new TrieLeafNode(_key.cropped(1), _value); |
|||
else |
|||
m_nodes[_key[0]] = m_nodes[_key[0]]->insert(_key.cropped(1), _value); |
|||
return this; |
|||
} |
|||
|
|||
MemTrieNode* TrieBranchNode::remove(bytesConstRef _key) |
|||
{ |
|||
if (_key.empty()) |
|||
if (m_value.size()) |
|||
{ |
|||
m_value.clear(); |
|||
return rejig(); |
|||
} |
|||
else {} |
|||
else if (m_nodes[_key[0]] != nullptr) |
|||
{ |
|||
m_nodes[_key[0]] = m_nodes[_key[0]]->remove(_key.cropped(1)); |
|||
return rejig(); |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
MemTrieNode* TrieBranchNode::rejig() |
|||
{ |
|||
mark(); |
|||
byte n = activeBranch(); |
|||
|
|||
if (n == (byte)-1 && m_value.size()) |
|||
{ |
|||
// switch to leaf
|
|||
auto r = new TrieLeafNode(bytesConstRef(), m_value); |
|||
delete this; |
|||
return r; |
|||
} |
|||
else if (n < 16 && m_value.empty()) |
|||
{ |
|||
// only branching to n...
|
|||
if (auto b = dynamic_cast<TrieBranchNode*>(m_nodes[n])) |
|||
{ |
|||
// switch to infix
|
|||
m_nodes[n] = nullptr; |
|||
delete this; |
|||
return new TrieInfixNode(bytesConstRef(&n, 1), b); |
|||
} |
|||
else |
|||
{ |
|||
auto x = dynamic_cast<TrieExtNode*>(m_nodes[n]); |
|||
assert(x); |
|||
// include in child
|
|||
pushFront(x->m_ext, n); |
|||
m_nodes[n] = nullptr; |
|||
delete this; |
|||
return x; |
|||
} |
|||
} |
|||
|
|||
return this; |
|||
} |
|||
|
|||
byte TrieBranchNode::activeBranch() const |
|||
{ |
|||
byte n = (byte)-1; |
|||
for (int i = 0; i < 16; ++i) |
|||
if (m_nodes[i] != nullptr) |
|||
{ |
|||
if (n == (byte)-1) |
|||
n = (byte)i; |
|||
else |
|||
return 16; |
|||
} |
|||
return n; |
|||
} |
|||
|
|||
MemTrieNode* TrieInfixNode::insert(bytesConstRef _key, std::string const& _value) |
|||
{ |
|||
assert(_value.size()); |
|||
mark(); |
|||
if (contains(_key)) |
|||
{ |
|||
m_next = m_next->insert(_key.cropped(m_ext.size()), _value); |
|||
return this; |
|||
} |
|||
else |
|||
{ |
|||
unsigned prefix = commonPrefix(_key, m_ext); |
|||
if (prefix) |
|||
{ |
|||
// one infix becomes two infixes, then insert into the second
|
|||
// instead of pop_front()...
|
|||
trimFront(m_ext, prefix); |
|||
|
|||
return new TrieInfixNode(_key.cropped(0, prefix), insert(_key.cropped(prefix), _value)); |
|||
} |
|||
else |
|||
{ |
|||
// split here.
|
|||
auto f = m_ext[0]; |
|||
trimFront(m_ext, 1); |
|||
MemTrieNode* n = m_ext.empty() ? m_next : this; |
|||
if (n != this) |
|||
{ |
|||
m_next = nullptr; |
|||
delete this; |
|||
} |
|||
TrieBranchNode* ret = new TrieBranchNode(f, n); |
|||
ret->insert(_key, _value); |
|||
return ret; |
|||
} |
|||
} |
|||
} |
|||
|
|||
MemTrieNode* TrieInfixNode::remove(bytesConstRef _key) |
|||
{ |
|||
if (contains(_key)) |
|||
{ |
|||
mark(); |
|||
m_next = m_next->remove(_key.cropped(m_ext.size())); |
|||
if (auto p = dynamic_cast<TrieExtNode*>(m_next)) |
|||
{ |
|||
// merge with child...
|
|||
m_ext.reserve(m_ext.size() + p->m_ext.size()); |
|||
for (auto i: p->m_ext) |
|||
m_ext.push_back(i); |
|||
p->m_ext = m_ext; |
|||
p->mark(); |
|||
m_next = nullptr; |
|||
delete this; |
|||
return p; |
|||
} |
|||
if (!m_next) |
|||
{ |
|||
delete this; |
|||
return nullptr; |
|||
} |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
MemTrieNode* TrieLeafNode::insert(bytesConstRef _key, std::string const& _value) |
|||
{ |
|||
assert(_value.size()); |
|||
mark(); |
|||
if (contains(_key)) |
|||
{ |
|||
m_value = _value; |
|||
return this; |
|||
} |
|||
else |
|||
{ |
|||
// create new trie.
|
|||
auto n = MemTrieNode::newBranch(_key, _value, bytesConstRef(&m_ext), m_value); |
|||
delete this; |
|||
return n; |
|||
} |
|||
} |
|||
|
|||
MemTrieNode* TrieLeafNode::remove(bytesConstRef _key) |
|||
{ |
|||
if (contains(_key)) |
|||
{ |
|||
delete this; |
|||
return nullptr; |
|||
} |
|||
return this; |
|||
} |
|||
|
|||
MemTrie::~MemTrie() |
|||
{ |
|||
delete m_root; |
|||
} |
|||
|
|||
h256 MemTrie::hash256() const |
|||
{ |
|||
return m_root ? m_root->hash256() : sha3(dev::rlp(bytesConstRef())); |
|||
} |
|||
|
|||
bytes MemTrie::rlp() const |
|||
{ |
|||
return m_root ? m_root->rlp() : dev::rlp(bytesConstRef()); |
|||
} |
|||
|
|||
void MemTrie::debugPrint() |
|||
{ |
|||
#if ENABLE_DEBUG_PRINT |
|||
if (m_root) |
|||
m_root->debugPrint(); |
|||
#endif |
|||
} |
|||
|
|||
std::string const& MemTrie::at(std::string const& _key) const |
|||
{ |
|||
if (!m_root) |
|||
return c_nullString; |
|||
auto h = asNibbles(_key); |
|||
return m_root->at(bytesConstRef(&h)); |
|||
} |
|||
|
|||
void MemTrie::insert(std::string const& _key, std::string const& _value) |
|||
{ |
|||
if (_value.empty()) |
|||
remove(_key); |
|||
auto h = asNibbles(_key); |
|||
m_root = m_root ? m_root->insert(&h, _value) : new TrieLeafNode(bytesConstRef(&h), _value); |
|||
} |
|||
|
|||
void MemTrie::remove(std::string const& _key) |
|||
{ |
|||
if (m_root) |
|||
{ |
|||
auto h = asNibbles(_key); |
|||
m_root = m_root->remove(&h); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
@ -1,54 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file MemTrie.h
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/FixedHash.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
|
|||
class MemTrieNode; |
|||
|
|||
/**
|
|||
* @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree. |
|||
*/ |
|||
class MemTrie |
|||
{ |
|||
public: |
|||
MemTrie(): m_root(nullptr) {} |
|||
~MemTrie(); |
|||
|
|||
h256 hash256() const; |
|||
bytes rlp() const; |
|||
|
|||
void debugPrint(); |
|||
|
|||
std::string const& at(std::string const& _key) const; |
|||
void insert(std::string const& _key, std::string const& _value); |
|||
void remove(std::string const& _key); |
|||
|
|||
private: |
|||
MemTrieNode* m_root; |
|||
}; |
|||
|
|||
} |
@ -1,220 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file SecretStore.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2015 |
|||
* Secret store test functions. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include "../JsonSpiritHeaders.h" |
|||
#include <libdevcrypto/SecretStore.h> |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libdevcore/TrieDB.h> |
|||
#include <libdevcore/TrieHash.h> |
|||
#include "MemTrie.h" |
|||
#include <test/TestHelper.h> |
|||
#include <test/TestUtils.h> |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::test; |
|||
|
|||
namespace js = json_spirit; |
|||
namespace fs = boost::filesystem; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(KeyStore) |
|||
|
|||
BOOST_AUTO_TEST_CASE(basic_tests) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
|
|||
testPath += "/KeyStoreTests"; |
|||
|
|||
cnote << "Testing Key Store..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/basic_tests.json"); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'KeyStoreTests/basic_tests.json' is empty. Have you cloned the 'tests' repo branch develop?"); |
|||
js::read_string(s, v); |
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
cnote << i.first; |
|||
js::mObject& o = i.second.get_obj(); |
|||
TransientDirectory tmpDir; |
|||
SecretStore store(tmpDir.path()); |
|||
h128 u = store.readKeyContent(js::write_string(o["json"], false)); |
|||
cdebug << "read uuid" << u; |
|||
bytesSec s = store.secret(u, [&](){ return o["password"].get_str(); }); |
|||
cdebug << "got secret" << toHex(s.makeInsecure()); |
|||
BOOST_REQUIRE_EQUAL(toHex(s.makeInsecure()), o["priv"].get_str()); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(import_key_from_file) |
|||
{ |
|||
// Imports a key from an external file. Tests that the imported key is there
|
|||
// and that the external file is not deleted.
|
|||
TransientDirectory importDir; |
|||
string importFile = importDir.path() + "/import.json"; |
|||
TransientDirectory storeDir; |
|||
string keyData = R"({ |
|||
"version": 3, |
|||
"crypto": { |
|||
"ciphertext": "d69313b6470ac1942f75d72ebf8818a0d484ac78478a132ee081cd954d6bd7a9", |
|||
"cipherparams": { "iv": "ffffffffffffffffffffffffffffffff" }, |
|||
"kdf": "pbkdf2", |
|||
"kdfparams": { "dklen": 32, "c": 262144, "prf": "hmac-sha256", "salt": "c82ef14476014cbf438081a42709e2ed" }, |
|||
"mac": "cf6bfbcc77142a22c4a908784b4a16f1023a1d0e2aff404c20158fa4f1587177", |
|||
"cipher": "aes-128-ctr", |
|||
"version": 1 |
|||
}, |
|||
"id": "abb67040-8dbe-0dad-fc39-2b082ef0ee5f" |
|||
})"; |
|||
string password = "bar"; |
|||
string priv = "0202020202020202020202020202020202020202020202020202020202020202"; |
|||
writeFile(importFile, keyData); |
|||
|
|||
h128 uuid; |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 0); |
|||
uuid = store.importKey(importFile); |
|||
BOOST_CHECK(!!uuid); |
|||
BOOST_CHECK(contentsString(importFile) == keyData); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
} |
|||
fs::remove(importFile); |
|||
// now do it again to check whether SecretStore properly stored it on disk
|
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(import_secret) |
|||
{ |
|||
for (string const& password: {"foobar", ""}) |
|||
{ |
|||
TransientDirectory storeDir; |
|||
string priv = "0202020202020202020202020202020202020202020202020202020202020202"; |
|||
|
|||
h128 uuid; |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 0); |
|||
uuid = store.importSecret(bytesSec(fromHex(priv)), password); |
|||
BOOST_CHECK(!!uuid); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
} |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(import_secret_bytesConstRef) |
|||
{ |
|||
for (string const& password: {"foobar", ""}) |
|||
{ |
|||
TransientDirectory storeDir; |
|||
string priv = "0202020202020202020202020202020202020202020202020202020202020202"; |
|||
|
|||
h128 uuid; |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 0); |
|||
bytes privateBytes = fromHex(priv); |
|||
uuid = store.importSecret(&privateBytes, password); |
|||
BOOST_CHECK(!!uuid); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
} |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(wrong_password) |
|||
{ |
|||
TransientDirectory storeDir; |
|||
SecretStore store(storeDir.path()); |
|||
string password = "foobar"; |
|||
string priv = "0202020202020202020202020202020202020202020202020202020202020202"; |
|||
|
|||
h128 uuid; |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 0); |
|||
uuid = store.importSecret(bytesSec(fromHex(priv)), password); |
|||
BOOST_CHECK(!!uuid); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
// password will not be queried
|
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return "abcdefg"; }).makeInsecure())); |
|||
} |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK(store.secret(uuid, [&](){ return "abcdefg"; }).empty()); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(recode) |
|||
{ |
|||
TransientDirectory storeDir; |
|||
SecretStore store(storeDir.path()); |
|||
string password = "foobar"; |
|||
string changedPassword = "abcdefg"; |
|||
string priv = "0202020202020202020202020202020202020202020202020202020202020202"; |
|||
|
|||
h128 uuid; |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 0); |
|||
uuid = store.importSecret(bytesSec(fromHex(priv)), password); |
|||
BOOST_CHECK(!!uuid); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure())); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
} |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK(store.secret(uuid, [&](){ return "abcdefg"; }).empty()); |
|||
BOOST_CHECK(store.recode(uuid, changedPassword, [&](){ return password; })); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; }).makeInsecure())); |
|||
store.clearCache(); |
|||
BOOST_CHECK(store.secret(uuid, [&](){ return password; }).empty()); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; }).makeInsecure())); |
|||
} |
|||
{ |
|||
SecretStore store(storeDir.path()); |
|||
BOOST_CHECK_EQUAL(store.keys().size(), 1); |
|||
BOOST_CHECK(store.secret(uuid, [&](){ return password; }).empty()); |
|||
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; }).makeInsecure())); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,879 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file crypto.cpp
|
|||
* @author Alex Leverington <nessence@gmail.com> |
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Crypto test functions. |
|||
*/ |
|||
|
|||
#if ETH_HAVE_SECP256K1 |
|||
#include <secp256k1/include/secp256k1.h> |
|||
#endif |
|||
#include <libdevcore/Common.h> |
|||
#include <libdevcore/RLP.h> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethereum/Transaction.h> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/SHA3.h> |
|||
#include <libdevcrypto/ECDHE.h> |
|||
#include <libdevcrypto/CryptoPP.h> |
|||
#include <test/TestUtils.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::test; |
|||
using namespace dev::crypto; |
|||
using namespace CryptoPP; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(devcrypto) |
|||
|
|||
static Secp256k1PP s_secp256k1; |
|||
static CryptoPP::AutoSeededRandomPool s_rng; |
|||
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>::EllipticCurve s_curve(s_params.GetCurve()); |
|||
|
|||
BOOST_AUTO_TEST_CASE(sha3general) |
|||
{ |
|||
BOOST_REQUIRE_EQUAL(sha3(""), h256("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); |
|||
BOOST_REQUIRE_EQUAL(sha3("hello"), h256("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(emptySHA3Types) |
|||
{ |
|||
h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); |
|||
BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3); |
|||
|
|||
h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); |
|||
BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3); |
|||
} |
|||
|
|||
#if ETH_HAVE_SECP256K1 |
|||
BOOST_AUTO_TEST_CASE(secp256k1lib) |
|||
{ |
|||
KeyPair k = KeyPair::create(); |
|||
BOOST_REQUIRE(!!k.sec()); |
|||
BOOST_REQUIRE(!!k.pub()); |
|||
Public test = toPublic(k.sec()); |
|||
BOOST_REQUIRE(k.pub() == test); |
|||
} |
|||
#endif |
|||
|
|||
BOOST_AUTO_TEST_CASE(cryptopp_patch) |
|||
{ |
|||
KeyPair k = KeyPair::create(); |
|||
bytes io_text; |
|||
s_secp256k1.decrypt(k.sec(), io_text); |
|||
BOOST_REQUIRE_EQUAL(io_text.size(), 0); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(verify_secert) |
|||
{ |
|||
Secret empty; |
|||
KeyPair kNot(empty); |
|||
BOOST_REQUIRE(!kNot.address()); |
|||
KeyPair k(sha3(empty)); |
|||
BOOST_REQUIRE(k.address()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) |
|||
{ |
|||
string message("Now is the time for all good persons to come to the aid of humanity."); |
|||
bytes m = asBytes(message); |
|||
bytesConstRef bcr(&m); |
|||
|
|||
KeyPair k = KeyPair::create(); |
|||
bytes cipher; |
|||
encrypt(k.pub(), bcr, cipher); |
|||
BOOST_REQUIRE(cipher != asBytes(message) && cipher.size() > 0); |
|||
|
|||
bytes plain; |
|||
decrypt(k.sec(), bytesConstRef(&cipher), plain); |
|||
|
|||
BOOST_REQUIRE(asString(plain) == message); |
|||
BOOST_REQUIRE(plain == asBytes(message)); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport) |
|||
{ |
|||
#if ETH_HAVE_SECP256K1 |
|||
secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); |
|||
#endif |
|||
|
|||
// base secret
|
|||
Secret secret(sha3("privacy")); |
|||
|
|||
// we get ec params from signer
|
|||
ECDSA<ECP, SHA3_256>::Signer signer; |
|||
|
|||
// e := sha3(msg)
|
|||
bytes e(fromHex("0x01")); |
|||
e.resize(32); |
|||
int tests = 2; |
|||
while (sha3(&e, &e), secret = sha3(secret), tests--) |
|||
{ |
|||
KeyPair key(secret); |
|||
Public pkey = key.pub(); |
|||
signer.AccessKey().Initialize(s_params, secretToExponent(secret)); |
|||
|
|||
h256 he(sha3(e)); |
|||
Integer heInt(he.asBytes().data(), 32); |
|||
h256 k(crypto::kdf(secret, he)); |
|||
Integer kInt(k.asBytes().data(), 32); |
|||
kInt %= s_params.GetSubgroupOrder()-1; |
|||
|
|||
ECP::Point rp = s_params.ExponentiateBase(kInt); |
|||
Integer const& q = s_params.GetGroupOrder(); |
|||
Integer r = s_params.ConvertElementToInteger(rp); |
|||
|
|||
Integer kInv = kInt.InverseMod(q); |
|||
Integer s = (kInv * (Integer(secret.data(), 32) * r + heInt)) % q; |
|||
BOOST_REQUIRE(!!r && !!s); |
|||
|
|||
Signature sig; |
|||
sig[64] = rp.y.IsOdd() ? 1 : 0; |
|||
r.Encode(sig.data(), 32); |
|||
s.Encode(sig.data() + 32, 32); |
|||
|
|||
Public p = dev::recover(sig, he); |
|||
BOOST_REQUIRE(p == pkey); |
|||
|
|||
// verify w/cryptopp
|
|||
BOOST_REQUIRE(s_secp256k1.verify(pkey, sig, bytesConstRef(&e))); |
|||
|
|||
// verify with secp256k1lib
|
|||
byte encpub[65] = {0x04}; |
|||
memcpy(&encpub[1], pkey.data(), 64); |
|||
byte dersig[72]; |
|||
size_t cssz = DSAConvertSignatureFormat(dersig, 72, DSA_DER, sig.data(), 64, DSA_P1363); |
|||
BOOST_CHECK(cssz <= 72); |
|||
#if ETH_HAVE_SECP256K1 |
|||
BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(ctx, he.data(), dersig, cssz, encpub, 65)); |
|||
#endif |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) |
|||
{ |
|||
#ifdef CRYPTOPPNOTBROKEN |
|||
secp256k1_start(); |
|||
|
|||
// cryptopp integer encoding
|
|||
Integer nHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2H"); |
|||
Integer nB(fromHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2").data(), 32); |
|||
BOOST_REQUIRE(nHex == nB); |
|||
|
|||
bytes sbytes(fromHex("0xFFFF")); |
|||
Secret secret(sha3(sbytes)); |
|||
KeyPair key(secret); |
|||
|
|||
bytes m(1, 0xff); |
|||
int tests = 2; |
|||
while (m[0]++, tests--) |
|||
{ |
|||
h256 hm(sha3(m)); |
|||
Integer hInt(hm.asBytes().data(), 32); |
|||
h256 k(hm ^ key.sec()); |
|||
Integer kInt(k.asBytes().data(), 32); |
|||
|
|||
// raw sign w/cryptopp (doesn't pass through cryptopp hash filter)
|
|||
ECDSA<ECP, SHA3_256>::Signer signer; |
|||
signer.AccessKey().Initialize(s_params, secretToExponent(key.sec())); |
|||
Integer r, s; |
|||
signer.RawSign(kInt, hInt, r, s); |
|||
|
|||
// verify cryptopp raw-signature w/cryptopp
|
|||
ECDSA<ECP, SHA3_256>::Verifier verifier; |
|||
verifier.AccessKey().Initialize(s_params, publicToPoint(key.pub())); |
|||
Signature sigppraw; |
|||
r.Encode(sigppraw.data(), 32); |
|||
s.Encode(sigppraw.data() + 32, 32); |
|||
BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), sigppraw.data(), 64)); |
|||
// BOOST_REQUIRE(crypto::verify(key.pub(), sigppraw, bytesConstRef(&m)));
|
|||
BOOST_REQUIRE(dev::verify(key.pub(), sigppraw, hm)); |
|||
|
|||
// sign with cryptopp, verify, recover w/sec256lib
|
|||
Signature seclibsig(dev::sign(key.sec(), hm)); |
|||
BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), seclibsig.data(), 64)); |
|||
// BOOST_REQUIRE(crypto::verify(key.pub(), seclibsig, bytesConstRef(&m)));
|
|||
BOOST_REQUIRE(dev::verify(key.pub(), seclibsig, hm)); |
|||
BOOST_REQUIRE(dev::recover(seclibsig, hm) == key.pub()); |
|||
|
|||
// sign with cryptopp (w/hash filter?), verify with cryptopp
|
|||
bytes sigppb(signer.MaxSignatureLength()); |
|||
size_t ssz = signer.SignMessage(s_rng, m.data(), m.size(), sigppb.data()); |
|||
Signature sigpp; |
|||
memcpy(sigpp.data(), sigppb.data(), 64); |
|||
BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), sigppb.data(), ssz)); |
|||
// BOOST_REQUIRE(crypto::verify(key.pub(), sigpp, bytesConstRef(&m)));
|
|||
BOOST_REQUIRE(dev::verify(key.pub(), sigpp, hm)); |
|||
|
|||
// sign with cryptopp and stringsource hash filter
|
|||
string sigstr; |
|||
StringSource ssrc(asString(m), true, new SignerFilter(s_rng, signer, new StringSink(sigstr))); |
|||
FixedHash<sizeof(Signature)> retsig((byte const*)sigstr.data(), Signature::ConstructFromPointer); |
|||
BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), retsig.data(), 64)); |
|||
// BOOST_REQUIRE(crypto::verify(key.pub(), retsig, bytesConstRef(&m)));
|
|||
BOOST_REQUIRE(dev::verify(key.pub(), retsig, hm)); |
|||
|
|||
/// verification w/sec256lib
|
|||
// requires public key and sig in standard format
|
|||
byte encpub[65] = {0x04}; |
|||
memcpy(&encpub[1], key.pub().data(), 64); |
|||
byte dersig[72]; |
|||
|
|||
// verify sec256lib sig w/sec256lib
|
|||
size_t cssz = DSAConvertSignatureFormat(dersig, 72, DSA_DER, seclibsig.data(), 64, DSA_P1363); |
|||
BOOST_CHECK(cssz <= 72); |
|||
BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(hm.data(), sizeof(hm), dersig, cssz, encpub, 65)); |
|||
|
|||
// verify cryptopp-raw sig w/sec256lib
|
|||
cssz = DSAConvertSignatureFormat(dersig, 72, DSA_DER, sigppraw.data(), 64, DSA_P1363); |
|||
BOOST_CHECK(cssz <= 72); |
|||
BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(hm.data(), sizeof(hm), dersig, cssz, encpub, 65)); |
|||
|
|||
// verify cryptopp sig w/sec256lib
|
|||
cssz = DSAConvertSignatureFormat(dersig, 72, DSA_DER, sigppb.data(), 64, DSA_P1363); |
|||
BOOST_CHECK(cssz <= 72); |
|||
BOOST_REQUIRE(1 == secp256k1_ecdsa_verify(hm.data(), sizeof(hm), dersig, cssz, encpub, 65)); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(sha3_norestart) |
|||
{ |
|||
CryptoPP::SHA3_256 ctx; |
|||
bytes input(asBytes("test")); |
|||
ctx.Update(input.data(), 4); |
|||
CryptoPP::SHA3_256 ctxCopy(ctx); |
|||
bytes interimDigest(32); |
|||
ctx.Final(interimDigest.data()); |
|||
ctx.Update(input.data(), 4); |
|||
bytes firstDigest(32); |
|||
ctx.Final(firstDigest.data()); |
|||
BOOST_REQUIRE(interimDigest == firstDigest); |
|||
|
|||
ctxCopy.Update(input.data(), 4); |
|||
bytes finalDigest(32); |
|||
ctxCopy.Final(interimDigest.data()); |
|||
BOOST_REQUIRE(interimDigest != finalDigest); |
|||
|
|||
// we can do this another way -- copy the context for final
|
|||
ctxCopy.Update(input.data(), 4); |
|||
ctxCopy.Update(input.data(), 4); |
|||
CryptoPP::SHA3_256 finalCtx(ctxCopy); |
|||
bytes finalDigest2(32); |
|||
finalCtx.Final(finalDigest2.data()); |
|||
BOOST_REQUIRE(finalDigest2 == interimDigest); |
|||
ctxCopy.Update(input.data(), 4); |
|||
bytes finalDigest3(32); |
|||
finalCtx.Final(finalDigest3.data()); |
|||
BOOST_REQUIRE(finalDigest2 != finalDigest3); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecies_kdf) |
|||
{ |
|||
KeyPair local = KeyPair::create(); |
|||
KeyPair remote = KeyPair::create(); |
|||
// nonce
|
|||
Secret z1; |
|||
ecdh::agree(local.sec(), remote.pub(), z1); |
|||
auto key1 = s_secp256k1.eciesKDF(z1, bytes(), 64); |
|||
bytesConstRef eKey1 = bytesConstRef(&key1).cropped(0, 32); |
|||
bytesRef mKey1 = bytesRef(&key1).cropped(32, 32); |
|||
sha3(mKey1, mKey1); |
|||
|
|||
Secret z2; |
|||
ecdh::agree(remote.sec(), local.pub(), z2); |
|||
auto key2 = s_secp256k1.eciesKDF(z2, bytes(), 64); |
|||
bytesConstRef eKey2 = bytesConstRef(&key2).cropped(0, 32); |
|||
bytesRef mKey2 = bytesRef(&key2).cropped(32, 32); |
|||
sha3(mKey2, mKey2); |
|||
|
|||
BOOST_REQUIRE(eKey1.toBytes() == eKey2.toBytes()); |
|||
BOOST_REQUIRE(mKey1.toBytes() == mKey2.toBytes()); |
|||
|
|||
BOOST_REQUIRE(!!z1); |
|||
BOOST_REQUIRE(z1 == z2); |
|||
|
|||
BOOST_REQUIRE(key1.size() > 0 && ((u512)h512(key1)) > 0); |
|||
BOOST_REQUIRE(key1 == key2); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecies_standard) |
|||
{ |
|||
KeyPair k = KeyPair::create(); |
|||
|
|||
string message("Now is the time for all good persons to come to the aid of humanity."); |
|||
string original = message; |
|||
bytes b = asBytes(message); |
|||
|
|||
s_secp256k1.encryptECIES(k.pub(), b); |
|||
BOOST_REQUIRE(b != asBytes(original)); |
|||
BOOST_REQUIRE(b.size() > 0 && b[0] == 0x04); |
|||
|
|||
s_secp256k1.decryptECIES(k.sec(), b); |
|||
BOOST_REQUIRE(bytesConstRef(&b).cropped(0, original.size()).toBytes() == asBytes(original)); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecies_eckeypair) |
|||
{ |
|||
KeyPair k = KeyPair::create(); |
|||
|
|||
string message("Now is the time for all good persons to come to the aid of humanity."); |
|||
string original = message; |
|||
|
|||
bytes b = asBytes(message); |
|||
s_secp256k1.encrypt(k.pub(), b); |
|||
BOOST_REQUIRE(b != asBytes(original)); |
|||
|
|||
s_secp256k1.decrypt(k.sec(), b); |
|||
BOOST_REQUIRE(b == asBytes(original)); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecdh) |
|||
{ |
|||
cnote << "Testing ecdh..."; |
|||
|
|||
ECDH<ECP>::Domain dhLocal(s_curveOID); |
|||
SecByteBlock privLocal(dhLocal.PrivateKeyLength()); |
|||
SecByteBlock pubLocal(dhLocal.PublicKeyLength()); |
|||
dhLocal.GenerateKeyPair(s_rng, privLocal, pubLocal); |
|||
|
|||
ECDH<ECP>::Domain dhRemote(s_curveOID); |
|||
SecByteBlock privRemote(dhRemote.PrivateKeyLength()); |
|||
SecByteBlock pubRemote(dhRemote.PublicKeyLength()); |
|||
dhRemote.GenerateKeyPair(s_rng, privRemote, pubRemote); |
|||
|
|||
assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength()); |
|||
|
|||
// local: send public to remote; remote: send public to local
|
|||
|
|||
// Local
|
|||
SecByteBlock sharedLocal(dhLocal.AgreedValueLength()); |
|||
assert(dhLocal.Agree(sharedLocal, privLocal, pubRemote)); |
|||
|
|||
// Remote
|
|||
SecByteBlock sharedRemote(dhRemote.AgreedValueLength()); |
|||
assert(dhRemote.Agree(sharedRemote, privRemote, pubLocal)); |
|||
|
|||
// Test
|
|||
Integer ssLocal, ssRemote; |
|||
ssLocal.Decode(sharedLocal.BytePtr(), sharedLocal.SizeInBytes()); |
|||
ssRemote.Decode(sharedRemote.BytePtr(), sharedRemote.SizeInBytes()); |
|||
|
|||
assert(ssLocal != 0); |
|||
assert(ssLocal == ssRemote); |
|||
|
|||
|
|||
// Now use our keys
|
|||
KeyPair a = KeyPair::create(); |
|||
byte puba[65] = {0x04}; |
|||
memcpy(&puba[1], a.pub().data(), 64); |
|||
|
|||
KeyPair b = KeyPair::create(); |
|||
byte pubb[65] = {0x04}; |
|||
memcpy(&pubb[1], b.pub().data(), 64); |
|||
|
|||
ECDH<ECP>::Domain dhA(s_curveOID); |
|||
Secret shared; |
|||
BOOST_REQUIRE(dhA.Agree(shared.writable().data(), a.sec().data(), pubb)); |
|||
BOOST_REQUIRE(shared); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecdhe) |
|||
{ |
|||
cnote << "Testing ecdhe..."; |
|||
|
|||
ECDHE a, b; |
|||
BOOST_CHECK_NE(a.pubkey(), b.pubkey()); |
|||
|
|||
ECDHE local; |
|||
ECDHE remote; |
|||
|
|||
// local tx pubkey -> remote
|
|||
Secret sremote; |
|||
remote.agree(local.pubkey(), sremote); |
|||
|
|||
// remote tx pbukey -> local
|
|||
Secret slocal; |
|||
local.agree(remote.pubkey(), slocal); |
|||
|
|||
BOOST_REQUIRE(sremote); |
|||
BOOST_REQUIRE(slocal); |
|||
BOOST_REQUIRE_EQUAL(sremote, slocal); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(handshakeNew) |
|||
{ |
|||
// authInitiator -> E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0)
|
|||
// authRecipient -> E(remote-pubk, ecdhe-random-pubk || nonce || 0x0)
|
|||
|
|||
h256 base(sha3("privacy")); |
|||
sha3(base.ref(), base.ref()); |
|||
Secret nodeAsecret(base); |
|||
KeyPair nodeA(nodeAsecret); |
|||
BOOST_REQUIRE(nodeA.pub()); |
|||
|
|||
sha3(base.ref(), base.ref()); |
|||
Secret nodeBsecret(base); |
|||
KeyPair nodeB(nodeBsecret); |
|||
BOOST_REQUIRE(nodeB.pub()); |
|||
|
|||
BOOST_REQUIRE_NE(nodeA.sec(), nodeB.sec()); |
|||
|
|||
// Initiator is Alice (nodeA)
|
|||
ECDHE eA; |
|||
bytes nAbytes(fromHex("0xAAAA")); |
|||
h256 nonceA(sha3(nAbytes)); |
|||
bytes auth(Signature::size + h256::size + Public::size + h256::size + 1); |
|||
Secret ssA; |
|||
{ |
|||
bytesRef sig(&auth[0], Signature::size); |
|||
bytesRef hepubk(&auth[Signature::size], h256::size); |
|||
bytesRef pubk(&auth[Signature::size + h256::size], Public::size); |
|||
bytesRef nonce(&auth[Signature::size + h256::size + Public::size], h256::size); |
|||
|
|||
crypto::ecdh::agree(nodeA.sec(), nodeB.pub(), ssA); |
|||
sign(eA.seckey(), (ssA ^ nonceA).makeInsecure()).ref().copyTo(sig); |
|||
sha3(eA.pubkey().ref(), hepubk); |
|||
nodeA.pub().ref().copyTo(pubk); |
|||
nonceA.ref().copyTo(nonce); |
|||
auth[auth.size() - 1] = 0x0; |
|||
} |
|||
bytes authcipher; |
|||
encrypt(nodeB.pub(), &auth, authcipher); |
|||
BOOST_REQUIRE_EQUAL(authcipher.size(), 279); |
|||
|
|||
// Receipient is Bob (nodeB)
|
|||
ECDHE eB; |
|||
bytes nBbytes(fromHex("0xBBBB")); |
|||
h256 nonceB(sha3(nAbytes)); |
|||
bytes ack(Public::size + h256::size + 1); |
|||
{ |
|||
// todo: replace nodeA.pub() in encrypt()
|
|||
// decrypt public key from auth
|
|||
bytes authdecrypted; |
|||
decrypt(nodeB.sec(), &authcipher, authdecrypted); |
|||
Public node; |
|||
bytesConstRef pubk(&authdecrypted[Signature::size + h256::size], Public::size); |
|||
pubk.copyTo(node.ref()); |
|||
|
|||
bytesRef epubk(&ack[0], Public::size); |
|||
bytesRef nonce(&ack[Public::size], h256::size); |
|||
|
|||
eB.pubkey().ref().copyTo(epubk); |
|||
nonceB.ref().copyTo(nonce); |
|||
auth[auth.size() - 1] = 0x0; |
|||
} |
|||
bytes ackcipher; |
|||
encrypt(nodeA.pub(), &ack, ackcipher); |
|||
BOOST_REQUIRE_EQUAL(ackcipher.size(), 182); |
|||
|
|||
BOOST_REQUIRE(eA.pubkey()); |
|||
BOOST_REQUIRE(eB.pubkey()); |
|||
BOOST_REQUIRE_NE(eA.seckey(), eB.seckey()); |
|||
|
|||
/// Alice (after receiving ack)
|
|||
Secret aEncryptK; |
|||
Secret aMacK; |
|||
Secret aEgressMac; |
|||
Secret aIngressMac; |
|||
{ |
|||
bytes ackdecrypted; |
|||
decrypt(nodeA.sec(), &ackcipher, ackdecrypted); |
|||
BOOST_REQUIRE(ackdecrypted.size()); |
|||
bytesConstRef ackRef(&ackdecrypted); |
|||
Public eBAck; |
|||
h256 nonceBAck; |
|||
ackRef.cropped(0, Public::size).copyTo(bytesRef(eBAck.data(), Public::size)); |
|||
ackRef.cropped(Public::size, h256::size).copyTo(nonceBAck.ref()); |
|||
BOOST_REQUIRE_EQUAL(eBAck, eB.pubkey()); |
|||
BOOST_REQUIRE_EQUAL(nonceBAck, nonceB); |
|||
|
|||
// TODO: export ess and require equal to b
|
|||
|
|||
bytes keyMaterialBytes(512); |
|||
bytesRef keyMaterial(&keyMaterialBytes); |
|||
|
|||
Secret ess; |
|||
// todo: ecdh-agree should be able to output bytes
|
|||
eA.agree(eBAck, ess); |
|||
ess.ref().copyTo(keyMaterial.cropped(0, h256::size)); |
|||
ssA.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); |
|||
// auto token = sha3(ssA);
|
|||
aEncryptK = sha3Secure(keyMaterial); |
|||
aEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); |
|||
aMacK = sha3Secure(keyMaterial); |
|||
|
|||
keyMaterialBytes.resize(h256::size + authcipher.size()); |
|||
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); |
|||
(aMacK ^ nonceBAck).ref().copyTo(keyMaterial); |
|||
bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size())); |
|||
aEgressMac = sha3Secure(keyMaterial); |
|||
|
|||
keyMaterialBytes.resize(h256::size + ackcipher.size()); |
|||
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); |
|||
(aMacK ^ nonceA).ref().copyTo(keyMaterial); |
|||
bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size())); |
|||
aIngressMac = sha3Secure(keyMaterial); |
|||
} |
|||
|
|||
|
|||
/// Bob (after sending ack)
|
|||
Secret ssB; |
|||
crypto::ecdh::agree(nodeB.sec(), nodeA.pub(), ssB); |
|||
BOOST_REQUIRE_EQUAL(ssA, ssB); |
|||
|
|||
Secret bEncryptK; |
|||
Secret bMacK; |
|||
Secret bEgressMac; |
|||
Secret bIngressMac; |
|||
{ |
|||
bytes authdecrypted; |
|||
decrypt(nodeB.sec(), &authcipher, authdecrypted); |
|||
BOOST_REQUIRE(authdecrypted.size()); |
|||
bytesConstRef ackRef(&authdecrypted); |
|||
Signature sigAuth; |
|||
h256 heA; |
|||
Public eAAuth; |
|||
Public nodeAAuth; |
|||
h256 nonceAAuth; |
|||
bytesConstRef sig(&authdecrypted[0], Signature::size); |
|||
bytesConstRef hepubk(&authdecrypted[Signature::size], h256::size); |
|||
bytesConstRef pubk(&authdecrypted[Signature::size + h256::size], Public::size); |
|||
bytesConstRef nonce(&authdecrypted[Signature::size + h256::size + Public::size], h256::size); |
|||
|
|||
nonce.copyTo(nonceAAuth.ref()); |
|||
pubk.copyTo(nodeAAuth.ref()); |
|||
BOOST_REQUIRE(nonceAAuth); |
|||
BOOST_REQUIRE_EQUAL(nonceA, nonceAAuth); |
|||
BOOST_REQUIRE(nodeAAuth); |
|||
BOOST_REQUIRE_EQUAL(nodeA.pub(), nodeAAuth); // bad test, bad!!!
|
|||
hepubk.copyTo(heA.ref()); |
|||
sig.copyTo(sigAuth.ref()); |
|||
|
|||
Secret ss; |
|||
s_secp256k1.agree(nodeB.sec(), nodeAAuth, ss); |
|||
eAAuth = recover(sigAuth, (ss ^ nonceAAuth).makeInsecure()); |
|||
// todo: test when this fails; means remote is bad or packet bits were flipped
|
|||
BOOST_REQUIRE_EQUAL(heA, sha3(eAAuth)); |
|||
BOOST_REQUIRE_EQUAL(eAAuth, eA.pubkey()); |
|||
|
|||
bytes keyMaterialBytes(512); |
|||
bytesRef keyMaterial(&keyMaterialBytes); |
|||
|
|||
Secret ess; |
|||
// todo: ecdh-agree should be able to output bytes
|
|||
eB.agree(eAAuth, ess); |
|||
// s_secp256k1.agree(eB.seckey(), eAAuth, ess);
|
|||
ess.ref().copyTo(keyMaterial.cropped(0, h256::size)); |
|||
ssB.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); |
|||
// auto token = sha3(ssA);
|
|||
bEncryptK = sha3Secure(keyMaterial); |
|||
bEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size)); |
|||
bMacK = sha3Secure(keyMaterial); |
|||
|
|||
// todo: replace nonceB with decrypted nonceB
|
|||
keyMaterialBytes.resize(h256::size + ackcipher.size()); |
|||
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); |
|||
(bMacK ^ nonceAAuth).ref().copyTo(keyMaterial); |
|||
bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size())); |
|||
bEgressMac = sha3Secure(keyMaterial); |
|||
|
|||
keyMaterialBytes.resize(h256::size + authcipher.size()); |
|||
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size()); |
|||
(bMacK ^ nonceB).ref().copyTo(keyMaterial); |
|||
bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size())); |
|||
bIngressMac = sha3Secure(keyMaterial); |
|||
} |
|||
|
|||
BOOST_REQUIRE_EQUAL(aEncryptK, bEncryptK); |
|||
BOOST_REQUIRE_EQUAL(aMacK, bMacK); |
|||
BOOST_REQUIRE_EQUAL(aEgressMac, bIngressMac); |
|||
BOOST_REQUIRE_EQUAL(bEgressMac, aIngressMac); |
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecies_aes128_ctr_unaligned) |
|||
{ |
|||
SecureFixedHash<16> encryptK(sha3("..."), h128::AlignLeft); |
|||
h256 egressMac(sha3("+++")); |
|||
// TESTING: send encrypt magic sequence
|
|||
bytes magic {0x22,0x40,0x08,0x91}; |
|||
bytes magicCipherAndMac; |
|||
magicCipherAndMac = encryptSymNoAuth(encryptK, h128(), &magic); |
|||
|
|||
magicCipherAndMac.resize(magicCipherAndMac.size() + 32); |
|||
sha3mac(egressMac.ref(), &magic, egressMac.ref()); |
|||
egressMac.ref().copyTo(bytesRef(&magicCipherAndMac).cropped(magicCipherAndMac.size() - 32, 32)); |
|||
|
|||
bytesConstRef cipher(&magicCipherAndMac[0], magicCipherAndMac.size() - 32); |
|||
bytes plaintext = decryptSymNoAuth(encryptK, h128(), cipher).makeInsecure(); |
|||
|
|||
plaintext.resize(magic.size()); |
|||
// @alex @subtly TODO: FIX: this check is pointless with the above line.
|
|||
BOOST_REQUIRE(plaintext.size() > 0); |
|||
BOOST_REQUIRE(magic == plaintext); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ecies_aes128_ctr) |
|||
{ |
|||
SecureFixedHash<16> k(sha3("0xAAAA"), h128::AlignLeft); |
|||
string m = "AAAAAAAAAAAAAAAA"; |
|||
bytesConstRef msg((byte*)m.data(), m.size()); |
|||
|
|||
bytes ciphertext; |
|||
h128 iv; |
|||
tie(ciphertext, iv) = encryptSymNoAuth(k, msg); |
|||
|
|||
bytes plaintext = decryptSymNoAuth(k, iv, &ciphertext).makeInsecure(); |
|||
BOOST_REQUIRE_EQUAL(asString(plaintext), m); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) |
|||
{ |
|||
const int aesKeyLen = 16; |
|||
BOOST_REQUIRE(sizeof(char) == sizeof(byte)); |
|||
|
|||
// generate test key
|
|||
AutoSeededRandomPool rng; |
|||
SecByteBlock key(0x00, aesKeyLen); |
|||
rng.GenerateBlock(key, key.size()); |
|||
|
|||
// cryptopp uses IV as nonce/counter which is same as using nonce w/0 ctr
|
|||
FixedHash<AES::BLOCKSIZE> ctr; |
|||
rng.GenerateBlock(ctr.data(), sizeof(ctr)); |
|||
|
|||
// used for decrypt
|
|||
FixedHash<AES::BLOCKSIZE> ctrcopy(ctr); |
|||
|
|||
string text = "Now is the time for all good persons to come to the aid of humanity."; |
|||
unsigned char const* in = (unsigned char*)&text[0]; |
|||
unsigned char* out = (unsigned char*)&text[0]; |
|||
string original = text; |
|||
string doublespeak = text + text; |
|||
|
|||
string cipherCopy; |
|||
try |
|||
{ |
|||
CTR_Mode<AES>::Encryption e; |
|||
e.SetKeyWithIV(key, key.size(), ctr.data()); |
|||
|
|||
// 68 % 255 should be difference of counter
|
|||
e.ProcessData(out, in, text.size()); |
|||
ctr = h128(u128(ctr) + text.size() / 16); |
|||
|
|||
BOOST_REQUIRE(text != original); |
|||
cipherCopy = text; |
|||
} |
|||
catch (CryptoPP::Exception& _e) |
|||
{ |
|||
cerr << _e.what() << endl; |
|||
} |
|||
|
|||
try |
|||
{ |
|||
CTR_Mode< AES >::Decryption d; |
|||
d.SetKeyWithIV(key, key.size(), ctrcopy.data()); |
|||
d.ProcessData(out, in, text.size()); |
|||
BOOST_REQUIRE(text == original); |
|||
} |
|||
catch (CryptoPP::Exception& _e) |
|||
{ |
|||
cerr << _e.what() << endl; |
|||
} |
|||
|
|||
|
|||
// reencrypt ciphertext...
|
|||
try |
|||
{ |
|||
BOOST_REQUIRE(cipherCopy != text); |
|||
in = (unsigned char*)&cipherCopy[0]; |
|||
out = (unsigned char*)&cipherCopy[0]; |
|||
|
|||
CTR_Mode<AES>::Encryption e; |
|||
e.SetKeyWithIV(key, key.size(), ctrcopy.data()); |
|||
e.ProcessData(out, in, text.size()); |
|||
|
|||
// yep, ctr mode.
|
|||
BOOST_REQUIRE(cipherCopy == original); |
|||
} |
|||
catch (CryptoPP::Exception& _e) |
|||
{ |
|||
cerr << _e.what() << endl; |
|||
} |
|||
|
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(cryptopp_aes128_cbc) |
|||
{ |
|||
const int aesKeyLen = 16; |
|||
BOOST_REQUIRE(sizeof(char) == sizeof(byte)); |
|||
|
|||
AutoSeededRandomPool rng; |
|||
SecByteBlock key(0x00, aesKeyLen); |
|||
rng.GenerateBlock(key, key.size()); |
|||
|
|||
// Generate random IV
|
|||
byte iv[AES::BLOCKSIZE]; |
|||
rng.GenerateBlock(iv, AES::BLOCKSIZE); |
|||
|
|||
string string128("AAAAAAAAAAAAAAAA"); |
|||
string plainOriginal = string128; |
|||
|
|||
CryptoPP::CBC_Mode<Rijndael>::Encryption cbcEncryption(key, key.size(), iv); |
|||
cbcEncryption.ProcessData((byte*)&string128[0], (byte*)&string128[0], string128.size()); |
|||
BOOST_REQUIRE(string128 != plainOriginal); |
|||
|
|||
CBC_Mode<Rijndael>::Decryption cbcDecryption(key, key.size(), iv); |
|||
cbcDecryption.ProcessData((byte*)&string128[0], (byte*)&string128[0], string128.size()); |
|||
BOOST_REQUIRE(plainOriginal == string128); |
|||
|
|||
|
|||
// plaintext whose size isn't divisible by block size must use stream filter for padding
|
|||
string string192("AAAAAAAAAAAAAAAABBBBBBBB"); |
|||
plainOriginal = string192; |
|||
|
|||
string cipher; |
|||
StreamTransformationFilter* aesStream = new StreamTransformationFilter(cbcEncryption, new StringSink(cipher)); |
|||
StringSource source(string192, true, aesStream); |
|||
BOOST_REQUIRE(cipher.size() == 32); |
|||
|
|||
cbcDecryption.ProcessData((byte*)&cipher[0], (byte*)&string192[0], cipher.size()); |
|||
BOOST_REQUIRE(string192 == plainOriginal); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(eth_keypairs) |
|||
{ |
|||
cnote << "Testing Crypto..."; |
|||
|
|||
KeyPair p(Secret(fromHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"))); |
|||
BOOST_REQUIRE(p.pub() == Public(fromHex("97466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f"))); |
|||
BOOST_REQUIRE(p.address() == Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075"))); |
|||
{ |
|||
eth::Transaction t(1000, 0, 0, h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b")), bytes(), 0, p.secret()); |
|||
auto rlp = t.rlp(eth::WithoutSignature); |
|||
cnote << RLP(rlp); |
|||
cnote << toHex(rlp); |
|||
cnote << t.sha3(eth::WithoutSignature); |
|||
rlp = t.rlp(eth::WithSignature); |
|||
cnote << RLP(rlp); |
|||
cnote << toHex(rlp); |
|||
cnote << t.sha3(eth::WithSignature); |
|||
BOOST_REQUIRE(t.sender() == p.address()); |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
int cryptoTest() |
|||
{ |
|||
cnote << "Testing Crypto..."; |
|||
|
|||
KeyPair p(Secret(fromHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"))); |
|||
BOOST_REQUIRE(p.pub() == Public(fromHex("97466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f"))); |
|||
BOOST_REQUIRE(p.address() == Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075"))); |
|||
{ |
|||
eth::Transaction t(1000, 0, 0, h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b")), bytes(), 0, p.secret()); |
|||
auto rlp = t.rlp(eth::WithoutSignature); |
|||
cnote << RLP(rlp); |
|||
cnote << toHex(rlp); |
|||
cnote << t.sha3(eth::WithoutSignature); |
|||
rlp = t.rlp(eth::WithSignature); |
|||
cnote << RLP(rlp); |
|||
cnote << toHex(rlp); |
|||
cnote << t.sha3(eth::WithSignature); |
|||
assert(t.sender() == p.address()); |
|||
} |
|||
|
|||
|
|||
#if 0 |
|||
// Test transaction.
|
|||
bytes tx = fromHex("88005401010101010101010101010101010101010101011f0de0b6b3a76400001ce8d4a5100080181c373130a009ba1f10285d4e659568bfcfec85067855c5a3c150100815dad4ef98fd37cf0593828c89db94bd6c64e210a32ef8956eaa81ea9307194996a3b879441f5d"); |
|||
cout << "TX: " << RLP(tx) << endl; |
|||
|
|||
Transaction t2(tx); |
|||
cout << "SENDER: " << hex << t2.sender() << dec << endl; |
|||
|
|||
secp256k1_start(); |
|||
|
|||
Transaction t; |
|||
t.nonce = 0; |
|||
t.value = 1; // 1 wei.
|
|||
t.type = eth::Transaction::MessageCall; |
|||
t.receiveAddress = toAddress(sha3("123")); |
|||
|
|||
bytes sig64 = toBigEndian(t.vrs.r) + toBigEndian(t.vrs.s); |
|||
cout << "SIG: " << sig64.size() << " " << toHex(sig64) << " " << t.vrs.v << endl; |
|||
|
|||
auto msg = t.rlp(false); |
|||
cout << "TX w/o SIG: " << RLP(msg) << endl; |
|||
cout << "RLP(TX w/o SIG): " << toHex(t.rlp(false)) << endl; |
|||
std::string hmsg = sha3(t.rlp(false), false); |
|||
cout << "SHA256(RLP(TX w/o SIG)): 0x" << toHex(hmsg) << endl; |
|||
|
|||
bytes privkey = sha3("123").asBytes(); |
|||
|
|||
{ |
|||
bytes pubkey(65); |
|||
int pubkeylen = 65; |
|||
|
|||
int ret = secp256k1_ecdsa_seckey_verify(privkey.data()); |
|||
cout << "SEC: " << dec << ret << " " << toHex(privkey) << endl; |
|||
|
|||
ret = secp256k1_ecdsa_pubkey_create(pubkey.data(), &pubkeylen, privkey.data(), 1); |
|||
pubkey.resize(pubkeylen); |
|||
int good = secp256k1_ecdsa_pubkey_verify(pubkey.data(), (int)pubkey.size()); |
|||
cout << "PUB: " << dec << ret << " " << pubkeylen << " " << toHex(pubkey) << (good ? " GOOD" : " BAD") << endl; |
|||
} |
|||
|
|||
// Test roundtrip...
|
|||
{ |
|||
bytes sig(64); |
|||
u256 nonce = 0; |
|||
int v = 0; |
|||
cout << toHex(hmsg) << endl; |
|||
cout << toHex(privkey) << endl; |
|||
cout << hex << nonce << dec << endl; |
|||
int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), (int)hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v); |
|||
cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << toHex(sig) << " " << v << endl; |
|||
|
|||
bytes pubkey(65); |
|||
int pubkeylen = 65; |
|||
ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), (int)hmsg.size(), (byte const*)sig.data(), pubkey.data(), &pubkeylen, 0, v); |
|||
pubkey.resize(pubkeylen); |
|||
cout << "MYREC: " << dec << ret << " " << pubkeylen << " " << toHex(pubkey) << endl; |
|||
} |
|||
|
|||
{ |
|||
bytes pubkey(65); |
|||
int pubkeylen = 65; |
|||
int ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), (int)hmsg.size(), (byte const*)sig64.data(), pubkey.data(), &pubkeylen, 0, (int)t.vrs.v - 27); |
|||
pubkey.resize(pubkeylen); |
|||
cout << "RECPUB: " << dec << ret << " " << pubkeylen << " " << toHex(pubkey) << endl; |
|||
cout << "SENDER: " << hex << toAddress(dev::sha3(bytesConstRef(&pubkey).cropped(1))) << dec << endl; |
|||
} |
|||
#endif |
|||
return 0; |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
@ -1,102 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file hexPrefix.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Main test functions. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
|
|||
#include "../JsonSpiritHeaders.h" |
|||
#include <libdevcore/Log.h> |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libdevcore/Base64.h> |
|||
#include <libdevcore/TrieCommon.h> |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
namespace js = json_spirit; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(BasicTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(hexPrefix_test) |
|||
{ |
|||
|
|||
string testPath = test::getTestPath(); |
|||
testPath += "/BasicTests"; |
|||
|
|||
cnote << "Testing Hex-Prefix-Encode..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/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::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) ); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(base64) |
|||
{ |
|||
static char const* const s_tests[][2] = |
|||
{ |
|||
{"", ""}, |
|||
{"f", "Zg=="}, |
|||
{"fo", "Zm8="}, |
|||
{"foo", "Zm9v"}, |
|||
{"foob", "Zm9vYg=="}, |
|||
{"fooba", "Zm9vYmE="}, |
|||
{"foobar", "Zm9vYmFy"}, |
|||
{ |
|||
"So?<p>" |
|||
"This 4, 5, 6, 7, 8, 9, z, {, |, } tests Base64 encoder. " |
|||
"Show me: @, A, B, C, D, E, F, G, H, I, J, K, L, M, " |
|||
"N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \\, ], ^, _, `, " |
|||
"a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s.", |
|||
"U28/PHA+VGhpcyA0LCA1LCA2LCA3LCA4LCA5LCB6LCB7LCB8LCB9IHRlc3RzIEJhc2U2NCBlbmNv" |
|||
"ZGVyLiBTaG93IG1lOiBALCBBLCBCLCBDLCBELCBFLCBGLCBHLCBILCBJLCBKLCBLLCBMLCBNLCBO" |
|||
"LCBPLCBQLCBRLCBSLCBTLCBULCBVLCBWLCBXLCBYLCBZLCBaLCBbLCBcLCBdLCBeLCBfLCBgLCBh" |
|||
"LCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBpLCBqLCBrLCBsLCBtLCBuLCBvLCBwLCBxLCByLCBzLg==" |
|||
} |
|||
}; |
|||
static const auto c_numTests = sizeof(s_tests) / sizeof(s_tests[0]); |
|||
|
|||
for (size_t i = 0; i < c_numTests; ++i) |
|||
{ |
|||
auto expectedDecoded = std::string{s_tests[i][0]}; |
|||
auto expectedEncoded = std::string{s_tests[i][1]}; |
|||
|
|||
auto encoded = toBase64(expectedDecoded); |
|||
BOOST_CHECK_EQUAL(expectedEncoded, encoded); |
|||
auto decodedBytes = fromBase64(expectedEncoded); |
|||
auto decoded = bytesConstRef{decodedBytes.data(), decodedBytes.size()}.toString(); |
|||
BOOST_CHECK_EQUAL(decoded, expectedDecoded); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,627 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file trie.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Trie test functions. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include "../JsonSpiritHeaders.h" |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libdevcore/TrieDB.h> |
|||
#include <libdevcore/TrieHash.h> |
|||
#include "MemTrie.h" |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
|
|||
namespace js = json_spirit; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
static unsigned fac(unsigned _i) |
|||
{ |
|||
return _i > 2 ? _i * fac(_i - 1) : _i; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
using dev::operator <<; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(TrieTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(fat_trie) |
|||
{ |
|||
h256 r; |
|||
MemoryDB fm; |
|||
{ |
|||
FatGenericTrieDB<MemoryDB> ft(&fm); |
|||
ft.init(); |
|||
ft.insert(h256("69", h256::FromHex, h256::AlignRight).ref(), h256("414243", h256::FromHex, h256::AlignRight).ref()); |
|||
for (auto i: ft) |
|||
cnote << i.first << i.second; |
|||
r = ft.root(); |
|||
} |
|||
{ |
|||
FatGenericTrieDB<MemoryDB> ft(&fm); |
|||
ft.setRoot(r); |
|||
for (auto i: ft) |
|||
cnote << i.first << i.second; |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
|
|||
testPath += "/TrieTests"; |
|||
|
|||
cnote << "Testing Secure Trie..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/hex_encoded_securetrie_test.json"); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'hex_encoded_securetrie_test.json' is empty. Have you cloned the 'tests' repo branch develop?"); |
|||
js::read_string(s, v); |
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
cnote << i.first; |
|||
js::mObject& o = i.second.get_obj(); |
|||
vector<pair<string, string>> ss; |
|||
for (auto i: o["in"].get_obj()) |
|||
{ |
|||
ss.push_back(make_pair(i.first, i.second.get_str())); |
|||
if (!ss.back().first.find("0x")) |
|||
ss.back().first = asString(fromHex(ss.back().first.substr(2))); |
|||
if (!ss.back().second.find("0x")) |
|||
ss.back().second = asString(fromHex(ss.back().second.substr(2))); |
|||
} |
|||
for (unsigned j = 0; j < min(1000000000u, dev::test::fac((unsigned)ss.size())); ++j) |
|||
{ |
|||
next_permutation(ss.begin(), ss.end()); |
|||
MemoryDB m; |
|||
EnforceRefs r(m, true); |
|||
GenericTrieDB<MemoryDB> t(&m); |
|||
MemoryDB hm; |
|||
EnforceRefs hr(hm, true); |
|||
HashedGenericTrieDB<MemoryDB> ht(&hm); |
|||
MemoryDB fm; |
|||
EnforceRefs fr(fm, true); |
|||
FatGenericTrieDB<MemoryDB> ft(&fm); |
|||
t.init(); |
|||
ht.init(); |
|||
ft.init(); |
|||
BOOST_REQUIRE(t.check(true)); |
|||
BOOST_REQUIRE(ht.check(true)); |
|||
BOOST_REQUIRE(ft.check(true)); |
|||
for (auto const& k: ss) |
|||
{ |
|||
t.insert(k.first, k.second); |
|||
ht.insert(k.first, k.second); |
|||
ft.insert(k.first, k.second); |
|||
BOOST_REQUIRE(t.check(true)); |
|||
BOOST_REQUIRE(ht.check(true)); |
|||
BOOST_REQUIRE(ft.check(true)); |
|||
auto i = ft.begin(); |
|||
auto j = t.begin(); |
|||
for (; i != ft.end() && j != t.end(); ++i, ++j) |
|||
{ |
|||
BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); |
|||
BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); |
|||
BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); |
|||
} |
|||
BOOST_CHECK_EQUAL(ht.root(), ft.root()); |
|||
} |
|||
BOOST_REQUIRE(!o["root"].is_null()); |
|||
BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ht.root().asArray())); |
|||
BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ft.root().asArray())); |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(trie_test_anyorder) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
|
|||
testPath += "/TrieTests"; |
|||
|
|||
cnote << "Testing Trie..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/trieanyorder.json"); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trieanyorder.json' is empty. Have you cloned the 'tests' repo branch develop?"); |
|||
js::read_string(s, v); |
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
cnote << i.first; |
|||
js::mObject& o = i.second.get_obj(); |
|||
vector<pair<string, string>> ss; |
|||
for (auto i: o["in"].get_obj()) |
|||
{ |
|||
ss.push_back(make_pair(i.first, i.second.get_str())); |
|||
if (!ss.back().first.find("0x")) |
|||
ss.back().first = asString(fromHex(ss.back().first.substr(2))); |
|||
if (!ss.back().second.find("0x")) |
|||
ss.back().second = asString(fromHex(ss.back().second.substr(2))); |
|||
} |
|||
for (unsigned j = 0; j < min(1000u, dev::test::fac((unsigned)ss.size())); ++j) |
|||
{ |
|||
next_permutation(ss.begin(), ss.end()); |
|||
MemoryDB m; |
|||
EnforceRefs r(m, true); |
|||
GenericTrieDB<MemoryDB> t(&m); |
|||
MemoryDB hm; |
|||
EnforceRefs hr(hm, true); |
|||
HashedGenericTrieDB<MemoryDB> ht(&hm); |
|||
MemoryDB fm; |
|||
EnforceRefs fr(fm, true); |
|||
FatGenericTrieDB<MemoryDB> ft(&fm); |
|||
t.init(); |
|||
ht.init(); |
|||
ft.init(); |
|||
BOOST_REQUIRE(t.check(true)); |
|||
BOOST_REQUIRE(ht.check(true)); |
|||
BOOST_REQUIRE(ft.check(true)); |
|||
for (auto const& k: ss) |
|||
{ |
|||
t.insert(k.first, k.second); |
|||
ht.insert(k.first, k.second); |
|||
ft.insert(k.first, k.second); |
|||
BOOST_REQUIRE(t.check(true)); |
|||
BOOST_REQUIRE(ht.check(true)); |
|||
BOOST_REQUIRE(ft.check(true)); |
|||
auto i = ft.begin(); |
|||
auto j = t.begin(); |
|||
for (; i != ft.end() && j != t.end(); ++i, ++j) |
|||
{ |
|||
BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); |
|||
BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); |
|||
BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); |
|||
} |
|||
BOOST_CHECK_EQUAL(ht.root(), ft.root()); |
|||
} |
|||
BOOST_REQUIRE(!o["root"].is_null()); |
|||
BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray())); |
|||
BOOST_CHECK_EQUAL(ht.root(), ft.root()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(trie_tests_ordered) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
|
|||
testPath += "/TrieTests"; |
|||
|
|||
cnote << "Testing Trie..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/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()) |
|||
{ |
|||
cnote << i.first; |
|||
js::mObject& o = i.second.get_obj(); |
|||
vector<pair<string, string>> ss; |
|||
vector<string> keysToBeDeleted; |
|||
for (auto& i: o["in"].get_array()) |
|||
{ |
|||
vector<string> values; |
|||
for (auto& s: i.get_array()) |
|||
{ |
|||
if (s.type() == json_spirit::str_type) |
|||
values.push_back(s.get_str()); |
|||
else if (s.type() == json_spirit::null_type) |
|||
{ |
|||
// mark entry for deletion
|
|||
values.push_back(""); |
|||
if (!values[0].find("0x")) |
|||
values[0] = asString(fromHex(values[0].substr(2))); |
|||
keysToBeDeleted.push_back(values[0]); |
|||
} |
|||
else |
|||
BOOST_FAIL("Bad type (expected string)"); |
|||
} |
|||
|
|||
BOOST_REQUIRE(values.size() == 2); |
|||
ss.push_back(make_pair(values[0], values[1])); |
|||
if (!ss.back().first.find("0x")) |
|||
ss.back().first = asString(fromHex(ss.back().first.substr(2))); |
|||
if (!ss.back().second.find("0x")) |
|||
ss.back().second = asString(fromHex(ss.back().second.substr(2))); |
|||
} |
|||
|
|||
MemoryDB m; |
|||
EnforceRefs r(m, true); |
|||
GenericTrieDB<MemoryDB> t(&m); |
|||
MemoryDB hm; |
|||
EnforceRefs hr(hm, true); |
|||
HashedGenericTrieDB<MemoryDB> ht(&hm); |
|||
MemoryDB fm; |
|||
EnforceRefs fr(fm, true); |
|||
FatGenericTrieDB<MemoryDB> ft(&fm); |
|||
t.init(); |
|||
ht.init(); |
|||
ft.init(); |
|||
BOOST_REQUIRE(t.check(true)); |
|||
BOOST_REQUIRE(ht.check(true)); |
|||
BOOST_REQUIRE(ft.check(true)); |
|||
|
|||
for (auto const& k: ss) |
|||
{ |
|||
if (find(keysToBeDeleted.begin(), keysToBeDeleted.end(), k.first) != keysToBeDeleted.end() && k.second.empty()) |
|||
t.remove(k.first), ht.remove(k.first), ft.remove(k.first); |
|||
else |
|||
t.insert(k.first, k.second), ht.insert(k.first, k.second), ft.insert(k.first, k.second); |
|||
BOOST_REQUIRE(t.check(true)); |
|||
BOOST_REQUIRE(ht.check(true)); |
|||
BOOST_REQUIRE(ft.check(true)); |
|||
auto i = ft.begin(); |
|||
auto j = t.begin(); |
|||
for (; i != ft.end() && j != t.end(); ++i, ++j) |
|||
{ |
|||
BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); |
|||
BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); |
|||
BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); |
|||
} |
|||
BOOST_CHECK_EQUAL(ht.root(), ft.root()); |
|||
} |
|||
|
|||
BOOST_REQUIRE(!o["root"].is_null()); |
|||
BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray())); |
|||
} |
|||
} |
|||
|
|||
h256 stringMapHash256(StringMap const& _s) |
|||
{ |
|||
BytesMap bytesMap; |
|||
for (auto const& _v: _s) |
|||
bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end()))); |
|||
return hash256(bytesMap); |
|||
} |
|||
|
|||
bytes stringMapRlp256(StringMap const& _s) |
|||
{ |
|||
BytesMap bytesMap; |
|||
for (auto const& _v: _s) |
|||
bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end()))); |
|||
return rlp256(bytesMap); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(moreTrieTests) |
|||
{ |
|||
cnote << "Testing Trie more..."; |
|||
// More tests...
|
|||
{ |
|||
MemoryDB m; |
|||
GenericTrieDB<MemoryDB> t(&m); |
|||
t.init(); // initialise as empty tree.
|
|||
cnote << t; |
|||
cnote << m; |
|||
cnote << t.root(); |
|||
cnote << stringMapHash256(StringMap()); |
|||
|
|||
t.insert(string("tesz"), string("test")); |
|||
cnote << t; |
|||
cnote << m; |
|||
cnote << t.root(); |
|||
cnote << stringMapHash256({{"test", "test"}}); |
|||
|
|||
t.insert(string("tesa"), string("testy")); |
|||
cnote << t; |
|||
cnote << m; |
|||
cnote << t.root(); |
|||
cnote << stringMapHash256({{"test", "test"}, {"te", "testy"}}); |
|||
cnote << t.at(string("test")); |
|||
cnote << t.at(string("te")); |
|||
cnote << t.at(string("t")); |
|||
|
|||
t.remove(string("te")); |
|||
cnote << m; |
|||
cnote << t.root(); |
|||
cnote << stringMapHash256({{"test", "test"}}); |
|||
|
|||
t.remove(string("test")); |
|||
cnote << m; |
|||
cnote << t.root(); |
|||
cnote << stringMapHash256(StringMap()); |
|||
} |
|||
{ |
|||
MemoryDB m; |
|||
GenericTrieDB<MemoryDB> t(&m); |
|||
t.init(); // initialise as empty tree.
|
|||
t.insert(string("a"), string("A")); |
|||
t.insert(string("b"), string("B")); |
|||
cnote << t; |
|||
cnote << m; |
|||
cnote << t.root(); |
|||
cnote << stringMapHash256({{"b", "B"}, {"a", "A"}}); |
|||
bytes r(stringMapRlp256({{"b", "B"}, {"a", "A"}})); |
|||
cnote << RLP(r); |
|||
} |
|||
{ |
|||
MemTrie t; |
|||
t.insert("dog", "puppy"); |
|||
cnote << hex << t.hash256(); |
|||
bytes r(t.rlp()); |
|||
cnote << RLP(r); |
|||
} |
|||
{ |
|||
MemTrie t; |
|||
t.insert("bed", "d"); |
|||
t.insert("be", "e"); |
|||
cnote << hex << t.hash256(); |
|||
bytes r(t.rlp()); |
|||
cnote << RLP(r); |
|||
} |
|||
{ |
|||
cnote << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}); |
|||
MemTrie t; |
|||
t.insert("dog", "puppy"); |
|||
t.insert("doe", "reindeer"); |
|||
cnote << hex << t.hash256(); |
|||
bytes r(t.rlp()); |
|||
cnote << RLP(r); |
|||
cnote << toHex(t.rlp()); |
|||
} |
|||
{ |
|||
MemoryDB m; |
|||
EnforceRefs r(m, true); |
|||
GenericTrieDB<MemoryDB> d(&m); |
|||
d.init(); // initialise as empty tree.
|
|||
MemTrie t; |
|||
StringMap s; |
|||
|
|||
auto add = [&](char const* a, char const* b) |
|||
{ |
|||
d.insert(string(a), string(b)); |
|||
t.insert(a, b); |
|||
s[a] = b; |
|||
|
|||
cnote << "/n-------------------------------"; |
|||
cnote << a << " -> " << b; |
|||
cnote << d; |
|||
cnote << m; |
|||
cnote << d.root(); |
|||
cnote << stringMapHash256(s); |
|||
|
|||
BOOST_REQUIRE(d.check(true)); |
|||
BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s)); |
|||
BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s)); |
|||
for (auto const& i: s) |
|||
{ |
|||
(void)i; |
|||
BOOST_REQUIRE_EQUAL(t.at(i.first), i.second); |
|||
BOOST_REQUIRE_EQUAL(d.at(i.first), i.second); |
|||
} |
|||
}; |
|||
|
|||
auto remove = [&](char const* a) |
|||
{ |
|||
s.erase(a); |
|||
t.remove(a); |
|||
d.remove(string(a)); |
|||
|
|||
/*cnote << endl << "-------------------------------";
|
|||
cnote << "X " << a; |
|||
cnote << d; |
|||
cnote << m; |
|||
cnote << d.root(); |
|||
cnote << hash256(s);*/ |
|||
|
|||
BOOST_REQUIRE(d.check(true)); |
|||
BOOST_REQUIRE(t.at(a).empty()); |
|||
BOOST_REQUIRE(d.at(string(a)).empty()); |
|||
BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s)); |
|||
BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s)); |
|||
for (auto const& i: s) |
|||
{ |
|||
(void)i; |
|||
BOOST_REQUIRE_EQUAL(t.at(i.first), i.second); |
|||
BOOST_REQUIRE_EQUAL(d.at(i.first), i.second); |
|||
} |
|||
}; |
|||
|
|||
add("dogglesworth", "cat"); |
|||
add("doe", "reindeer"); |
|||
remove("dogglesworth"); |
|||
add("horse", "stallion"); |
|||
add("do", "verb"); |
|||
add("doge", "coin"); |
|||
remove("horse"); |
|||
remove("do"); |
|||
remove("doge"); |
|||
remove("doe"); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(trieLowerBound) |
|||
{ |
|||
cnote << "Stress-testing Trie.lower_bound..."; |
|||
if (0) |
|||
{ |
|||
MemoryDB dm; |
|||
EnforceRefs e(dm, true); |
|||
GenericTrieDB<MemoryDB> d(&dm); |
|||
d.init(); // initialise as empty tree.
|
|||
for (int a = 0; a < 20; ++a) |
|||
{ |
|||
StringMap m; |
|||
for (int i = 0; i < 50; ++i) |
|||
{ |
|||
auto k = randomWord(); |
|||
auto v = toString(i); |
|||
m[k] = v; |
|||
d.insert(k, v); |
|||
} |
|||
|
|||
for (auto i: d) |
|||
{ |
|||
auto it = d.lower_bound(i.first); |
|||
for (auto iit = d.begin(); iit != d.end(); ++iit) |
|||
if ((*iit).first.toString() >= i.first.toString()) |
|||
{ |
|||
BOOST_REQUIRE(it == iit); |
|||
break; |
|||
} |
|||
} |
|||
for (unsigned i = 0; i < 100; ++i) |
|||
{ |
|||
auto k = randomWord(); |
|||
auto it = d.lower_bound(k); |
|||
for (auto iit = d.begin(); iit != d.end(); ++iit) |
|||
if ((*iit).first.toString() >= k) |
|||
{ |
|||
BOOST_REQUIRE(it == iit); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(trieStess) |
|||
{ |
|||
cnote << "Stress-testing Trie..."; |
|||
{ |
|||
MemoryDB m; |
|||
MemoryDB dm; |
|||
EnforceRefs e(dm, true); |
|||
GenericTrieDB<MemoryDB> d(&dm); |
|||
d.init(); // initialise as empty tree.
|
|||
MemTrie t; |
|||
BOOST_REQUIRE(d.check(true)); |
|||
for (int a = 0; a < 20; ++a) |
|||
{ |
|||
StringMap m; |
|||
for (int i = 0; i < 50; ++i) |
|||
{ |
|||
auto k = randomWord(); |
|||
auto v = toString(i); |
|||
m[k] = v; |
|||
t.insert(k, v); |
|||
d.insert(k, v); |
|||
BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256()); |
|||
BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root()); |
|||
BOOST_REQUIRE(d.check(true)); |
|||
} |
|||
while (!m.empty()) |
|||
{ |
|||
auto k = m.begin()->first; |
|||
auto v = m.begin()->second; |
|||
d.remove(k); |
|||
t.remove(k); |
|||
m.erase(k); |
|||
if (!d.check(true)) |
|||
{ |
|||
// cwarn << m;
|
|||
for (auto i: d) |
|||
cwarn << i.first.toString() << i.second.toString(); |
|||
|
|||
MemoryDB dm2; |
|||
EnforceRefs e2(dm2, true); |
|||
GenericTrieDB<MemoryDB> d2(&dm2); |
|||
d2.init(); // initialise as empty tree.
|
|||
for (auto i: d) |
|||
d2.insert(i.first, i.second); |
|||
|
|||
cwarn << "Good:" << d2.root(); |
|||
// for (auto i: dm2.get())
|
|||
// cwarn << i.first << ": " << RLP(i.second);
|
|||
d2.debugStructure(cerr); |
|||
cwarn << "Broken:" << d.root(); // Leaves an extension -> extension (3c1... -> 742...)
|
|||
// for (auto i: dm.get())
|
|||
// cwarn << i.first << ": " << RLP(i.second);
|
|||
d.debugStructure(cerr); |
|||
|
|||
d2.insert(k, v); |
|||
cwarn << "Pres:" << d2.root(); |
|||
// for (auto i: dm2.get())
|
|||
// cwarn << i.first << ": " << RLP(i.second);
|
|||
d2.debugStructure(cerr); |
|||
if (g_logVerbosity != -1) |
|||
g_logVerbosity = 99; |
|||
d2.remove(k); |
|||
if (g_logVerbosity != -1) |
|||
g_logVerbosity = 4; |
|||
|
|||
cwarn << "Good?" << d2.root(); |
|||
} |
|||
BOOST_REQUIRE(d.check(true)); |
|||
BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256()); |
|||
BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
template<typename Trie> void perfTestTrie(char const* _name) |
|||
{ |
|||
for (size_t p = 1000; p != 1000000; p*=10) |
|||
{ |
|||
MemoryDB dm; |
|||
Trie d(&dm); |
|||
d.init(); |
|||
cnote << "TriePerf " << _name << p; |
|||
std::vector<h256> keys(1000); |
|||
Timer t; |
|||
size_t ki = 0; |
|||
for (size_t i = 0; i < p; ++i) |
|||
{ |
|||
auto k = h256::random(); |
|||
auto v = toString(i); |
|||
d.insert(k, v); |
|||
|
|||
if (i % (p / 1000) == 0) |
|||
keys[ki++] = k; |
|||
} |
|||
cnote << "Insert " << p << "values: " << t.elapsed(); |
|||
t.restart(); |
|||
for (auto k: keys) |
|||
d.at(k); |
|||
cnote << "Query 1000 values: " << t.elapsed(); |
|||
t.restart(); |
|||
size_t i = 0; |
|||
for (auto it = d.begin(); i < 1000 && it != d.end(); ++it, ++i) |
|||
*it; |
|||
cnote << "Iterate 1000 values: " << t.elapsed(); |
|||
t.restart(); |
|||
for (auto k: keys) |
|||
d.remove(k); |
|||
cnote << "Remove 1000 values:" << t.elapsed() << "\n"; |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(triePerf) |
|||
{ |
|||
if (test::Options::get().performance) |
|||
{ |
|||
perfTestTrie<SpecificTrieDB<GenericTrieDB<MemoryDB>, h256>>("GenericTrieDB"); |
|||
perfTestTrie<SpecificTrieDB<HashedGenericTrieDB<MemoryDB>, h256>>("HashedGenericTrieDB"); |
|||
perfTestTrie<SpecificTrieDB<FatGenericTrieDB<MemoryDB>, h256>>("FatGenericTrieDB"); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
|||
|
@ -1,5 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRCS) |
|||
|
|||
add_sources(${SRCS}) |
@ -1,58 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file commonjs.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/Log.h> |
|||
#include <libethcore/CommonJS.h> |
|||
|
|||
BOOST_AUTO_TEST_SUITE(commonjs) |
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
BOOST_AUTO_TEST_CASE(jsToPublic) |
|||
{ |
|||
cnote << "Testing jsToPublic..."; |
|||
KeyPair kp = KeyPair::create(); |
|||
string s = toJS(kp.pub()); |
|||
Public pub = dev::jsToPublic(s); |
|||
BOOST_CHECK_EQUAL(kp.pub(), pub); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(jsToAddress) |
|||
{ |
|||
cnote << "Testing jsToPublic..."; |
|||
KeyPair kp = KeyPair::create(); |
|||
string s = toJS(kp.address()); |
|||
Address address = dev::jsToAddress(s); |
|||
BOOST_CHECK_EQUAL(kp.address(), address); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(jsToSecret) |
|||
{ |
|||
cnote << "Testing jsToPublic..."; |
|||
KeyPair kp = KeyPair::create(); |
|||
string s = toJS(kp.secret().makeInsecure()); |
|||
Secret secret = dev::jsToSecret(s); |
|||
BOOST_CHECK_EQUAL(kp.secret().makeInsecure(), secret.makeInsecure()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,83 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file dagger.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Dashimoto test functions. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
#include "../JsonSpiritHeaders.h" |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libethcore/EthashAux.h> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace js = json_spirit; |
|||
|
|||
using dev::operator <<; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(DashimotoTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(basic_test) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
|
|||
testPath += "/PoWTests"; |
|||
|
|||
cnote << "Testing Proof of Work..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/ethash_tests.json"); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'ethash_tests.json' is empty. Have you cloned the 'tests' repo branch develop?"); |
|||
js::read_string(s, v); |
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
cnote << i.first; |
|||
js::mObject& o = i.second.get_obj(); |
|||
vector<pair<string, string>> ss; |
|||
Ethash::BlockHeader header(fromHex(o["header"].get_str()), CheckNothing, h256{}, HeaderData); |
|||
h256 headerHash(o["header_hash"].get_str()); |
|||
Nonce nonce(o["nonce"].get_str()); |
|||
BOOST_REQUIRE_EQUAL(headerHash, header.hashWithout()); |
|||
BOOST_REQUIRE_EQUAL(nonce, header.nonce()); |
|||
|
|||
unsigned cacheSize(o["cache_size"].get_int()); |
|||
h256 cacheHash(o["cache_hash"].get_str()); |
|||
BOOST_REQUIRE_EQUAL(EthashAux::get()->light(header.seedHash())->size, cacheSize); |
|||
BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->light(header.seedHash())->data()), cacheHash); |
|||
|
|||
#if TEST_FULL |
|||
unsigned fullSize(o["full_size"].get_int()); |
|||
h256 fullHash(o["full_hash"].get_str()); |
|||
BOOST_REQUIRE_EQUAL(EthashAux::get()->full(header.seedHash())->size(), fullSize); |
|||
BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->full(header.seedHash())->data()), fullHash); |
|||
#endif |
|||
|
|||
h256 result(o["result"].get_str()); |
|||
EthashProofOfWork::Result r = EthashAux::eval(header.seedHash(), header.hashWithout(), header.nonce()); |
|||
BOOST_REQUIRE_EQUAL(r.value, result); |
|||
BOOST_REQUIRE_EQUAL(r.mixHash, header.mixHash()); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
|||
|
@ -1,63 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file difficulty.cpp
|
|||
* @author Christoph Jentzsch <cj@ethdev.com> |
|||
* @date 2015 |
|||
* difficulty calculation tests. |
|||
*/ |
|||
|
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <test/TestHelper.h> |
|||
#include <libethcore/BlockInfo.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace js = json_spirit; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(DifficultyTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(difficultyTests) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
testPath += "/BasicTests"; |
|||
|
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/difficulty.json"); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'difficulty.json' is empty. Have you cloned the 'tests' repo branch develop?"); |
|||
js::read_string(s, v); |
|||
|
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
js::mObject o = i.second.get_obj(); |
|||
cnote << "Difficulty test: " << i.first; |
|||
BlockInfo parent; |
|||
parent.setTimestamp(test::toInt(o["parentTimestamp"])); |
|||
parent.setDifficulty(test::toInt(o["parentDifficulty"])); |
|||
parent.setNumber(test::toInt(o["currentBlockNumber"]) - 1); |
|||
|
|||
BlockInfo current; |
|||
current.setTimestamp(test::toInt(o["currentTimestamp"])); |
|||
current.setNumber(test::toInt(o["currentBlockNumber"])); |
|||
|
|||
BOOST_CHECK_EQUAL(current.calculateDifficulty(parent), test::toInt(o["currentDifficulty"])); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,80 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file icap.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libethcore/ICAP.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(IcapTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressEncoding) |
|||
{ |
|||
Address address("0x52dc504a422f0e2a9e7632a34a50f1a82f8224c7"); |
|||
ICAP icap(address); |
|||
BOOST_CHECK_EQUAL(icap.encoded(), "XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2O7"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressEncodingRandomString) |
|||
{ |
|||
Address address("0x11c5496aee77c1ba1f0854206a26dda82a81d6d8"); |
|||
ICAP icap(address); |
|||
BOOST_CHECK_EQUAL(icap.encoded(), "XE1222Q908LN1QBBU6XUQSO1OHWJIOS46OO"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressEncodingWithZeroPrefix) |
|||
{ |
|||
Address address("0x00c5496aee77c1ba1f0854206a26dda82a81d6d8"); |
|||
ICAP icap(address); |
|||
BOOST_CHECK_EQUAL(icap.encoded(), "XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressDecoding) |
|||
{ |
|||
Address address("0x52dc504a422f0e2a9e7632a34a50f1a82f8224c7"); |
|||
ICAP icap = ICAP::decoded("XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2O7"); |
|||
BOOST_CHECK_EQUAL(icap.direct(), address); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressDecodingRandomString) |
|||
{ |
|||
Address address("0x11c5496aee77c1ba1f0854206a26dda82a81d6d8"); |
|||
ICAP icap = ICAP::decoded("XE1222Q908LN1QBBU6XUQSO1OHWJIOS46OO"); |
|||
BOOST_CHECK_EQUAL(icap.direct(), address); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressDecodingWithZeroPrefix) |
|||
{ |
|||
Address address("0x00c5496aee77c1ba1f0854206a26dda82a81d6d8"); |
|||
ICAP icap = ICAP::decoded("XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS"); |
|||
BOOST_CHECK_EQUAL(icap.direct(), address); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(addressDecodingAndEncoding) |
|||
{ |
|||
std::string encoded = "XE499OG1EH8ZZI0KXC6N83EKGT1BM97P2O7"; |
|||
ICAP icap = ICAP::decoded(encoded); |
|||
BOOST_CHECK_EQUAL(icap.encoded(), encoded); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,150 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file keymanager.cpp
|
|||
* @author Christoph Jentzsch <cj@ethdev.com> |
|||
* @date 2015 |
|||
* Keymanager test functions. |
|||
*/ |
|||
|
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <test/TestHelper.h> |
|||
#include <libdevcore/TransientDirectory.h> |
|||
#include <libethcore/KeyManager.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(KeyManagerTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyInfoDefaultConstructor) |
|||
{ |
|||
cnote << "KeyInfoDefaultConstructor"; |
|||
KeyInfo kiDefault; |
|||
BOOST_CHECK_EQUAL(kiDefault.accountName, ""); |
|||
BOOST_CHECK(kiDefault.passHash == h256()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyInfoConstructor) |
|||
{ |
|||
cnote << "KeyInfoConstructor"; |
|||
h256 passHash("0x2a"); |
|||
string accountName = "myAccount"; |
|||
KeyInfo ki(passHash, accountName); |
|||
BOOST_CHECK_EQUAL(ki.accountName, "myAccount"); |
|||
BOOST_CHECK(ki.passHash == h256("0x2a")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyManagerConstructor) |
|||
{ |
|||
cnote << "KeyManagerConstructor"; |
|||
KeyManager km; |
|||
BOOST_CHECK_EQUAL(km.keysFile(), km.defaultPath()); |
|||
BOOST_CHECK_EQUAL(km.defaultPath(), getDataDir("ethereum") + "/keys.info"); |
|||
BOOST_CHECK(km.store().keys() == SecretStore().keys()); |
|||
for (auto a: km.accounts()) |
|||
km.kill(a); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyManagerKeysFile) |
|||
{ |
|||
cnote << "KeyManagerKeysFile"; |
|||
KeyManager km; |
|||
string password = "hardPassword"; |
|||
BOOST_CHECK(!km.load(password)); |
|||
|
|||
// set to valid path
|
|||
TransientDirectory tmpDir; |
|||
km.setKeysFile(tmpDir.path()); |
|||
BOOST_CHECK(!km.exists()); |
|||
BOOST_CHECK_THROW(km.create(password), boost::filesystem::filesystem_error); |
|||
km.setKeysFile(tmpDir.path() + "/notExistingDir/keysFile.json"); |
|||
BOOST_CHECK_NO_THROW(km.create(password)); |
|||
BOOST_CHECK(km.exists()); |
|||
km.setKeysFile(tmpDir.path() + "keysFile.json"); |
|||
BOOST_CHECK_NO_THROW(km.create(password)); |
|||
km.save(password); |
|||
BOOST_CHECK(km.load(password)); |
|||
|
|||
for (auto a: km.accounts()) |
|||
km.kill(a); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyManagerHints) |
|||
{ |
|||
cnote << "KeyManagerHints"; |
|||
KeyManager km; |
|||
string password = "hardPassword"; |
|||
|
|||
// set to valid path
|
|||
TransientDirectory tmpDir; |
|||
km.setKeysFile(tmpDir.path() + "keysFile.json"); |
|||
km.create(password); |
|||
km.save(password); |
|||
|
|||
BOOST_CHECK(!km.haveHint(password + "2")); |
|||
km.notePassword(password); |
|||
BOOST_CHECK(km.haveHint(password)); |
|||
|
|||
for (auto a: km.accounts()) |
|||
km.kill(a); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyManagerAccounts) |
|||
{ |
|||
string password = "hardPassword"; |
|||
|
|||
TransientDirectory tmpDir; |
|||
KeyManager km(tmpDir.path()+ "keysFile.json", tmpDir.path()); |
|||
|
|||
BOOST_CHECK_NO_THROW(km.create(password)); |
|||
BOOST_CHECK(km.accounts().empty()); |
|||
BOOST_CHECK(km.load(password)); |
|||
|
|||
for (auto a: km.accounts()) |
|||
km.kill(a); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(KeyManagerKill) |
|||
{ |
|||
string password = "hardPassword"; |
|||
TransientDirectory tmpDir; |
|||
KeyPair kp = KeyPair::create(); |
|||
|
|||
{ |
|||
KeyManager km(tmpDir.path() + "keysFile.json", tmpDir.path()); |
|||
BOOST_CHECK_NO_THROW(km.create(password)); |
|||
BOOST_CHECK(km.accounts().empty()); |
|||
BOOST_CHECK(km.load(password)); |
|||
BOOST_CHECK(km.import(kp.secret(), "test")); |
|||
} |
|||
{ |
|||
KeyManager km(tmpDir.path() + "keysFile.json", tmpDir.path()); |
|||
BOOST_CHECK(km.load(password)); |
|||
Addresses addresses = km.accounts(); |
|||
BOOST_CHECK(addresses.size() == 1 && addresses[0] == kp.address()); |
|||
km.kill(addresses[0]); |
|||
} |
|||
{ |
|||
KeyManager km(tmpDir.path() + "keysFile.json", tmpDir.path()); |
|||
BOOST_CHECK(km.load(password)); |
|||
BOOST_CHECK(km.accounts().empty()); |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,144 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file AccountDiff.cpp
|
|||
* @author Dimitry Khokhlov <Dimitry@ethdev.com> |
|||
* @date 2015 |
|||
* libethereum unit test functions coverage. |
|||
*/ |
|||
|
|||
#include <boost/filesystem/operations.hpp> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <test/TestHelper.h> |
|||
#include "../JsonSpiritHeaders.h" |
|||
|
|||
#include <libdevcore/TransientDirectory.h> |
|||
|
|||
#include <libethereum/Defaults.h> |
|||
#include <libethereum/AccountDiff.h> |
|||
#include <libethereum/BlockChain.h> |
|||
#include <libethereum/BlockQueue.h> |
|||
|
|||
using namespace dev; |
|||
using namespace eth; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(libethereum) |
|||
|
|||
BOOST_AUTO_TEST_CASE(AccountDiff) |
|||
{ |
|||
dev::eth::AccountDiff accDiff; |
|||
|
|||
// Testing changeType
|
|||
// exist = true exist_from = true AccountChange::Deletion
|
|||
accDiff.exist = dev::Diff<bool>(true, false); |
|||
BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::Deletion, "Account change type expected to be Deletion!"); |
|||
BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "XXX") == 0, "Deletion lead expected to be 'XXX'!"); |
|||
|
|||
// exist = true exist_from = false AccountChange::Creation
|
|||
accDiff.exist = dev::Diff<bool>(false, true); |
|||
BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::Creation, "Account change type expected to be Creation!"); |
|||
BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "+++") == 0, "Creation lead expected to be '+++'!"); |
|||
|
|||
// exist = false bn = true sc = true AccountChange::All
|
|||
accDiff.exist = dev::Diff<bool>(false, false); |
|||
accDiff.nonce = dev::Diff<dev::u256>(1, 2); |
|||
accDiff.code = dev::Diff<dev::bytes>(dev::fromHex("00"), dev::fromHex("01")); |
|||
BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::All, "Account change type expected to be All!"); |
|||
BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "***") == 0, "All lead expected to be '***'!"); |
|||
|
|||
// exist = false bn = true sc = false AccountChange::Intrinsic
|
|||
accDiff.exist = dev::Diff<bool>(false, false); |
|||
accDiff.nonce = dev::Diff<dev::u256>(1, 2); |
|||
accDiff.code = dev::Diff<dev::bytes>(dev::fromHex("00"), dev::fromHex("00")); |
|||
BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::Intrinsic, "Account change type expected to be Intrinsic!"); |
|||
BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), " * ") == 0, "Intrinsic lead expected to be ' * '!"); |
|||
|
|||
// exist = false bn = false sc = true AccountChange::CodeStorage
|
|||
accDiff.exist = dev::Diff<bool>(false, false); |
|||
accDiff.nonce = dev::Diff<dev::u256>(1, 1); |
|||
accDiff.balance = dev::Diff<dev::u256>(1, 1); |
|||
accDiff.code = dev::Diff<dev::bytes>(dev::fromHex("00"), dev::fromHex("01")); |
|||
BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::CodeStorage, "Account change type expected to be CodeStorage!"); |
|||
BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), "* *") == 0, "CodeStorage lead expected to be '* *'!"); |
|||
|
|||
// exist = false bn = false sc = false AccountChange::None
|
|||
accDiff.exist = dev::Diff<bool>(false, false); |
|||
accDiff.nonce = dev::Diff<dev::u256>(1, 1); |
|||
accDiff.balance = dev::Diff<dev::u256>(1, 1); |
|||
accDiff.code = dev::Diff<dev::bytes>(dev::fromHex("00"), dev::fromHex("00")); |
|||
BOOST_CHECK_MESSAGE(accDiff.changeType() == dev::eth::AccountChange::None, "Account change type expected to be None!"); |
|||
BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead(accDiff.changeType()), " ") == 0, "None lead expected to be ' '!"); |
|||
|
|||
//ofstream
|
|||
accDiff.exist = dev::Diff<bool>(false, false); |
|||
accDiff.nonce = dev::Diff<dev::u256>(1, 2); |
|||
accDiff.balance = dev::Diff<dev::u256>(1, 2); |
|||
accDiff.code = dev::Diff<dev::bytes>(dev::fromHex("00"), dev::fromHex("01")); |
|||
std::map<dev::u256, dev::Diff<dev::u256>> storage; |
|||
storage[1] = accDiff.nonce; |
|||
accDiff.storage = storage; |
|||
std::stringstream buffer; |
|||
|
|||
//if (!_s.exist.to())
|
|||
buffer << accDiff; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "", "Not expected output: '" + buffer.str() + "'"); |
|||
buffer.str(std::string()); |
|||
|
|||
accDiff.exist = dev::Diff<bool>(false, true); |
|||
buffer << accDiff; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "#2 (+1) 2 (+1) $[1] ([0]) \n * 0000000000000000000000000000000000000000000000000000000000000001: 2 (1)", "Not expected output: '" + buffer.str() + "'"); |
|||
buffer.str(std::string()); |
|||
|
|||
storage[1] = dev::Diff<dev::u256>(0, 0); |
|||
accDiff.storage = storage; |
|||
buffer << accDiff; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "#2 (+1) 2 (+1) $[1] ([0]) \n + 0000000000000000000000000000000000000000000000000000000000000001: 0", "Not expected output: '" + buffer.str() + "'"); |
|||
buffer.str(std::string()); |
|||
|
|||
storage[1] = dev::Diff<dev::u256>(1, 0); |
|||
accDiff.storage = storage; |
|||
buffer << accDiff; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "#2 (+1) 2 (+1) $[1] ([0]) \nXXX 0000000000000000000000000000000000000000000000000000000000000001 (1)", "Not expected output: '" + buffer.str() + "'"); |
|||
buffer.str(std::string()); |
|||
|
|||
BOOST_CHECK_MESSAGE(accDiff.changed() == true, "dev::eth::AccountDiff::changed(): incorrect return value"); |
|||
|
|||
//unexpected value
|
|||
//BOOST_CHECK_MESSAGE(strcmp(dev::eth::lead((dev::eth::AccountChange)123), "") != 0, "Not expected output when dev::eth::lead on unexpected value");
|
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(StateDiff) |
|||
{ |
|||
dev::eth::StateDiff stateDiff; |
|||
dev::eth::AccountDiff accDiff; |
|||
|
|||
accDiff.exist = dev::Diff<bool>(false, false); |
|||
accDiff.nonce = dev::Diff<dev::u256>(1, 2); |
|||
accDiff.balance = dev::Diff<dev::u256>(1, 2); |
|||
accDiff.code = dev::Diff<dev::bytes>(dev::fromHex("00"), dev::fromHex("01")); |
|||
std::map<dev::u256, dev::Diff<dev::u256>> storage; |
|||
storage[1] = accDiff.nonce; |
|||
accDiff.storage = storage; |
|||
std::stringstream buffer; |
|||
|
|||
dev::Address address("001122334455667788991011121314151617181920"); |
|||
stateDiff.accounts[address] = accDiff; |
|||
buffer << stateDiff; |
|||
|
|||
BOOST_CHECK_MESSAGE(buffer.str() == "1 accounts changed:\n*** 0000000000000000000000000000000000000000: \n", "Not expected output: '" + buffer.str() + "'"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,277 +0,0 @@ |
|||
{ |
|||
"SuicideTransaction" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x42", |
|||
"gasLimit" : "125000", |
|||
"gasUsed" : "0", |
|||
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"nonce" : "0x0102030405060708", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", |
|||
"timestamp" : "0x54c98c81", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "90000000000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
}, |
|||
"aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000", |
|||
"nonce" : "0", |
|||
"code" : "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "100000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
|
|||
"GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideLast" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x42", |
|||
"gasLimit" : "147000", |
|||
"gasUsed" : "0", |
|||
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"nonce" : "0x0102030405060708", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", |
|||
"timestamp" : "0x54c98c81", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "90000000000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
}, |
|||
"aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000", |
|||
"nonce" : "0", |
|||
"code" : "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "1", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "2", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "3", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "4", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "5", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "22000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "6", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
|
|||
"GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideFirst" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x42", |
|||
"gasLimit" : "147000", |
|||
"gasUsed" : "0", |
|||
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"nonce" : "0x0102030405060708", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", |
|||
"timestamp" : "0x54c98c81", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "90000000000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
}, |
|||
"aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000", |
|||
"nonce" : "0", |
|||
"code" : "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "6", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "1", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "2", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "3", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "4", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "5", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
}, |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "22000", |
|||
"gasPrice" : "10", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
} |
|||
} |
@ -1,386 +0,0 @@ |
|||
{ |
|||
"highGasUsage" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x42", |
|||
"gasLimit" : "31415920", |
|||
"gasUsed" : "0", |
|||
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"nonce" : "0x0102030405060708", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", |
|||
"timestamp" : "0x54c98c81", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "9000000000000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
}, |
|||
"aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000", |
|||
"nonce" : "0", |
|||
"code" : "0x60003551", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "10000000000000", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "12000000000000", |
|||
"nonce" : "1", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "14000000000000", |
|||
"nonce" : "2", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "16000000000000", |
|||
"nonce" : "3", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "18000000000000", |
|||
"nonce" : "4", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "20000000000000", |
|||
"nonce" : "5", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "22000000000000", |
|||
"nonce" : "6", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "24000000000000", |
|||
"nonce" : "7", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "26000000000000", |
|||
"nonce" : "8", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "28000000000000", |
|||
"nonce" : "9", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "0xffffffffffff", |
|||
"gasLimit" : "850000", |
|||
"gasPrice" : "30000000000000", |
|||
"nonce" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
|
|||
"notxs" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x42", |
|||
"gasLimit" : "3141592", |
|||
"gasUsed" : "0", |
|||
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"nonce" : "0x0102030405060708", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", |
|||
"timestamp" : "0x54c98c81", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"transactions" : [ |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -1,647 +0,0 @@ |
|||
{ |
|||
"RPC_API_Test" : { |
|||
"genesisBlockHeader" : { |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x42", |
|||
"gasLimit" : "3141592", |
|||
"gasUsed" : "0", |
|||
"number" : "0", |
|||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", |
|||
"receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", |
|||
"timestamp" : "0x54c98c81", |
|||
"mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"nonce" : "0x0102030405060708", |
|||
"transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
"pre" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"blocks" : [ |
|||
{ |
|||
"blocknumber" : "1", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "create contract: 6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"data" : "0x5b5b610705806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104d6565b60006000f35b61014261039b565b8060005260206000f35b610157600435610326565b60006000f35b6101686004356102c9565b60006000f35b610176610442565b8060005260206000f35b6101886103d3565b8060ff1660005260206000f35b61019d610413565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104c5565b60006000f35b6101d36103b7565b8060000b60005260206000f35b6101e8610454565b60006000f35b6101f6610401565b8060005260206000f35b61020861051f565b60006000f35b6102196004356102e5565b60006000f35b610227610693565b60006000f35b610238600435610342565b60006000f35b610246610484565b60006000f35b610254610493565b60006000f35b61026560043561038d565b60006000f35b610276600435610350565b60006000f35b61028760043561035e565b60006000f35b6102956105b4565b60006000f35b6102a3610547565b60006000f35b6102b16103ef565b8060005260206000f35b6102c3610600565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff02191690837f01000000000000000000000000000000000000000000000000000000000000009081020402179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff1690506103b4565b90565b6000600060019054906101000a900460000b90506103d0565b90565b6000600060029054906101000a900460ff1690506103ec565b90565b600060016000505490506103fe565b90565b60006002600050549050610410565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061043f565b90565b60006004600050549050610451565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56", |
|||
"gasLimit" : "3141592", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "2", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getBool", |
|||
"data" : "0x12a7b914", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "1", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "3", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getInt8", |
|||
"data" : "0x57cb2fc4", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "2", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "4", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getUint8", |
|||
"data" : "0x343a875d", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
{ |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x", |
|||
"gasLimit" : "3141592", |
|||
"gasUsed" : "0", |
|||
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", |
|||
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", |
|||
"nonce" : "18a524c1790fa83b", |
|||
"number" : "2", |
|||
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", |
|||
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", |
|||
"timestamp" : "0x54c98c82", |
|||
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
}, |
|||
{ |
|||
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|||
"coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"difficulty" : "131072", |
|||
"extraData" : "0x", |
|||
"gasLimit" : "3141592", |
|||
"gasUsed" : "0", |
|||
"hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", |
|||
"mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", |
|||
"nonce" : "18a524c1790fa83b", |
|||
"number" : "2", |
|||
"parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", |
|||
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", |
|||
"timestamp" : "0x54c98c82", |
|||
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", |
|||
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "5", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getInt256", |
|||
"data" : "0xf5b53e17", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "4", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "6", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getUint256", |
|||
"data" : "0x68895979", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "5", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "7", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getAddress", |
|||
"data" : "0x38cc4831", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "6", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "8", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getBytes32", |
|||
"data" : "0x1f903037", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "7", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "9", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setBool", |
|||
"data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "8", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "10", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setBool", |
|||
"data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "9", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "11", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setInt8", |
|||
"data" : "0x9a19a953fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "12", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setUint8", |
|||
"data" : "0x1774e6460000000000000000000000000000000000000000000000000000000000000008", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "11", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "13", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setInt256", |
|||
"data" : "0xa53b1c1effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "12", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "14", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setUint256", |
|||
"data" : "0xd2282dc5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "13", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "15", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setAddress", |
|||
"data" : "0xe30081a0aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "14", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "16", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "setBytes32", |
|||
"data" : "0xc2b12a73aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "15", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "17", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getInt8", |
|||
"data" : "0x57cb2fc4", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "16", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "18", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getUint8", |
|||
"data" : "0x343a875d", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "17", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "19", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getInt256", |
|||
"data" : "0xf5b53e17", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "18", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "20", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getUint256", |
|||
"data" : "0x68895979", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "19", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "21", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getAddress", |
|||
"data" : "0x38cc4831", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "20", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "22", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "getBytes32", |
|||
"data" : "0x1f903037", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "21", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "23", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log0", |
|||
"data" : "0x65538c73", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "22", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "24", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log0a", |
|||
"data" : "0xa6780857", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "23", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "25", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log1", |
|||
"data" : "0xb61c0503", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "24", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "26", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log1a", |
|||
"data" : "0x4e7ad367", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "25", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "27", |
|||
"reverted": true, |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log1", |
|||
"data" : "0x4e7ad367", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "26", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "28", |
|||
"reverted": true, |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log1a", |
|||
"data" : "0x4e7ad367", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "27", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "27", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log2", |
|||
"data" : "0x102accc1", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "26", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "28", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log2a", |
|||
"data" : "0x76bc21d9", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "27", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "29", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log3", |
|||
"data" : "0xf38b0600", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "28", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "30", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log3a", |
|||
"data" : "0xe8beef5b", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "29", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "31", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log4", |
|||
"data" : "0xfd408767", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "30", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
}, |
|||
{ |
|||
"blocknumber" : "32", |
|||
"transactions" : [ |
|||
{ |
|||
"data" : "log4a", |
|||
"data" : "0x9dc2c8f5", |
|||
"gasLimit" : "314159", |
|||
"gasPrice" : "1", |
|||
"nonce" : "31", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", |
|||
"value" : "10" |
|||
} |
|||
], |
|||
"uncleHeaders" : [ |
|||
] |
|||
} |
|||
] |
|||
} |
|||
} |
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
@ -1,5 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
|
|||
aux_source_directory(. SRCS) |
|||
|
|||
add_sources(${SRCS}) |
@ -1,222 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file ClientBase.cpp
|
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include <libdevcore/CommonJS.h> |
|||
#include <libtestutils/FixedClient.h> |
|||
#include "../TestUtils.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
using namespace dev::test; |
|||
|
|||
BOOST_FIXTURE_TEST_SUITE(ClientBase, ParallelClientBaseFixture) |
|||
|
|||
BOOST_AUTO_TEST_CASE(blocks) |
|||
{ |
|||
enumerateClients([](Json::Value const& _json, dev::eth::ClientBase& _client) -> void |
|||
{ |
|||
auto compareState = [&_client](Json::Value const& _o, string const& _name, BlockNumber _blockNumber) -> void |
|||
{ |
|||
Address address(_name); |
|||
|
|||
// balanceAt
|
|||
u256 expectedBalance = u256(_o["balance"].asString()); |
|||
u256 balance = _client.balanceAt(address, _blockNumber); |
|||
ETH_CHECK_EQUAL(expectedBalance, balance); |
|||
|
|||
// countAt
|
|||
u256 expectedCount = u256(_o["nonce"].asString()); |
|||
u256 count = _client.countAt(address, _blockNumber); |
|||
ETH_CHECK_EQUAL(expectedCount, count); |
|||
|
|||
// stateAt
|
|||
for (string const& pos: _o["storage"].getMemberNames()) |
|||
{ |
|||
u256 expectedState = u256(_o["storage"][pos].asString()); |
|||
u256 state = _client.stateAt(address, u256(pos), _blockNumber); |
|||
ETH_CHECK_EQUAL(expectedState, state); |
|||
} |
|||
|
|||
// codeAt
|
|||
bytes expectedCode = fromHex(_o["code"].asString()); |
|||
bytes code = _client.codeAt(address, _blockNumber); |
|||
ETH_CHECK_EQUAL_COLLECTIONS(expectedCode.begin(), expectedCode.end(), |
|||
code.begin(), code.end()); |
|||
}; |
|||
|
|||
for (string const& name: _json["postState"].getMemberNames()) |
|||
{ |
|||
Json::Value o = _json["postState"][name]; |
|||
compareState(o, name, PendingBlock); |
|||
} |
|||
|
|||
for (string const& name: _json["pre"].getMemberNames()) |
|||
{ |
|||
Json::Value o = _json["pre"][name]; |
|||
compareState(o, name, 0); |
|||
} |
|||
|
|||
// number
|
|||
unsigned expectedNumber = _json["blocks"].size(); |
|||
unsigned number = _client.number(); |
|||
ETH_CHECK_EQUAL(expectedNumber, number); |
|||
|
|||
u256 totalDifficulty = u256(_json["genesisBlockHeader"]["difficulty"].asString()); |
|||
for (Json::Value const& block: _json["blocks"]) |
|||
{ |
|||
Json::Value blockHeader = block["blockHeader"]; |
|||
Json::Value uncles = block["uncleHeaders"]; |
|||
Json::Value transactions = block["transactions"]; |
|||
h256 blockHash = h256(fromHex(blockHeader["hash"].asString())); |
|||
|
|||
// just update the difficulty
|
|||
for (Json::Value const& uncle: uncles) |
|||
{ |
|||
totalDifficulty += u256(uncle["difficulty"].asString()); |
|||
} |
|||
|
|||
// hashFromNumber
|
|||
h256 expectedHashFromNumber = h256(fromHex(blockHeader["hash"].asString())); |
|||
h256 hashFromNumber = _client.hashFromNumber(jsToInt(blockHeader["number"].asString())); |
|||
ETH_CHECK_EQUAL(expectedHashFromNumber, hashFromNumber); |
|||
|
|||
// blockInfo
|
|||
auto compareBlockInfos = [](Json::Value const& _b, Ethash::BlockHeader _blockInfo) -> void |
|||
{ |
|||
LogBloom expectedBlockInfoBloom = LogBloom(fromHex(_b["bloom"].asString())); |
|||
Address expectedBlockInfoCoinbase = Address(fromHex(_b["coinbase"].asString())); |
|||
u256 expectedBlockInfoDifficulty = u256(_b["difficulty"].asString()); |
|||
bytes expectedBlockInfoExtraData = fromHex(_b["extraData"].asString()); |
|||
u256 expectedBlockInfoGasLimit = u256(_b["gasLimit"].asString()); |
|||
u256 expectedBlockInfoGasUsed = u256(_b["gasUsed"].asString()); |
|||
h256 expectedBlockInfoHash = h256(fromHex(_b["hash"].asString())); |
|||
h256 expectedBlockInfoMixHash = h256(fromHex(_b["mixHash"].asString())); |
|||
Nonce expectedBlockInfoNonce = Nonce(fromHex(_b["nonce"].asString())); |
|||
u256 expectedBlockInfoNumber = u256(_b["number"].asString()); |
|||
h256 expectedBlockInfoParentHash = h256(fromHex(_b["parentHash"].asString())); |
|||
h256 expectedBlockInfoReceiptsRoot = h256(fromHex(_b["receiptTrie"].asString())); |
|||
u256 expectedBlockInfoTimestamp = u256(_b["timestamp"].asString()); |
|||
h256 expectedBlockInfoTransactionsRoot = h256(fromHex(_b["transactionsTrie"].asString())); |
|||
h256 expectedBlockInfoUncldeHash = h256(fromHex(_b["uncleHash"].asString())); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoBloom, _blockInfo.logBloom()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoCoinbase, _blockInfo.beneficiary()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoDifficulty, _blockInfo.difficulty()); |
|||
ETH_CHECK_EQUAL_COLLECTIONS( |
|||
expectedBlockInfoExtraData.begin(), |
|||
expectedBlockInfoExtraData.end(), |
|||
_blockInfo.extraData().begin(), |
|||
_blockInfo.extraData().end() |
|||
); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoGasLimit, _blockInfo.gasLimit()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoGasUsed, _blockInfo.gasUsed()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoHash, _blockInfo.hash()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoMixHash, _blockInfo.mixHash()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoNonce, _blockInfo.nonce()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoNumber, _blockInfo.number()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoParentHash, _blockInfo.parentHash()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoReceiptsRoot, _blockInfo.receiptsRoot()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoTimestamp, _blockInfo.timestamp()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoTransactionsRoot, _blockInfo.transactionsRoot()); |
|||
ETH_CHECK_EQUAL(expectedBlockInfoUncldeHash, _blockInfo.sha3Uncles()); |
|||
}; |
|||
|
|||
Ethash::BlockHeader blockInfo((static_cast<FixedClient&>(_client)).bc().headerData(blockHash), IgnoreSeal, h256{}, HeaderData); |
|||
compareBlockInfos(blockHeader, blockInfo); |
|||
|
|||
// blockDetails
|
|||
unsigned expectedBlockDetailsNumber = jsToInt(blockHeader["number"].asString()); |
|||
totalDifficulty += u256(blockHeader["difficulty"].asString()); |
|||
BlockDetails blockDetails = _client.blockDetails(blockHash); |
|||
ETH_CHECK_EQUAL(expectedBlockDetailsNumber, blockDetails.number); |
|||
ETH_CHECK_EQUAL(totalDifficulty, blockDetails.totalDifficulty); |
|||
|
|||
auto compareTransactions = [](Json::Value const& _t, Transaction _transaction) -> void |
|||
{ |
|||
bytes expectedTransactionData = fromHex(_t["data"].asString()); |
|||
u256 expectedTransactionGasLimit = u256(_t["gasLimit"].asString()); |
|||
u256 expectedTransactionGasPrice = u256(_t["gasPrice"].asString()); |
|||
u256 expectedTransactionNonce = u256(_t["nonce"].asString()); |
|||
u256 expectedTransactionSignatureR = h256(fromHex(_t["r"].asString())); |
|||
u256 expectedTransactionSignatureS = h256(fromHex(_t["s"].asString())); |
|||
// unsigned expectedTransactionSignatureV = jsToInt(t["v"].asString());
|
|||
|
|||
ETH_CHECK_EQUAL_COLLECTIONS( |
|||
expectedTransactionData.begin(), |
|||
expectedTransactionData.end(), |
|||
_transaction.data().begin(), |
|||
_transaction.data().end() |
|||
); |
|||
ETH_CHECK_EQUAL(expectedTransactionGasLimit, _transaction.gas()); |
|||
ETH_CHECK_EQUAL(expectedTransactionGasPrice, _transaction.gasPrice()); |
|||
ETH_CHECK_EQUAL(expectedTransactionNonce, _transaction.nonce()); |
|||
ETH_CHECK_EQUAL(expectedTransactionSignatureR, _transaction.signature().r); |
|||
ETH_CHECK_EQUAL(expectedTransactionSignatureS, _transaction.signature().s); |
|||
// ETH_CHECK_EQUAL(expectedTransactionSignatureV, _transaction.signature().v); // 27 === 0x0, 28 === 0x1, not sure why
|
|||
}; |
|||
|
|||
Transactions ts = _client.transactions(blockHash); |
|||
TransactionHashes tHashes = _client.transactionHashes(blockHash); |
|||
unsigned tsCount = _client.transactionCount(blockHash); |
|||
|
|||
ETH_REQUIRE(transactions.size() == ts.size()); |
|||
ETH_REQUIRE(transactions.size() == tHashes.size()); |
|||
|
|||
// transactionCount
|
|||
ETH_CHECK_EQUAL(transactions.size(), tsCount); |
|||
|
|||
for (unsigned i = 0; i < tsCount; i++) |
|||
{ |
|||
Json::Value t = transactions[i]; |
|||
|
|||
// transaction (by block hash and transaction index)
|
|||
Transaction transaction = _client.transaction(blockHash, i); |
|||
compareTransactions(t, transaction); |
|||
|
|||
// transaction (by hash)
|
|||
Transaction transactionByHash = _client.transaction(transaction.sha3()); |
|||
compareTransactions(t, transactionByHash); |
|||
|
|||
// transactions
|
|||
compareTransactions(t, ts[i]); |
|||
|
|||
// transactionHashes
|
|||
ETH_CHECK_EQUAL(transaction.sha3(), tHashes[i]); |
|||
} |
|||
|
|||
// uncleCount
|
|||
unsigned usCount = _client.uncleCount(blockHash); |
|||
ETH_CHECK_EQUAL(uncles.size(), usCount); |
|||
|
|||
for (unsigned i = 0; i < usCount; i++) |
|||
{ |
|||
Json::Value u = uncles[i]; |
|||
|
|||
// uncle (by hash)
|
|||
BlockInfo uncle = _client.uncle(blockHash, i); |
|||
compareBlockInfos(u, uncle); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
File diff suppressed because it is too large
@ -1,24 +0,0 @@ |
|||
|
|||
n = 100 |
|||
|
|||
splitNumBegin = 128 - (n / 2) |
|||
i = 1 |
|||
|
|||
template = """ |
|||
function right{0}(uint seed) returns (uint) {{ |
|||
var r = nextRand(seed); |
|||
if (r >= 2**{2}) |
|||
return right{1}(r); |
|||
return left{1}(r); |
|||
}} |
|||
|
|||
function left{0}(uint seed) returns (uint) {{ |
|||
var r = nextRand(nextRand(seed)); |
|||
if (r >= 2**{2}) |
|||
return left{1}(r); |
|||
return right{1}(r); |
|||
}} |
|||
""" |
|||
|
|||
for i in range(1, n): |
|||
print template.format(i, i + 1, i + splitNumBegin) |
@ -1,169 +0,0 @@ |
|||
{ |
|||
"blockhash0" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "5", |
|||
"currentGasLimit" : "100000000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x" : "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", |
|||
"0x02" : "0x13600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 5) [[ 2 ]] (BLOCKHASH 4) }", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "285000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"blockhashOutOfRange" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "257", |
|||
"currentGasLimit" : "100000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (BLOCKHASH 0) [[ 1 ]] (BLOCKHASH 257) [[ 2 ]] (BLOCKHASH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "3850000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "2850000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"blockhashInRange" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "257", |
|||
"currentGasLimit" : "100000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x" : "0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", |
|||
"0x01" : "0xad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", |
|||
"0x02" : "0x6ca54da2c4784ea43fd88b3402de07ae4bced597cbb19f323b7595857a6720ae" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (BLOCKHASH 1) [[ 1 ]] (BLOCKHASH 2) [[ 2 ]] (BLOCKHASH 256) }", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "285000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"blockhashDOS-sec71" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "257", |
|||
"currentGasLimit" : "100000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x" : "0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", |
|||
"0x01" : "0xad7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", |
|||
"0x02" : "0x6ca54da2c4784ea43fd88b3402de07ae4bced597cbb19f323b7595857a6720ae" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "0x61010043035b804050600556", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "750000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -1,64 +0,0 @@ |
|||
{ |
|||
"add11" : { |
|||
"env" : "Environment parameters for test execution", |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : "Expected post state result (may be not defined at all)", |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000100000", |
|||
"code" : "0x6001600101600055", |
|||
"storage" : { |
|||
"0x" : "0x02" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "41012", |
|||
"code" : "0x", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "999999999999858988", |
|||
"code" : "0x", |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : "Previous state before execution", |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"code" : "0x6001600101600055", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000000000000000", |
|||
"code" : "0x", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : "could also be defiend via v,r,s instead of secretKey", |
|||
"transaction" : { |
|||
"data" : "", |
|||
"gasLimit" : "400000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "100000" |
|||
} |
|||
} |
|||
} |
@ -1,817 +0,0 @@ |
|||
{ |
|||
"TransactionCreateRandomInitCode" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "32599" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "67401", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x600a80600c6000396000f200600160008035811a8100", |
|||
"gasLimit" : "32599", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "1" |
|||
} |
|||
}, |
|||
|
|||
"NotEnoughCashContractCreation" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "22177" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "22177", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x600a80600c6000396000f200600160008035811a8100", |
|||
"gasLimit" : "22176", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "100" |
|||
} |
|||
}, |
|||
|
|||
"OutOfGasContractCreation" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x600a80600c6000396000f200600160008035811a8100", |
|||
"gasLimit" : "22000", |
|||
"gasPrice" : "3", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "1" |
|||
} |
|||
}, |
|||
"StackUnderFlowContractCreation" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "40000" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "50000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x6000f1", |
|||
"gasLimit" : "40000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"TransactionCreateAutoSuicideContract" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"0000000000000000000000000000000000000000" : { |
|||
"balance" : "15" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x600a80600c6000396000fff2ffff600160008035811a81", |
|||
"gasLimit" : "23000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "15" |
|||
} |
|||
}, |
|||
|
|||
"TransactionCreateStopInInitcode" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { |
|||
"balance" : "1" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x600a80600c600039600000f20000600160008035811a81", |
|||
"gasLimit" : "23000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "1" |
|||
} |
|||
}, |
|||
|
|||
"TransactionCreateSuicideInInitcode" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "23000" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x600a80600c6000396000f200ff600160008035811a81", |
|||
"gasLimit" : "23000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "", |
|||
"value" : "1" |
|||
} |
|||
}, |
|||
|
|||
"CallTheContractToCreateEmptyContract" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1", |
|||
"nonce" : "1" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
}, |
|||
"d2571607e241ecf590ed94b12d87c94babe36db6" : { |
|||
"balance" : "0", |
|||
"code" : "0x", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "0", |
|||
"nonce": "0", |
|||
"code": "{(CREATE 0 0 32)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "100000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "1" |
|||
} |
|||
}, |
|||
|
|||
"CallRecursiveContract" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1", |
|||
"nonce" : "41", |
|||
"storage" : { |
|||
"0x02" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" |
|||
} |
|||
}, |
|||
"1a4c83e1a9834cdc7e4a905ff7f0cf44aed73180" : { |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x02" : "0x1a4c83e1a9834cdc7e4a905ff7f0cf44aed73180" |
|||
} |
|||
}, |
|||
"8e3411c91d5dd4081b4846fa2f93808f5ad19686" : { |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x02" : "0x8e3411c91d5dd4081b4846fa2f93808f5ad19686" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "0", |
|||
"nonce": "40", |
|||
"code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "400000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "1" |
|||
} |
|||
}, |
|||
|
|||
"CallContractToCreateContractWhichWouldCreateContractInInitCode" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1", |
|||
"nonce" : "1" |
|||
}, |
|||
"62c01474f089b07dae603491675dc5b5748f7049" : { |
|||
"nonce" : "0" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
}, |
|||
"d2571607e241ecf590ed94b12d87c94babe36db6" : { |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x" : "0x0c" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "1", |
|||
"nonce": "0", |
|||
"//": "{[[0]] 12 (CREATE 0 64 32)}", |
|||
"code": "{(MSTORE 0 0x600c600055602060406000f0)(CREATE 0 20 12)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "20000000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"CallContractToCreateContractWhichWouldCreateContractIfCalled" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x" : "0xd2571607e241ecf590ed94b12d87c94babe36db6" |
|||
} |
|||
}, |
|||
"62c01474f089b07dae603491675dc5b5748f7049" : { |
|||
"nonce" : "0" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
}, |
|||
"d2571607e241ecf590ed94b12d87c94babe36db6" : { |
|||
"balance" : "2", |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x" : "0x0c" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "1000", |
|||
"nonce": "0", |
|||
"//": "(CREATE 0 64 32)", |
|||
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", |
|||
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 50000 (SLOAD 0) 1 0 0 0 0)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "20000000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"CallContractToCreateContractOOGBonusGas" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x" : "0xd2571607e241ecf590ed94b12d87c94babe36db6" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
}, |
|||
"d2571607e241ecf590ed94b12d87c94babe36db6" : { |
|||
"balance" : "1", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
"0x" : "0x0c" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "112", |
|||
"nonce": "0", |
|||
"//": "(CREATE 0 64 32)", |
|||
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", |
|||
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 12 0 0 0 0)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "20000000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"CallContractToCreateContractOOG" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"nonce" : "0" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "0", |
|||
"nonce": "0", |
|||
"//": "Create should fail. So CALL goes to 0x0...0", |
|||
"//": "(CREATE 0 64 32)", |
|||
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", |
|||
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 0 (SLOAD 0) 0 0 0 0 0)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "20000000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"CallContractToCreateContractAndCallItOOG" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"nonce" : "1", |
|||
"storage" : { |
|||
"0x" : "0xd2571607e241ecf590ed94b12d87c94babe36db6" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
}, |
|||
"d2571607e241ecf590ed94b12d87c94babe36db6" : { |
|||
"balance" : "1", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
"0x" : "0x0c" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "1000", |
|||
"nonce": "0", |
|||
"//": "(CREATE 0 64 32)", |
|||
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", |
|||
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 1 11 21)(CALL 1000 (SLOAD 0) 0 0 0 0 0)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "203000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"CallContractToCreateContractNoCash" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "100000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"nonce" : "0" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "10000", |
|||
"nonce": "0", |
|||
"//": "(CREATE 0 64 32)", |
|||
"//": "{[[0]] 12 (MSTORE 32 0x602060406000f0)(RETURN 57 7)}", |
|||
"code": "{(MSTORE 0 0x600c60005566602060406000f060205260076039f3)[[0]](CREATE 100000 11 21)}", |
|||
"storage": {} |
|||
}, |
|||
|
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x00", |
|||
"gasLimit" : "20000000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"ReturnTest" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "10000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"194f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"storage" : { |
|||
"0x" : "0x15" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"194f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "0", |
|||
"code" : "{(CALL 2000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 30 1 31 1) [[0]](MLOAD 0) (RETURN 30 2)}", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
|
|||
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"code" : "{(MSTORE 0 0x15) (RETURN 31 1)}", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "300000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "194f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "0" |
|||
} |
|||
}, |
|||
|
|||
"ReturnTest2" : { |
|||
"env" : { |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", |
|||
"currentDifficulty" : "45678256", |
|||
"currentGasLimit" : "1000000000", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : 1, |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"expect" : { |
|||
"194f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"storage" : { |
|||
"0x" : "0x15", |
|||
"0x01" : "0x3f" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : |
|||
{ |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"code" : "", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"194f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "0", |
|||
"code" : "{(MSTORE 0 0x15)(CALL 7000 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b 0 0 32 32 32) [[0]](MLOAD 0) [[1]](MLOAD 32) (RETURN 0 64)}", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
|
|||
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"code" : "{(MSTORE 0 (MUL 3 (CALLDATALOAD 0)))(RETURN 0 32)}", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "250000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "194f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "0" |
|||
} |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -1,245 +0,0 @@ |
|||
{ |
|||
"mload32bitBound": { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "17592320524892", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : "1", |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] (MLOAD 4294967296) } ", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "175923205248920", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "17592320524892", |
|||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"mload32bitBound_return": { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "175923205248920000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : "1", |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (RETURN 0 4294967295) } ", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1759232052489200000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "175923205248920000", |
|||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"mload32bitBound_return2": { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "175923205248920000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : "1", |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{[ 0 ] 1 (RETURN 0 4294967295) } ", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1759232052489200000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "175923205248920000", |
|||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"mload32bitBound_Msize": { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "175923205248920000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : "1", |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"storage" : { |
|||
"0x" : "0x20" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [4294967295] 1 [[ 0 ]] (MSIZE)} ", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1759232052489200000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "175923205248920000", |
|||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"mload32bitBound2": { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "37791080412587", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : "1", |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"post" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] (MLOAD 6294967296) } ", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "377910804219850", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "37791080412587", |
|||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"FillStack" : { |
|||
"env" : { |
|||
"currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5", |
|||
"currentDifficulty" : "5623894562375", |
|||
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", |
|||
"currentNumber" : "0", |
|||
"currentTimestamp" : "1", |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "0", |
|||
"code" : "0x5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3504357155320803a975560005155", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"945304eb96065b2a98b57a48a06ae28d285a71b5" : { |
|||
"balance" : "46", |
|||
"code" : "0x6000355415600957005b60203560003555", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000000000000000", |
|||
"code" : "0x", |
|||
"nonce" : "0", |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"data" : "0x5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3504357155320803a97", |
|||
"gasLimit" : "3141592", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "264050067" |
|||
} |
|||
} |
|||
} |
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
@ -1,69 +0,0 @@ |
|||
{ |
|||
"recursiveCreate": { |
|||
"env": { |
|||
"previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber": "0", |
|||
"currentGasLimit": "10000000", |
|||
"currentDifficulty": "256", |
|||
"currentTimestamp": 1, |
|||
"currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"pre": { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "20000000", |
|||
"nonce" : "0", |
|||
"code": "{(CODECOPY 0 0 32)(CREATE 0 0 32)}", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { |
|||
"balance": "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code": "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction": { |
|||
"nonce": "0", |
|||
"gasPrice": "1", |
|||
"gasLimit": "465224", |
|||
"to": "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value": "100000", |
|||
"secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data": "" |
|||
} |
|||
}, |
|||
|
|||
"recursiveCreateReturnValue": { |
|||
"env": { |
|||
"previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber": "0", |
|||
"currentGasLimit": "10000000000", |
|||
"currentDifficulty": "256", |
|||
"currentTimestamp": 1, |
|||
"currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"pre": { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87": { |
|||
"balance": "20000000", |
|||
"nonce" : "0", |
|||
"code": "{(CODECOPY 0 0 32) [[ 0 ]] (ADD (CREATE 0 0 32) 1) }", |
|||
"storage": {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { |
|||
"balance": "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code": "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction": { |
|||
"nonce": "0", |
|||
"gasPrice": "1", |
|||
"gasLimit": "1000000000", |
|||
"to": "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value": "100000", |
|||
"secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data": "" |
|||
} |
|||
} |
|||
} |
@ -1,956 +0,0 @@ |
|||
{ |
|||
"refund_getEtherBack" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "228500", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000010", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "13003" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "2271987", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 0 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "2285000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "228500", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_changeNonZeroStorage" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000010", |
|||
"storage" : { |
|||
"0x01" : "0x17" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "26006" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "973984", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 23 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "228500", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_OOG" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "26005" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "473995", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 0 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "500000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "26005", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_NoOOG_1" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "13003" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "37197", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 0 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "50200", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "26006", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund50_1" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "23015" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "76985", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"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" : "100000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "100000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund50_2" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x0a" : "0x01", |
|||
"0x0b" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "43021" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "56979", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"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" : "100000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "100000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund50percentCap" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x0a" : "0x8000000000000000000000000000000000000000000000000000000000000000", |
|||
"0x0b" : "0x0de0b6b3a7640000" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "45600" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "54400" |
|||
} |
|||
}, |
|||
"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" : "100000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "100000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund600" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x0b" : "0x0de0b6b3a7640000" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "38105" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "61895" |
|||
} |
|||
}, |
|||
"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" : "100000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "100000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refundSuicide50procentCap" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "10000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"storage" : { |
|||
"0x0a" : "0x01", |
|||
"0x0b" : "0x01", |
|||
"0x16" : "0x984476", |
|||
"0x17" : "0x96bd58" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "70566" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "9929434", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 22 ]] (GAS) [[ 10 ]] 1 [[ 11 ]] (CALL 500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 ) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 [[ 7 ]] 0 [[ 8 ]] 0 [[ 23 ]] (GAS) }", |
|||
"storage" : { |
|||
"0x01" : "0x01", |
|||
"0x02" : "0x01", |
|||
"0x03" : "0x01", |
|||
"0x04" : "0x01", |
|||
"0x05" : "0x01", |
|||
"0x06" : "0x01", |
|||
"0x07" : "0x01", |
|||
"0x08" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "10000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (SUICIDE 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) }", |
|||
"storage" : {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "10000000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_CallToSuicideStorage" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "10000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "2000000000000000010", |
|||
"storage" : { |
|||
"0x" : "0x01", |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "20534" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "99979456", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (CALL 500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (SUICIDE 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "10000000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_CallToSuicideNoStorage" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "10000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "2000000000000000010", |
|||
"storage" : { |
|||
"0x" : "0x01", |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "20534" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "99979456", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (CALL 500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (SUICIDE 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) }", |
|||
"storage" : {} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "10000000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_TxToSuicide" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "10000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000010", |
|||
"storage" : { |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "10502" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "99989488", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (SUICIDE 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "21003", |
|||
"to" : "aaae7baea6a6c7c4c2dfeb977efac326af552aaa", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_TxToSuicideOOG" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "10000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "21002" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "99978998", |
|||
"nonce" : "1" |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (SUICIDE 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "21002", |
|||
"to" : "aaae7baea6a6c7c4c2dfeb977efac326af552aaa", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_CallToSuicideTwice" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "10000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "2000000000000000010", |
|||
"storage" : { |
|||
"0x" : "0x01", |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "20566" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "99979424", |
|||
"nonce" : "1" |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (CALL 500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 ) (CALL 500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ (SUICIDE 0x095e7baea6a6c7c4c2dfeb977efac326af552d87) }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "10000000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_CallA" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000010", |
|||
"storage" : { |
|||
"0x" : "0x01", |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "31070" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "1968920", |
|||
"nonce" : "1" |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"storage" : { |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (CALL 5500 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 0 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "2000000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "200000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_CallA_notEnoughGasInCall" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000010", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "31069" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "68921", |
|||
"nonce" : "1" |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (CALL 5005 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 0 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "100000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "85000", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
}, |
|||
|
|||
"refund_CallA_OOG" : { |
|||
"env" : { |
|||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", |
|||
"currentNumber" : "0", |
|||
"currentGasLimit" : "1000000", |
|||
"currentDifficulty" : "256", |
|||
"currentTimestamp" : 1, |
|||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" |
|||
}, |
|||
"expect" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { |
|||
"balance" : "31069" |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "268931", |
|||
"nonce" : "1" |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
} |
|||
}, |
|||
"pre" : { |
|||
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 0 ]] (CALL 6000 0xaaae7baea6a6c7c4c2dfeb977efac326af552aaa 0 0 0 0 0 )}", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"aaae7baea6a6c7c4c2dfeb977efac326af552aaa" : { |
|||
"balance" : "1000000000000000000", |
|||
"nonce" : "0", |
|||
"code" : "{ [[ 1 ]] 0 }", |
|||
"storage" : { |
|||
"0x01" : "0x01" |
|||
} |
|||
}, |
|||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { |
|||
"balance" : "300000", |
|||
"nonce" : "0", |
|||
"code" : "", |
|||
"storage": {} |
|||
} |
|||
}, |
|||
"transaction" : { |
|||
"nonce" : "0", |
|||
"gasPrice" : "1", |
|||
"gasLimit" : "31069", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"data" : "" |
|||
} |
|||
} |
|||
} |
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
@ -1,169 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Transaction.cpp
|
|||
* @author Dmitrii Khokhlov <winsvega@mail.ru> |
|||
* @date 2015 |
|||
* Transaaction test functions. |
|||
*/ |
|||
|
|||
#include "test/TestHelper.h" |
|||
#include <libethcore/Exceptions.h> |
|||
#include <libevm/VMFace.h> |
|||
#include <libethcore/Common.h> |
|||
|
|||
using namespace dev; |
|||
using namespace eth; |
|||
|
|||
BOOST_AUTO_TEST_SUITE(libethereum) |
|||
|
|||
BOOST_AUTO_TEST_CASE(TransactionGasRequired) |
|||
{ |
|||
Transaction tr(fromHex("0xf86d800182521c94095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"), CheckTransaction::None); |
|||
BOOST_CHECK_MESSAGE(tr.gasRequired() == 21952, "Transaction::GasRequired() has changed!"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(TransactionConstructor) |
|||
{ |
|||
bool wasException = false; |
|||
try |
|||
{ |
|||
Transaction(fromHex("0xf86d800182521c94095e7baea6a6c7c4c2dfeb977efac326af552d870a8e0358ac39584bc98a7c979f984b031ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"), CheckTransaction::Everything); |
|||
} |
|||
catch (OutOfGasIntrinsic) |
|||
{ |
|||
wasException = true; |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
BOOST_ERROR("Exception thrown but expected OutOfGasIntrinsic instead"); |
|||
} |
|||
|
|||
BOOST_CHECK_MESSAGE(wasException, "Expected OutOfGasIntrinsic exception to be thrown at TransactionConstructor test"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ExecutionResultOutput) |
|||
{ |
|||
std::stringstream buffer; |
|||
ExecutionResult exRes; |
|||
|
|||
exRes.gasUsed = u256("12345"); |
|||
exRes.newAddress = Address("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"); |
|||
exRes.output = fromHex("001122334455"); |
|||
|
|||
buffer << exRes; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "{12345, a94f5374fce5edbc8e2a8697c15331677e6ebf0b, 001122334455}", "Error ExecutionResultOutput"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(transactionExceptionOutput) |
|||
{ |
|||
std::stringstream buffer; |
|||
buffer << TransactionException::BadInstruction; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "BadInstruction", "Error output TransactionException::BadInstruction"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::None; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "None", "Error output TransactionException::None"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::BadRLP; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "BadRLP", "Error output TransactionException::BadRLP"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::InvalidFormat; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "InvalidFormat", "Error output TransactionException::InvalidFormat"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::OutOfGasIntrinsic; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "OutOfGasIntrinsic", "Error output TransactionException::OutOfGasIntrinsic"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::InvalidSignature; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "InvalidSignature", "Error output TransactionException::InvalidSignature"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::InvalidNonce; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "InvalidNonce", "Error output TransactionException::InvalidNonce"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::NotEnoughCash; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "NotEnoughCash", "Error output TransactionException::NotEnoughCash"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::OutOfGasBase; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "OutOfGasBase", "Error output TransactionException::OutOfGasBase"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::BlockGasLimitReached; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "BlockGasLimitReached", "Error output TransactionException::BlockGasLimitReached"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::BadInstruction; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "BadInstruction", "Error output TransactionException::BadInstruction"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::BadJumpDestination; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "BadJumpDestination", "Error output TransactionException::BadJumpDestination"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::OutOfGas; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "OutOfGas", "Error output TransactionException::OutOfGas"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::OutOfStack; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "OutOfStack", "Error output TransactionException::OutOfStack"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException::StackUnderflow; |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "StackUnderflow", "Error output TransactionException::StackUnderflow"); |
|||
buffer.str(std::string()); |
|||
|
|||
buffer << TransactionException(-1); |
|||
BOOST_CHECK_MESSAGE(buffer.str() == "Unknown", "Error output TransactionException::StackUnderflow"); |
|||
buffer.str(std::string()); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(toTransactionExceptionConvert) |
|||
{ |
|||
RLPException rlpEx("exception");//toTransactionException(*(dynamic_cast<Exception*>
|
|||
BOOST_CHECK_MESSAGE(toTransactionException(rlpEx) == TransactionException::BadRLP, "RLPException !=> TransactionException"); |
|||
OutOfGasIntrinsic oogEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(oogEx) == TransactionException::OutOfGasIntrinsic, "OutOfGasIntrinsic !=> TransactionException"); |
|||
InvalidSignature sigEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(sigEx) == TransactionException::InvalidSignature, "InvalidSignature !=> TransactionException"); |
|||
OutOfGasBase oogbEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(oogbEx) == TransactionException::OutOfGasBase, "OutOfGasBase !=> TransactionException"); |
|||
InvalidNonce nonceEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(nonceEx) == TransactionException::InvalidNonce, "InvalidNonce !=> TransactionException"); |
|||
NotEnoughCash cashEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(cashEx) == TransactionException::NotEnoughCash, "NotEnoughCash !=> TransactionException"); |
|||
BlockGasLimitReached blGasEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(blGasEx) == TransactionException::BlockGasLimitReached, "BlockGasLimitReached !=> TransactionException"); |
|||
BadInstruction badInsEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(badInsEx) == TransactionException::BadInstruction, "BadInstruction !=> TransactionException"); |
|||
BadJumpDestination badJumpEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(badJumpEx) == TransactionException::BadJumpDestination, "BadJumpDestination !=> TransactionException"); |
|||
OutOfGas oogEx2; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(oogEx2) == TransactionException::OutOfGas, "OutOfGas !=> TransactionException"); |
|||
OutOfStack oosEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(oosEx) == TransactionException::OutOfStack, "OutOfStack !=> TransactionException"); |
|||
StackUnderflow stackEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(stackEx) == TransactionException::StackUnderflow, "StackUnderflow !=> TransactionException"); |
|||
Exception notEx; |
|||
BOOST_CHECK_MESSAGE(toTransactionException(notEx) == TransactionException::Unknown, "Unexpected should be TransactionException::Unknown"); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
File diff suppressed because one or more lines are too long
@ -1,867 +0,0 @@ |
|||
{ |
|||
"RightVRSTest" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"invalidSignature" : { |
|||
"expect" : "invalid", |
|||
"transaction" : { |
|||
"data" : "", |
|||
"gasLimit" : "1000000", |
|||
"gasPrice" : "0", |
|||
"nonce" : "0", |
|||
"r" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", |
|||
"s" : "0xbadf00d70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", |
|||
"v": "27", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "100000" |
|||
} |
|||
}, |
|||
|
|||
"NotEnoughGasLimit" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x", |
|||
"gasLimit" : "20000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"V_overflow32bit" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x5544", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "4294967323", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"V_overflow32bitSigned" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x5544", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "2147483647", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"V_overflow64bitPlus27" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x5544", |
|||
"gasLimit" : "22000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "18446744073709551643", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"V_overflow64bitPlus28" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x5544", |
|||
"gasLimit" : "22000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "18446744073709551644", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"V_overflow64bitSigned" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x5544", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "18446744073709551388", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"WrongVRSTestVEqual26" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "26", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"WrongVRSTestVEqual29" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "29", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"WrongVRSTestVEqual31" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "31", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"WrongVRSTestVOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "310", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"WrongVRSTestIncorrectSize" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a02c3", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a302c3" |
|||
} |
|||
}, |
|||
|
|||
"SenderTest" : { |
|||
"senderExpect" : "sender 0f65fe9276bc9a24ae7083ae28e2660ef72df99e", |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"DataTestNotEnoughGAS" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x0358ac39584bc98a7c979f984b03", |
|||
"gasLimit" : "21020", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"DataTestEnoughGAS" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x0358ac39584bc98a7c979f984b03", |
|||
"gasLimit" : "23000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"DataTestZeroBytes" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x000000000000000000000000000000000000000000000000000000000", |
|||
"gasLimit" : "25000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"DataTestLastZeroBytes" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x010000000000000000000000000000000000000000000000000000000", |
|||
"gasLimit" : "25000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"DataTestFirstZeroBytes" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x000000000000000000000000001000000000000000000000000000000", |
|||
"gasLimit" : "25000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "secretkey 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithTooManyRLPElements" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "10", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804", |
|||
"extrafield" : "128472387293" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithTooFewRLPElements" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithHihghValue" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
|
|||
"TransactionWithHighValueOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithSvalueHigh" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithSvalue0" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithSvalue1" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0x01" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithSvalueTooHigh" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithSvalueOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0000" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRvalueOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410000", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRvalueHigh" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRvalueTooHigh" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRvalue0" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRvalue1" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x01", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRvaluePrefixed00" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0xebaaedce6af48a03bbfd25e8cd0364141", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRSvalue0" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0", |
|||
"s" : "0" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithRSvalue1" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "1", |
|||
"s" : "1" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithSvaluePrefixed00" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0xef0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithHihghNonce256" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithHihghNonce32" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "4294967296", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithNonceOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithHihghGas" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithHihghGasPrice" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithGasLimitxPriceOverflow" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", |
|||
"gasPrice" : "100000000000000000", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithGasPriceOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"TransactionWithGasLimitOverflow" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639936", |
|||
"gasPrice" : "123", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"AddressMoreThan20PrefixedBy0" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "0x12", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "123", |
|||
"nonce" : "54", |
|||
"to" : "0x0000000000000000095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "11", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"EmptyTransaction" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "0", |
|||
"gasPrice" : "0", |
|||
"nonce" : "0", |
|||
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", |
|||
"value" : "0", |
|||
"v" : "27", |
|||
"r" : "0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353", |
|||
"s" : "0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804" |
|||
} |
|||
}, |
|||
|
|||
"AddressMoreThan20" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b1c", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"AddressLessThan20" : { |
|||
"expect" : "invalid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "b9331677e6ebf", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"AddressLessThan20Prefixed0" : { |
|||
"expect" : "valid", |
|||
"transaction" : |
|||
{ |
|||
"data" : "", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "0", |
|||
"to" : "0x000000000000000000000000000b9331677e6ebf", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", |
|||
"s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" |
|||
} |
|||
}, |
|||
|
|||
"unpadedRValue": { |
|||
"expect" : "valid", |
|||
"transaction": { |
|||
"nonce": "13", |
|||
"gasPrice": "0x09184e72a000", |
|||
"gasLimit": "0xf710", |
|||
"to": "7c47ef93268a311f4cad0c750724299e9b72c268", |
|||
"data": "0x379607f50000000000000000000000000000000000000000000000000000000000000005", |
|||
"r": "0x006ab6dda9f4df56ea45583af36660329147f1753f3724ea5eb9ed83e812ca77", |
|||
"s": "0x495701e230667832c8999e884e366a61028633ecf951e8cd66d119f381ae5718", |
|||
"v": "28", |
|||
"value": "" |
|||
} |
|||
}, |
|||
|
|||
"libsecp256k1test": { |
|||
"expect" : "valid", |
|||
"transaction": { |
|||
"nonce": "0", |
|||
"gasPrice": "0x09184e72a000", |
|||
"gasLimit": "0xf388", |
|||
"to": "", |
|||
"data": "0x", |
|||
"r": "44", |
|||
"s": "4", |
|||
"v": "27", |
|||
"value": "0" |
|||
} |
|||
}, |
|||
|
|||
"dataTx_bcValidBlockTest": { |
|||
"expect" : "valid", |
|||
"transaction": { |
|||
"nonce": "0", |
|||
"gasPrice": "50", |
|||
"gasLimit": "50000", |
|||
"to": "", |
|||
"data": "0x60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b56", |
|||
"r" : "0xc5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0", |
|||
"s" : "0xe221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", |
|||
"v": "28", |
|||
"value": "0" |
|||
} |
|||
}, |
|||
|
|||
"RSsecp256k1" : { |
|||
"expect" : "invalid", |
|||
"transaction" : { |
|||
"data" : "0x", |
|||
"gasLimit" : "21000", |
|||
"gasPrice" : "1", |
|||
"nonce" : "3", |
|||
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", |
|||
"value" : "10", |
|||
"v" : "28", |
|||
"r" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", |
|||
"s" : "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" |
|||
} |
|||
} |
|||
} |
@ -1,865 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file block.cpp
|
|||
* @author Christoph Jentzsch <cj@ethdev.com> |
|||
* @date 2015 |
|||
* block test functions. |
|||
*/ |
|||
#include "test/fuzzTesting/fuzzHelper.h" |
|||
#include <boost/filesystem.hpp> |
|||
#include <libdevcore/FileSystem.h> |
|||
#include <libdevcore/TransientDirectory.h> |
|||
#include <libethcore/Params.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <libethereum/TransactionQueue.h> |
|||
#include <test/TestHelper.h> |
|||
#include <libethereum/Block.h> |
|||
|
|||
using namespace std; |
|||
using namespace json_spirit; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev { namespace test { |
|||
|
|||
typedef std::vector<bytes> uncleList; |
|||
typedef std::pair<bytes, uncleList> blockSet; |
|||
|
|||
using BlockHeader = Ethash::BlockHeader; |
|||
|
|||
BlockHeader constructBlock(mObject& _o, h256 const& _stateRoot = h256{}); |
|||
bytes createBlockRLPFromFields(mObject& _tObj, h256 const& _stateRoot = h256{}); |
|||
RLPStream createFullBlockFromHeader(BlockHeader const& _bi, bytes const& _txs = RLPEmptyList, bytes const& _uncles = RLPEmptyList); |
|||
|
|||
mArray writeTransactionsToJson(Transactions const& _txs); |
|||
mObject writeBlockHeaderToJson(mObject& _o, BlockHeader const& _bi); |
|||
void overwriteBlockHeader(BlockHeader& _current_BlockHeader, mObject& _blObj, const BlockHeader& _parent); |
|||
void updatePoW(BlockHeader& _bi); |
|||
mArray importUncles(mObject const& _blObj, vector<BlockHeader>& _vBiUncles, vector<BlockHeader> const& _vBiBlocks, std::vector<blockSet> _blockSet); |
|||
|
|||
void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) |
|||
{ |
|||
string testname; |
|||
for (auto& i: _v.get_obj()) |
|||
{ |
|||
mObject& o = i.second.get_obj(); |
|||
if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) |
|||
{ |
|||
o.clear(); |
|||
continue; |
|||
} |
|||
|
|||
cnote << i.first; |
|||
testname = "(" + i.first + ") "; |
|||
BOOST_REQUIRE(o.count("genesisBlockHeader")); |
|||
BOOST_REQUIRE(o.count("pre")); |
|||
|
|||
ImportTest importer(o, _fillin, testType::BlockChainTests); |
|||
TransientDirectory tdStateDB; |
|||
BlockHeader biGenesisBlock = constructBlock(o["genesisBlockHeader"].get_obj(), h256{}); |
|||
|
|||
State trueState(OverlayDB(State::openDB(tdStateDB.path(), h256{}, WithExisting::Kill)), BaseState::Empty); |
|||
ImportTest::importState(o["pre"].get_obj(), trueState); |
|||
o["pre"] = fillJsonWithState(trueState); //convert all fields to hex
|
|||
trueState.commit(); |
|||
|
|||
//Imported blocks from the start
|
|||
vector<blockSet> blockSets; //Block(bytes) => UncleList(Blocks(bytes))
|
|||
|
|||
if (_fillin) |
|||
biGenesisBlock = constructBlock(o["genesisBlockHeader"].get_obj(), trueState.rootHash()); |
|||
else |
|||
BOOST_CHECK_MESSAGE(biGenesisBlock.stateRoot() == trueState.rootHash(), testname + "root hash does not match"); |
|||
|
|||
if (_fillin) |
|||
{ |
|||
// find new valid nonce
|
|||
updatePoW(biGenesisBlock); |
|||
|
|||
//update genesis block in json file
|
|||
writeBlockHeaderToJson(o["genesisBlockHeader"].get_obj(), biGenesisBlock); |
|||
} |
|||
|
|||
// create new "genesis" block
|
|||
RLPStream rlpGenesisBlock = createFullBlockFromHeader(biGenesisBlock); |
|||
biGenesisBlock.verifyInternals(&rlpGenesisBlock.out()); |
|||
o["genesisRLP"] = toHex(rlpGenesisBlock.out(), 2, HexPrefix::Add); |
|||
|
|||
// construct true blockchain
|
|||
TransientDirectory td; |
|||
FullBlockChain<Ethash> trueBc(rlpGenesisBlock.out(), AccountMap(), td.path(), WithExisting::Kill); |
|||
|
|||
if (_fillin) |
|||
{ |
|||
BOOST_REQUIRE(o.count("blocks")); |
|||
mArray blArray; |
|||
|
|||
blockSet genesis; |
|||
genesis.first = rlpGenesisBlock.out(); |
|||
genesis.second = uncleList(); |
|||
blockSets.push_back(genesis); |
|||
vector<BlockHeader> vBiBlocks; |
|||
vBiBlocks.push_back(biGenesisBlock); |
|||
|
|||
size_t importBlockNumber = 0; |
|||
for (auto const& bl: o["blocks"].get_array()) |
|||
{ |
|||
mObject blObj = bl.get_obj(); |
|||
if (blObj.count("blocknumber") > 0) |
|||
importBlockNumber = max((int)toInt(blObj["blocknumber"]), 1); |
|||
else |
|||
importBlockNumber++; |
|||
|
|||
//each time construct a new blockchain up to importBlockNumber (to generate next block header)
|
|||
vBiBlocks.clear(); |
|||
vBiBlocks.push_back(biGenesisBlock); |
|||
|
|||
TransientDirectory tdBc; |
|||
TransientDirectory tdStateDB; |
|||
FullBlockChain<Ethash> bc(rlpGenesisBlock.out(), AccountMap(), tdBc.path(), WithExisting::Kill); |
|||
|
|||
//OverlayDB database (State::openDB(td_stateDB.path(), h256{}, WithExisting::Kill));
|
|||
State state(OverlayDB(State::openDB(tdStateDB.path(), h256{}, WithExisting::Kill)), BaseState::Empty); //= importer.m_statePre;
|
|||
ImportTest::importState(o["pre"].get_obj(), state); |
|||
state.commit(); |
|||
|
|||
//import previous blocks
|
|||
for (size_t i = 1; i < importBlockNumber; i++) //0 block is genesis
|
|||
{ |
|||
BlockQueue uncleQueue; |
|||
uncleQueue.setChain(bc); |
|||
uncleList uncles = blockSets.at(i).second; |
|||
for (size_t j = 0; j < uncles.size(); j++) |
|||
uncleQueue.import(&uncles.at(j), false); |
|||
|
|||
const bytes blockFromSet = blockSets.at(i).first; |
|||
bc.sync(uncleQueue, state.db(), 4); |
|||
bc.attemptImport(blockFromSet, state.db()); |
|||
vBiBlocks.push_back(BlockHeader(blockFromSet)); |
|||
} |
|||
|
|||
// get txs
|
|||
TransactionQueue txs; |
|||
ZeroGasPricer gp; |
|||
BOOST_REQUIRE(blObj.count("transactions")); |
|||
for (auto const& txObj: blObj["transactions"].get_array()) |
|||
{ |
|||
mObject tx = txObj.get_obj(); |
|||
importer.importTransaction(tx); |
|||
if (txs.import(importer.m_transaction.rlp()) != ImportResult::Success) |
|||
cnote << "failed importing transaction\n"; |
|||
} |
|||
|
|||
//get uncles
|
|||
vector<BlockHeader> vBiUncles; |
|||
blObj["uncleHeaders"] = importUncles(blObj, vBiUncles, vBiBlocks, blockSets); |
|||
|
|||
BlockQueue uncleBlockQueue; |
|||
uncleBlockQueue.setChain(bc); |
|||
uncleList uncleBlockQueueList; |
|||
cnote << "import uncle in blockQueue"; |
|||
for (size_t i = 0; i < vBiUncles.size(); i++) |
|||
{ |
|||
RLPStream uncle = createFullBlockFromHeader(vBiUncles.at(i)); |
|||
try |
|||
{ |
|||
uncleBlockQueue.import(&uncle.out(), false); |
|||
uncleBlockQueueList.push_back(uncle.out()); |
|||
// wait until block is verified
|
|||
this_thread::sleep_for(chrono::seconds(1)); |
|||
} |
|||
catch(...) |
|||
{ |
|||
cnote << "error in importing uncle! This produces an invalid block (May be by purpose for testing)."; |
|||
} |
|||
} |
|||
|
|||
bc.sync(uncleBlockQueue, state.db(), 4); |
|||
|
|||
Block block = bc.genesisBlock(state.db()); //NOT CLEAR WHAT IT RETURNS IF bc INITIALIZED WITH CUSTOM GENESIS BLOCK
|
|||
block.setBeneficiary(biGenesisBlock.beneficiary()); |
|||
try |
|||
{ |
|||
block.sync(bc); |
|||
block.sync(bc, txs, gp); |
|||
mine(block, bc); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
cnote << "block sync or mining did throw an exception: " << diagnostic_information(_e); |
|||
return; |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
cnote << "block sync or mining did throw an exception: " << _e.what(); |
|||
return; |
|||
} |
|||
|
|||
blObj["rlp"] = toHex(block.blockData(), 2, HexPrefix::Add); |
|||
|
|||
//get valid transactions
|
|||
Transactions txList; |
|||
for (auto const& txi: txs.topTransactions(std::numeric_limits<unsigned>::max())) |
|||
txList.push_back(txi); |
|||
blObj["transactions"] = writeTransactionsToJson(txList); |
|||
|
|||
BlockHeader current_BlockHeader(block.blockData()); |
|||
|
|||
RLPStream uncleStream; |
|||
uncleStream.appendList(vBiUncles.size()); |
|||
for (unsigned i = 0; i < vBiUncles.size(); ++i) |
|||
{ |
|||
RLPStream uncleRlp; |
|||
vBiUncles[i].streamRLP(uncleRlp); |
|||
uncleStream.appendRaw(uncleRlp.out()); |
|||
} |
|||
|
|||
if (blObj.count("blockHeader")) |
|||
overwriteBlockHeader(current_BlockHeader, blObj, bc.info()); |
|||
|
|||
if (blObj.count("blockHeader") && blObj["blockHeader"].get_obj().count("bruncle")) |
|||
current_BlockHeader.populateFromParent(vBiBlocks[vBiBlocks.size() -1]); |
|||
|
|||
if (vBiUncles.size()) |
|||
{ |
|||
// update unclehash in case of invalid uncles
|
|||
current_BlockHeader.setSha3Uncles(sha3(uncleStream.out())); |
|||
updatePoW(current_BlockHeader); |
|||
} |
|||
|
|||
// write block header
|
|||
mObject oBlockHeader; |
|||
writeBlockHeaderToJson(oBlockHeader, current_BlockHeader); |
|||
blObj["blockHeader"] = oBlockHeader; |
|||
vBiBlocks.push_back(current_BlockHeader); |
|||
|
|||
// compare blocks from state and from rlp
|
|||
RLPStream txStream; |
|||
txStream.appendList(txList.size()); |
|||
for (unsigned i = 0; i < txList.size(); ++i) |
|||
{ |
|||
RLPStream txrlp; |
|||
txList[i].streamRLP(txrlp); |
|||
txStream.appendRaw(txrlp.out()); |
|||
} |
|||
|
|||
RLPStream blockRLP = createFullBlockFromHeader(current_BlockHeader, txStream.out(), uncleStream.out()); |
|||
|
|||
blObj["rlp"] = toHex(blockRLP.out(), 2, HexPrefix::Add); |
|||
|
|||
if (sha3(RLP(block.blockData())[0].data()) != sha3(RLP(blockRLP.out())[0].data())) |
|||
{ |
|||
cnote << "block header mismatch block.blockData() vs updated block.info()\n"; |
|||
cnote << toHex(RLP(block.blockData())[0].data()) << "vs" << toHex(RLP(blockRLP.out())[0].data()); |
|||
} |
|||
|
|||
if (sha3(RLP(block.blockData())[1].data()) != sha3(RLP(blockRLP.out())[1].data())) |
|||
cnote << "txs mismatch\n"; |
|||
|
|||
if (sha3(RLP(block.blockData())[2].data()) != sha3(RLP(blockRLP.out())[2].data())) |
|||
cnote << "uncle list mismatch\n" << RLP(block.blockData())[2].data() << "\n" << RLP(blockRLP.out())[2].data(); |
|||
|
|||
try |
|||
{ |
|||
block.sync(bc); |
|||
bc.import(blockRLP.out(), block.db()); |
|||
block.sync(bc); |
|||
|
|||
//there we get new blockchain status in state which could have more difficulty than we have in trueState
|
|||
//attempt to import new block to the true blockchain
|
|||
trueBc.sync(uncleBlockQueue, trueState.db(), 4); |
|||
trueBc.attemptImport(blockRLP.out(), trueState.db()); |
|||
|
|||
if (block.blockData() == trueBc.block()) |
|||
trueState = block.state(); |
|||
|
|||
blockSet newBlock; |
|||
newBlock.first = blockRLP.out(); |
|||
newBlock.second = uncleBlockQueueList; |
|||
if (importBlockNumber < blockSets.size()) |
|||
{ |
|||
//make new correct history of imported blocks
|
|||
blockSets[importBlockNumber] = newBlock; |
|||
for (size_t i = importBlockNumber + 1; i < blockSets.size(); i++) |
|||
blockSets.pop_back(); |
|||
} |
|||
else |
|||
blockSets.push_back(newBlock); |
|||
} |
|||
// if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
|
|||
catch (...) |
|||
{ |
|||
cnote << "block is invalid!\n"; |
|||
blObj.erase(blObj.find("blockHeader")); |
|||
blObj.erase(blObj.find("uncleHeaders")); |
|||
blObj.erase(blObj.find("transactions")); |
|||
} |
|||
blArray.push_back(blObj); |
|||
this_thread::sleep_for(chrono::seconds(1)); |
|||
} //for blocks
|
|||
|
|||
if (o.count("expect") > 0) |
|||
{ |
|||
AccountMaskMap expectStateMap; |
|||
State stateExpect(OverlayDB(), BaseState::Empty); |
|||
ImportTest::importState(o["expect"].get_obj(), stateExpect, expectStateMap); |
|||
if (ImportTest::compareStates(stateExpect, trueState, expectStateMap, Options::get().checkState ? WhenError::Throw : WhenError::DontThrow)) |
|||
cerr << testname << endl; |
|||
o.erase(o.find("expect")); |
|||
} |
|||
|
|||
o["blocks"] = blArray; |
|||
o["postState"] = fillJsonWithState(trueState); |
|||
o["lastblockhash"] = toString(trueBc.info().hash()); |
|||
|
|||
//make all values hex in pre section
|
|||
State prestate(OverlayDB(), BaseState::Empty); |
|||
ImportTest::importState(o["pre"].get_obj(), prestate); |
|||
o["pre"] = fillJsonWithState(prestate); |
|||
}//_fillin
|
|||
else |
|||
{ |
|||
for (auto const& bl: o["blocks"].get_array()) |
|||
{ |
|||
bool importedAndBest = true; |
|||
mObject blObj = bl.get_obj(); |
|||
bytes blockRLP; |
|||
try |
|||
{ |
|||
blockRLP = importByteArray(blObj["rlp"].get_str()); |
|||
trueBc.import(blockRLP, trueState.db()); |
|||
if (trueBc.info() != BlockHeader(blockRLP)) |
|||
importedAndBest = false; |
|||
} |
|||
// if exception is thrown, RLP is invalid and no blockHeader, Transaction list, or Uncle list should be given
|
|||
catch (Exception const& _e) |
|||
{ |
|||
cnote << "state sync or block import did throw an exception: " << diagnostic_information(_e); |
|||
BOOST_CHECK(blObj.count("blockHeader") == 0); |
|||
BOOST_CHECK(blObj.count("transactions") == 0); |
|||
BOOST_CHECK(blObj.count("uncleHeaders") == 0); |
|||
continue; |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
cnote << "state sync or block import did throw an exception: " << _e.what(); |
|||
BOOST_CHECK(blObj.count("blockHeader") == 0); |
|||
BOOST_CHECK(blObj.count("transactions") == 0); |
|||
BOOST_CHECK(blObj.count("uncleHeaders") == 0); |
|||
continue; |
|||
} |
|||
catch (...) |
|||
{ |
|||
cnote << "state sync or block import did throw an exception\n"; |
|||
BOOST_CHECK(blObj.count("blockHeader") == 0); |
|||
BOOST_CHECK(blObj.count("transactions") == 0); |
|||
BOOST_CHECK(blObj.count("uncleHeaders") == 0); |
|||
continue; |
|||
} |
|||
|
|||
BOOST_REQUIRE(blObj.count("blockHeader")); |
|||
|
|||
mObject tObj = blObj["blockHeader"].get_obj(); |
|||
BlockHeader blockHeaderFromFields; |
|||
const bytes c_rlpBytesBlockHeader = createBlockRLPFromFields(tObj); |
|||
const RLP c_blockHeaderRLP(c_rlpBytesBlockHeader); |
|||
blockHeaderFromFields.populateFromHeader(c_blockHeaderRLP, IgnoreSeal); |
|||
|
|||
BlockHeader blockFromRlp(trueBc.header()); |
|||
|
|||
if (importedAndBest) |
|||
{ |
|||
//Check the fields restored from RLP to original fields
|
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.headerHash(WithProof) == blockFromRlp.headerHash(WithProof), testname + "hash in given RLP not matching the block hash!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.parentHash() == blockFromRlp.parentHash(), testname + "parentHash in given RLP not matching the block parentHash!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.sha3Uncles() == blockFromRlp.sha3Uncles(), testname + "sha3Uncles in given RLP not matching the block sha3Uncles!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.beneficiary() == blockFromRlp.beneficiary(), testname + "beneficiary in given RLP not matching the block beneficiary!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.stateRoot() == blockFromRlp.stateRoot(), testname + "stateRoot in given RLP not matching the block stateRoot!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.transactionsRoot() == blockFromRlp.transactionsRoot(), testname + "transactionsRoot in given RLP not matching the block transactionsRoot!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.receiptsRoot() == blockFromRlp.receiptsRoot(), testname + "receiptsRoot in given RLP not matching the block receiptsRoot!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.logBloom() == blockFromRlp.logBloom(), testname + "logBloom in given RLP not matching the block logBloom!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.difficulty() == blockFromRlp.difficulty(), testname + "difficulty in given RLP not matching the block difficulty!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.number() == blockFromRlp.number(), testname + "number in given RLP not matching the block number!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasLimit() == blockFromRlp.gasLimit(),"testname + gasLimit in given RLP not matching the block gasLimit!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.gasUsed() == blockFromRlp.gasUsed(), testname + "gasUsed in given RLP not matching the block gasUsed!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.timestamp() == blockFromRlp.timestamp(), testname + "timestamp in given RLP not matching the block timestamp!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.extraData() == blockFromRlp.extraData(), testname + "extraData in given RLP not matching the block extraData!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.mixHash() == blockFromRlp.mixHash(), testname + "mixHash in given RLP not matching the block mixHash!"); |
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields.nonce() == blockFromRlp.nonce(), testname + "nonce in given RLP not matching the block nonce!"); |
|||
|
|||
BOOST_CHECK_MESSAGE(blockHeaderFromFields == blockFromRlp, testname + "However, blockHeaderFromFields != blockFromRlp!"); |
|||
|
|||
//Check transaction list
|
|||
Transactions txsFromField; |
|||
|
|||
for (auto const& txObj: blObj["transactions"].get_array()) |
|||
{ |
|||
mObject tx = txObj.get_obj(); |
|||
|
|||
BOOST_REQUIRE(tx.count("nonce")); |
|||
BOOST_REQUIRE(tx.count("gasPrice")); |
|||
BOOST_REQUIRE(tx.count("gasLimit")); |
|||
BOOST_REQUIRE(tx.count("to")); |
|||
BOOST_REQUIRE(tx.count("value")); |
|||
BOOST_REQUIRE(tx.count("v")); |
|||
BOOST_REQUIRE(tx.count("r")); |
|||
BOOST_REQUIRE(tx.count("s")); |
|||
BOOST_REQUIRE(tx.count("data")); |
|||
|
|||
try |
|||
{ |
|||
Transaction t(createRLPStreamFromTransactionFields(tx).out(), CheckTransaction::Everything); |
|||
txsFromField.push_back(t); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed transaction constructor with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (exception const& _e) |
|||
{ |
|||
cnote << _e.what(); |
|||
} |
|||
} |
|||
|
|||
Transactions txsFromRlp; |
|||
RLP root(blockRLP); |
|||
for (auto const& tr: root[1]) |
|||
{ |
|||
Transaction tx(tr.data(), CheckTransaction::Everything); |
|||
txsFromRlp.push_back(tx); |
|||
} |
|||
|
|||
BOOST_CHECK_MESSAGE(txsFromRlp.size() == txsFromField.size(), "transaction list size does not match"); |
|||
|
|||
for (size_t i = 0; i < txsFromField.size(); ++i) |
|||
{ |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].data() == txsFromRlp[i].data(), testname + "transaction data in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].gas() == txsFromRlp[i].gas(), testname + "transaction gasLimit in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].gasPrice() == txsFromRlp[i].gasPrice(), testname + "transaction gasPrice in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].nonce() == txsFromRlp[i].nonce(), testname + "transaction nonce in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].signature().r == txsFromRlp[i].signature().r, testname + "transaction r in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].signature().s == txsFromRlp[i].signature().s, testname + "transaction s in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].signature().v == txsFromRlp[i].signature().v, testname + "transaction v in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].receiveAddress() == txsFromRlp[i].receiveAddress(), testname + "transaction receiveAddress in rlp and in field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].value() == txsFromRlp[i].value(), testname + "transaction receiveAddress in rlp and in field do not match"); |
|||
|
|||
BOOST_CHECK_MESSAGE(txsFromField[i] == txsFromRlp[i], testname + "transactions from rlp and transaction from field do not match"); |
|||
BOOST_CHECK_MESSAGE(txsFromField[i].rlp() == txsFromRlp[i].rlp(), testname + "transactions rlp do not match"); |
|||
} |
|||
|
|||
// check uncle list
|
|||
|
|||
// uncles from uncle list field
|
|||
vector<BlockHeader> uBlHsFromField; |
|||
if (blObj["uncleHeaders"].type() != json_spirit::null_type) |
|||
for (auto const& uBlHeaderObj: blObj["uncleHeaders"].get_array()) |
|||
{ |
|||
mObject uBlH = uBlHeaderObj.get_obj(); |
|||
BOOST_REQUIRE(uBlH.size() == 16); |
|||
bytes uncleRLP = createBlockRLPFromFields(uBlH); |
|||
const RLP c_uRLP(uncleRLP); |
|||
BlockHeader uncleBlockHeader; |
|||
try |
|||
{ |
|||
uncleBlockHeader.populateFromHeader(c_uRLP); |
|||
} |
|||
catch(...) |
|||
{ |
|||
BOOST_ERROR(testname + "invalid uncle header"); |
|||
} |
|||
uBlHsFromField.push_back(uncleBlockHeader); |
|||
} |
|||
|
|||
// uncles from block RLP
|
|||
vector<BlockHeader> uBlHsFromRlp; |
|||
for (auto const& uRLP: root[2]) |
|||
{ |
|||
BlockHeader uBl; |
|||
uBl.populateFromHeader(uRLP); |
|||
uBlHsFromRlp.push_back(uBl); |
|||
} |
|||
|
|||
BOOST_REQUIRE_EQUAL(uBlHsFromField.size(), uBlHsFromRlp.size()); |
|||
|
|||
for (size_t i = 0; i < uBlHsFromField.size(); ++i) |
|||
BOOST_CHECK_MESSAGE(uBlHsFromField[i] == uBlHsFromRlp[i], testname + "block header in rlp and in field do not match"); |
|||
}//importedAndBest
|
|||
}//all blocks
|
|||
|
|||
BOOST_REQUIRE(o.count("lastblockhash") > 0); |
|||
BOOST_CHECK_MESSAGE(toString(trueBc.info().hash()) == o["lastblockhash"].get_str(), |
|||
testname + "Boost check: " + i.first + " lastblockhash does not match " + toString(trueBc.info().hash()) + " expected: " + o["lastblockhash"].get_str()); |
|||
} |
|||
} |
|||
} |
|||
// helping functions
|
|||
|
|||
mArray importUncles(mObject const& _blObj, vector<BlockHeader>& _vBiUncles, vector<BlockHeader> const& _vBiBlocks, std::vector<blockSet> _blockSet) |
|||
{ |
|||
// write uncle list
|
|||
mArray aUncleList; |
|||
mObject uncleHeaderObj_pre; |
|||
|
|||
for (auto const& uHObj: _blObj.at("uncleHeaders").get_array()) |
|||
{ |
|||
mObject uncleHeaderObj = uHObj.get_obj(); |
|||
if (uncleHeaderObj.count("sameAsPreviousSibling")) |
|||
{ |
|||
writeBlockHeaderToJson(uncleHeaderObj_pre, _vBiUncles[_vBiUncles.size()-1]); |
|||
aUncleList.push_back(uncleHeaderObj_pre); |
|||
_vBiUncles.push_back(_vBiUncles[_vBiUncles.size()-1]); |
|||
uncleHeaderObj_pre = uncleHeaderObj; |
|||
continue; |
|||
} |
|||
|
|||
if (uncleHeaderObj.count("sameAsBlock")) |
|||
{ |
|||
size_t number = (size_t)toInt(uncleHeaderObj["sameAsBlock"]); |
|||
uncleHeaderObj.erase("sameAsBlock"); |
|||
BlockHeader currentUncle = _vBiBlocks[number]; |
|||
writeBlockHeaderToJson(uncleHeaderObj, currentUncle); |
|||
aUncleList.push_back(uncleHeaderObj); |
|||
_vBiUncles.push_back(currentUncle); |
|||
uncleHeaderObj_pre = uncleHeaderObj; |
|||
continue; |
|||
} |
|||
|
|||
if (uncleHeaderObj.count("sameAsPreviousBlockUncle")) |
|||
{ |
|||
bytes uncleRLP = _blockSet[(size_t)toInt(uncleHeaderObj["sameAsPreviousBlockUncle"])].second[0]; |
|||
BlockHeader uncleHeader(uncleRLP); |
|||
writeBlockHeaderToJson(uncleHeaderObj, uncleHeader); |
|||
aUncleList.push_back(uncleHeaderObj); |
|||
|
|||
_vBiUncles.push_back(uncleHeader); |
|||
uncleHeaderObj_pre = uncleHeaderObj; |
|||
continue; |
|||
} |
|||
|
|||
string overwrite = "false"; |
|||
if (uncleHeaderObj.count("overwriteAndRedoPoW")) |
|||
{ |
|||
overwrite = uncleHeaderObj["overwriteAndRedoPoW"].get_str(); |
|||
uncleHeaderObj.erase("overwriteAndRedoPoW"); |
|||
} |
|||
|
|||
BlockHeader uncleBlockFromFields = constructBlock(uncleHeaderObj); |
|||
|
|||
// make uncle header valid
|
|||
uncleBlockFromFields.setTimestamp((u256)time(0)); |
|||
if (_vBiBlocks.size() > 2) |
|||
{ |
|||
if (uncleBlockFromFields.number() - 1 < _vBiBlocks.size()) |
|||
uncleBlockFromFields.populateFromParent(_vBiBlocks[(size_t)uncleBlockFromFields.number() - 1]); |
|||
else |
|||
uncleBlockFromFields.populateFromParent(_vBiBlocks[_vBiBlocks.size() - 2]); |
|||
} |
|||
else |
|||
continue; |
|||
|
|||
if (overwrite != "false") |
|||
{ |
|||
uncleBlockFromFields = constructHeader( |
|||
overwrite == "parentHash" ? h256(uncleHeaderObj["parentHash"].get_str()) : uncleBlockFromFields.parentHash(), |
|||
uncleBlockFromFields.sha3Uncles(), |
|||
uncleBlockFromFields.beneficiary(), |
|||
overwrite == "stateRoot" ? h256(uncleHeaderObj["stateRoot"].get_str()) : uncleBlockFromFields.stateRoot(), |
|||
uncleBlockFromFields.transactionsRoot(), |
|||
uncleBlockFromFields.receiptsRoot(), |
|||
uncleBlockFromFields.logBloom(), |
|||
overwrite == "difficulty" ? toInt(uncleHeaderObj["difficulty"]) : overwrite == "timestamp" ? uncleBlockFromFields.calculateDifficulty(_vBiBlocks[(size_t)uncleBlockFromFields.number() - 1]) : uncleBlockFromFields.difficulty(), |
|||
uncleBlockFromFields.number(), |
|||
overwrite == "gasLimit" ? toInt(uncleHeaderObj["gasLimit"]) : uncleBlockFromFields.gasLimit(), |
|||
overwrite == "gasUsed" ? toInt(uncleHeaderObj["gasUsed"]) : uncleBlockFromFields.gasUsed(), |
|||
overwrite == "timestamp" ? toInt(uncleHeaderObj["timestamp"]) : uncleBlockFromFields.timestamp(), |
|||
uncleBlockFromFields.extraData()); |
|||
|
|||
if (overwrite == "parentHashIsBlocksParent") |
|||
uncleBlockFromFields.populateFromParent(_vBiBlocks[_vBiBlocks.size() - 1]); |
|||
} |
|||
|
|||
updatePoW(uncleBlockFromFields); |
|||
|
|||
if (overwrite == "nonce") |
|||
updateEthashSeal(uncleBlockFromFields, uncleBlockFromFields.mixHash(), Nonce(uncleHeaderObj["nonce"].get_str())); |
|||
|
|||
if (overwrite == "mixHash") |
|||
updateEthashSeal(uncleBlockFromFields, h256(uncleHeaderObj["mixHash"].get_str()), uncleBlockFromFields.nonce()); |
|||
|
|||
writeBlockHeaderToJson(uncleHeaderObj, uncleBlockFromFields); |
|||
|
|||
aUncleList.push_back(uncleHeaderObj); |
|||
_vBiUncles.push_back(uncleBlockFromFields); |
|||
|
|||
uncleHeaderObj_pre = uncleHeaderObj; |
|||
} //for _blObj["uncleHeaders"].get_array()
|
|||
|
|||
return aUncleList; |
|||
} |
|||
|
|||
bytes createBlockRLPFromFields(mObject& _tObj, h256 const& _stateRoot) |
|||
{ |
|||
RLPStream rlpStream; |
|||
rlpStream.appendList(_tObj.count("hash") > 0 ? (_tObj.size() - 1) : _tObj.size()); |
|||
|
|||
if (_tObj.count("parentHash")) |
|||
rlpStream << importByteArray(_tObj["parentHash"].get_str()); |
|||
|
|||
if (_tObj.count("uncleHash")) |
|||
rlpStream << importByteArray(_tObj["uncleHash"].get_str()); |
|||
|
|||
if (_tObj.count("coinbase")) |
|||
rlpStream << importByteArray(_tObj["coinbase"].get_str()); |
|||
|
|||
if (_stateRoot) |
|||
rlpStream << _stateRoot; |
|||
else if (_tObj.count("stateRoot")) |
|||
rlpStream << importByteArray(_tObj["stateRoot"].get_str()); |
|||
|
|||
if (_tObj.count("transactionsTrie")) |
|||
rlpStream << importByteArray(_tObj["transactionsTrie"].get_str()); |
|||
|
|||
if (_tObj.count("receiptTrie")) |
|||
rlpStream << importByteArray(_tObj["receiptTrie"].get_str()); |
|||
|
|||
if (_tObj.count("bloom")) |
|||
rlpStream << importByteArray(_tObj["bloom"].get_str()); |
|||
|
|||
if (_tObj.count("difficulty")) |
|||
rlpStream << bigint(_tObj["difficulty"].get_str()); |
|||
|
|||
if (_tObj.count("number")) |
|||
rlpStream << bigint(_tObj["number"].get_str()); |
|||
|
|||
if (_tObj.count("gasLimit")) |
|||
rlpStream << bigint(_tObj["gasLimit"].get_str()); |
|||
|
|||
if (_tObj.count("gasUsed")) |
|||
rlpStream << bigint(_tObj["gasUsed"].get_str()); |
|||
|
|||
if (_tObj.count("timestamp")) |
|||
rlpStream << bigint(_tObj["timestamp"].get_str()); |
|||
|
|||
if (_tObj.count("extraData")) |
|||
rlpStream << fromHex(_tObj["extraData"].get_str()); |
|||
|
|||
if (_tObj.count("mixHash")) |
|||
rlpStream << importByteArray(_tObj["mixHash"].get_str()); |
|||
|
|||
if (_tObj.count("nonce")) |
|||
rlpStream << importByteArray(_tObj["nonce"].get_str()); |
|||
|
|||
return rlpStream.out(); |
|||
} |
|||
|
|||
void overwriteBlockHeader(BlockHeader& _header, mObject& _blObj, BlockHeader const& _parent) |
|||
{ |
|||
auto ho = _blObj["blockHeader"].get_obj(); |
|||
if (ho.size() != 14) |
|||
{ |
|||
BlockHeader tmp = constructHeader( |
|||
ho.count("parentHash") ? h256(ho["parentHash"].get_str()) : _header.parentHash(), |
|||
ho.count("uncleHash") ? h256(ho["uncleHash"].get_str()) : _header.sha3Uncles(), |
|||
ho.count("coinbase") ? Address(ho["coinbase"].get_str()) : _header.beneficiary(), |
|||
ho.count("stateRoot") ? h256(ho["stateRoot"].get_str()): _header.stateRoot(), |
|||
ho.count("transactionsTrie") ? h256(ho["transactionsTrie"].get_str()) : _header.transactionsRoot(), |
|||
ho.count("receiptTrie") ? h256(ho["receiptTrie"].get_str()) : _header.receiptsRoot(), |
|||
ho.count("bloom") ? LogBloom(ho["bloom"].get_str()) : _header.logBloom(), |
|||
ho.count("difficulty") ? toInt(ho["difficulty"]) : _header.difficulty(), |
|||
ho.count("number") ? toInt(ho["number"]) : _header.number(), |
|||
ho.count("gasLimit") ? toInt(ho["gasLimit"]) : _header.gasLimit(), |
|||
ho.count("gasUsed") ? toInt(ho["gasUsed"]) : _header.gasUsed(), |
|||
ho.count("timestamp") ? toInt(ho["timestamp"]) : _header.timestamp(), |
|||
ho.count("extraData") ? importByteArray(ho["extraData"].get_str()) : _header.extraData()); |
|||
|
|||
if (ho.count("RelTimestamp")) |
|||
{ |
|||
tmp.setTimestamp(toInt(ho["RelTimestamp"]) +_parent.timestamp()); |
|||
tmp.setDifficulty(tmp.calculateDifficulty(_parent)); |
|||
this_thread::sleep_for(chrono::seconds((int)toInt(ho["RelTimestamp"]))); |
|||
} |
|||
|
|||
// find new valid nonce
|
|||
if (static_cast<BlockInfo>(tmp) != static_cast<BlockInfo>(_header) && tmp.difficulty()) |
|||
mine(tmp); |
|||
|
|||
|
|||
if (ho.count("mixHash")) |
|||
updateEthashSeal(tmp, h256(ho["mixHash"].get_str()), tmp.nonce()); |
|||
if (ho.count("nonce")) |
|||
updateEthashSeal(tmp, tmp.mixHash(), Nonce(ho["nonce"].get_str())); |
|||
|
|||
tmp.noteDirty(); |
|||
_header = tmp; |
|||
} |
|||
else |
|||
{ |
|||
// take the blockheader as is
|
|||
const bytes c_blockRLP = createBlockRLPFromFields(ho); |
|||
const RLP c_bRLP(c_blockRLP); |
|||
_header.populateFromHeader(c_bRLP, IgnoreSeal); |
|||
} |
|||
} |
|||
|
|||
BlockHeader constructBlock(mObject& _o, h256 const& _stateRoot) |
|||
{ |
|||
BlockHeader ret; |
|||
try |
|||
{ |
|||
// construct genesis block
|
|||
const bytes c_blockRLP = createBlockRLPFromFields(_o, _stateRoot); |
|||
const RLP c_bRLP(c_blockRLP); |
|||
ret.populateFromHeader(c_bRLP, IgnoreSeal); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
cnote << "block population did throw an exception: " << diagnostic_information(_e); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed block population with Exception: " << _e.what()); |
|||
} |
|||
catch(...) |
|||
{ |
|||
BOOST_ERROR("block population did throw an unknown exception\n"); |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
void updatePoW(BlockHeader& _bi) |
|||
{ |
|||
mine(_bi); |
|||
_bi.noteDirty(); |
|||
} |
|||
|
|||
mArray writeTransactionsToJson(Transactions const& _txs) |
|||
{ |
|||
mArray txArray; |
|||
for (auto const& txi: _txs) |
|||
{ |
|||
mObject txObject = fillJsonWithTransaction(txi); |
|||
txArray.push_back(txObject); |
|||
} |
|||
return txArray; |
|||
} |
|||
|
|||
mObject writeBlockHeaderToJson(mObject& _o, BlockHeader const& _bi) |
|||
{ |
|||
_o["parentHash"] = toString(_bi.parentHash()); |
|||
_o["uncleHash"] = toString(_bi.sha3Uncles()); |
|||
_o["coinbase"] = toString(_bi.beneficiary()); |
|||
_o["stateRoot"] = toString(_bi.stateRoot()); |
|||
_o["transactionsTrie"] = toString(_bi.transactionsRoot()); |
|||
_o["receiptTrie"] = toString(_bi.receiptsRoot()); |
|||
_o["bloom"] = toString(_bi.logBloom()); |
|||
_o["difficulty"] = toCompactHex(_bi.difficulty(), HexPrefix::Add, 1); |
|||
_o["number"] = toCompactHex(_bi.number(), HexPrefix::Add, 1); |
|||
_o["gasLimit"] = toCompactHex(_bi.gasLimit(), HexPrefix::Add, 1); |
|||
_o["gasUsed"] = toCompactHex(_bi.gasUsed(), HexPrefix::Add, 1); |
|||
_o["timestamp"] = toCompactHex(_bi.timestamp(), HexPrefix::Add, 1); |
|||
_o["extraData"] = toHex(_bi.extraData(), 2, HexPrefix::Add); |
|||
_o["mixHash"] = toString(_bi.mixHash()); |
|||
_o["nonce"] = toString(_bi.nonce()); |
|||
_o["hash"] = toString(_bi.hash()); |
|||
return _o; |
|||
} |
|||
|
|||
RLPStream createFullBlockFromHeader(BlockHeader const& _bi, bytes const& _txs, bytes const& _uncles) |
|||
{ |
|||
RLPStream rlpStream; |
|||
_bi.streamRLP(rlpStream, WithProof); |
|||
|
|||
RLPStream ret(3); |
|||
ret.appendRaw(rlpStream.out()); |
|||
ret.appendRaw(_txs); |
|||
ret.appendRaw(_uncles); |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
} }// Namespace Close
|
|||
|
|||
BOOST_AUTO_TEST_SUITE(BlockChainTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcForkBlockTest) |
|||
{ |
|||
dev::test::executeTests("bcForkBlockTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcTotalDifficultyTest) |
|||
{ |
|||
dev::test::executeTests("bcTotalDifficultyTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcInvalidRLPTest) |
|||
{ |
|||
dev::test::executeTests("bcInvalidRLPTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcRPC_API_Test) |
|||
{ |
|||
dev::test::executeTests("bcRPC_API_Test", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcValidBlockTest) |
|||
{ |
|||
dev::test::executeTests("bcValidBlockTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcInvalidHeaderTest) |
|||
{ |
|||
dev::test::executeTests("bcInvalidHeaderTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcUncleTest) |
|||
{ |
|||
dev::test::executeTests("bcUncleTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcUncleHeaderValiditiy) |
|||
{ |
|||
dev::test::executeTests("bcUncleHeaderValiditiy", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcGasPricerTest) |
|||
{ |
|||
dev::test::executeTests("bcGasPricerTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
//BOOST_AUTO_TEST_CASE(bcBruncleTest)
|
|||
//{
|
|||
// if (c_network != Network::Frontier)
|
|||
// dev::test::executeTests("bcBruncleTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests);
|
|||
//}
|
|||
|
|||
BOOST_AUTO_TEST_CASE(bcBlockGasLimitTest) |
|||
{ |
|||
dev::test::executeTests("bcBlockGasLimitTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(bcWalletTest) |
|||
{ |
|||
if (test::Options::get().wallet) |
|||
dev::test::executeTests("bcWalletTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(userDefinedFile) |
|||
{ |
|||
dev::test::userDefinedTest(dev::test::doBlockchainTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,144 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file gasPricer.cpp
|
|||
* @author Christoph Jentzsch <cj@ethdev.com> |
|||
* @date 2015 |
|||
* Gas pricer tests |
|||
*/ |
|||
|
|||
#include <libtestutils/BlockChainLoader.h> |
|||
#include <libethcore/Ethash.h> |
|||
#include <libethereum/BlockChain.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <libethereum/GasPricer.h> |
|||
#include <libethereum/BasicGasPricer.h> |
|||
#include "../TestHelper.h" |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev { namespace test { |
|||
|
|||
void executeGasPricerTest(string const& name, double _etherPrice, double _blockFee, string const& bcTestPath, TransactionPriority _txPrio, u256 _expectedAsk, u256 _expectedBid) |
|||
{ |
|||
cnote << name; |
|||
BasicGasPricer gp(u256(double(ether / 1000) / _etherPrice), u256(_blockFee * 1000)); |
|||
|
|||
Json::Value vJson = test::loadJsonFromFile(test::getTestPath() + bcTestPath); |
|||
test::BlockChainLoader bcLoader(vJson[name]); |
|||
BlockChain const& bc = bcLoader.bc(); |
|||
|
|||
gp.update(bc); |
|||
BOOST_CHECK_EQUAL(gp.ask(Block()), _expectedAsk); |
|||
BOOST_CHECK_EQUAL(gp.bid(_txPrio), _expectedBid); |
|||
} |
|||
} } |
|||
|
|||
BOOST_AUTO_TEST_SUITE(GasPricer) |
|||
|
|||
BOOST_AUTO_TEST_CASE(trivialGasPricer) |
|||
{ |
|||
cnote << "trivialGasPricer"; |
|||
std::shared_ptr<dev::eth::GasPricer> gp(new TrivialGasPricer); |
|||
BOOST_CHECK_EQUAL(gp->ask(Block()), DefaultGasPrice); |
|||
BOOST_CHECK_EQUAL(gp->bid(), DefaultGasPrice); |
|||
|
|||
bytes bl = CanonBlockChain<Ethash>::createGenesisBlock(); |
|||
gp->update(FullBlockChain<Ethash>(bl, AccountMap(), TransientDirectory().path(), WithExisting::Kill)); |
|||
BOOST_CHECK_EQUAL(gp->ask(Block()), DefaultGasPrice); |
|||
BOOST_CHECK_EQUAL(gp->bid(), DefaultGasPrice); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricerNoUpdate) |
|||
{ |
|||
cnote << "basicGasPricer"; |
|||
BasicGasPricer gp(u256(double(ether / 1000) / 30.679), u256(15.0 * 1000)); |
|||
BOOST_CHECK_EQUAL(gp.ask(Block()), 155632494086); |
|||
BOOST_CHECK_EQUAL(gp.bid(), 155632494086); |
|||
|
|||
gp.setRefPrice(u256(0)); |
|||
BOOST_CHECK_EQUAL(gp.ask(Block()), 0); |
|||
BOOST_CHECK_EQUAL(gp.bid(), 0); |
|||
|
|||
gp.setRefPrice(u256(1)); |
|||
gp.setRefBlockFees(u256(0)); |
|||
BOOST_CHECK_EQUAL(gp.ask(Block()), 0); |
|||
BOOST_CHECK_EQUAL(gp.bid(), 0); |
|||
|
|||
gp.setRefPrice(u256("0x100000000000000000000000000000000")); |
|||
BOOST_CHECK_THROW(gp.setRefBlockFees(u256("0x100000000000000000000000000000000")), Overflow); |
|||
BOOST_CHECK_EQUAL(gp.ask(Block()), 0); |
|||
BOOST_CHECK_EQUAL(gp.bid(), 0); |
|||
|
|||
gp.setRefPrice(1); |
|||
gp.setRefBlockFees(u256("0x100000000000000000000000000000000")); |
|||
BOOST_CHECK_THROW(gp.setRefPrice(u256("0x100000000000000000000000000000000")), Overflow); |
|||
BOOST_CHECK_EQUAL(gp.ask(Block()), u256("108315264019305646138446560671076")); |
|||
BOOST_CHECK_EQUAL(gp.bid(), u256("108315264019305646138446560671076")); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_RPC_API_Test) |
|||
{ |
|||
dev::test::executeGasPricerTest("RPC_API_Test", 30.679, 15.0, "/BlockchainTests/bcRPC_API_Test.json", TransactionPriority::Medium, 155632494086, 1); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_bcValidBlockTest) |
|||
{ |
|||
dev::test::executeGasPricerTest("SimpleTx", 30.679, 15.0, "/BlockchainTests/bcValidBlockTest.json", TransactionPriority::Medium, 155632494086, 10); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_bcUncleTest) |
|||
{ |
|||
dev::test::executeGasPricerTest("twoUncle", 30.679, 15.0, "/BlockchainTests/bcUncleTest.json", TransactionPriority::Medium, 155632494086, 1); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_bcUncleHeaderValiditiy) |
|||
{ |
|||
dev::test::executeGasPricerTest("correct", 30.679, 15.0, "/BlockchainTests/bcUncleHeaderValiditiy.json", TransactionPriority::Medium, 155632494086, 1); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_notxs) |
|||
{ |
|||
dev::test::executeGasPricerTest("notxs", 30.679, 15.0, "/BlockchainTests/bcGasPricerTest.json", TransactionPriority::Medium, 155632494086, 155632494086); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_LowestPrio) |
|||
{ |
|||
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockchainTests/bcGasPricerTest.json", TransactionPriority::Lowest, 15731282021, 10000000000000); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_LowPrio) |
|||
{ |
|||
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockchainTests/bcGasPricerTest.json", TransactionPriority::Low, 15731282021, 15734152261884); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_MediumPrio) |
|||
{ |
|||
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockchainTests/bcGasPricerTest.json", TransactionPriority::Medium, 15731282021, 20000000000000); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_HighPrio) |
|||
{ |
|||
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockchainTests/bcGasPricerTest.json", TransactionPriority::High, 15731282021, 24265847738115); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(basicGasPricer_highGasUsage_HighestPrio) |
|||
{ |
|||
dev::test::executeGasPricerTest("highGasUsage", 30.679, 15.0, "/BlockchainTests/bcGasPricerTest.json", TransactionPriority::Highest, 15731282021, 30000000000000); |
|||
} |
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,68 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file genesis.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* Trie test functions. |
|||
*/ |
|||
|
|||
#include <fstream> |
|||
#include <random> |
|||
|
|||
#include <boost/test/unit_test.hpp> |
|||
#include "../JsonSpiritHeaders.h" |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace js = json_spirit; |
|||
|
|||
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) |
|||
{ |
|||
string testPath = test::getTestPath(); |
|||
testPath += "/BasicTests"; |
|||
|
|||
cnote << "Testing Genesis block..."; |
|||
js::mValue v; |
|||
string s = contentsString(testPath + "/genesishashestest.json"); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'genesishashestest.json' is empty. Have you cloned the 'tests' repo branch develop?"); |
|||
js::read_string(s, v); |
|||
|
|||
js::mObject o = v.get_obj(); |
|||
|
|||
BOOST_CHECK_EQUAL(CanonBlockChain<Ethash>::genesis().stateRoot(), h256(o["genesis_state_root"].get_str())); |
|||
BOOST_CHECK_EQUAL(toHex(CanonBlockChain<Ethash>::createGenesisBlock()), toHex(fromHex(o["genesis_rlp_hex"].get_str()))); |
|||
BOOST_CHECK_EQUAL(Ethash::BlockHeader(CanonBlockChain<Ethash>::createGenesisBlock()).hash(), h256(o["genesis_hash"].get_str())); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
@ -1,257 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file state.cpp
|
|||
* @author Christoph Jentzsch <cj@ethdev.com> |
|||
* @date 2014 |
|||
* State test functions. |
|||
*/ |
|||
|
|||
#include <boost/filesystem/operations.hpp> |
|||
#include <boost/test/unit_test.hpp> |
|||
|
|||
#include "../JsonSpiritHeaders.h" |
|||
#include <libdevcore/CommonIO.h> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <libethereum/State.h> |
|||
#include <libethereum/ExtVM.h> |
|||
#include <libethereum/Defaults.h> |
|||
#include <libevm/VM.h> |
|||
#include <test/TestHelper.h> |
|||
|
|||
using namespace std; |
|||
using namespace json_spirit; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev { namespace test { |
|||
|
|||
void doStateTests(json_spirit::mValue& v, bool _fillin) |
|||
{ |
|||
string testname; |
|||
for (auto& i: v.get_obj()) |
|||
{ |
|||
mObject& o = i.second.get_obj(); |
|||
if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) |
|||
{ |
|||
o.clear(); |
|||
continue; |
|||
} |
|||
|
|||
cnote << i.first; |
|||
testname = "(" + i.first + ") "; |
|||
|
|||
BOOST_REQUIRE_MESSAGE(o.count("env") > 0, testname + "env not set!"); |
|||
BOOST_REQUIRE_MESSAGE(o.count("pre") > 0, testname + "pre not set!"); |
|||
BOOST_REQUIRE_MESSAGE(o.count("transaction") > 0, testname + "transaction not set!"); |
|||
|
|||
ImportTest importer(o, _fillin); |
|||
const State importedStatePost = importer.m_statePost; |
|||
bytes output; |
|||
|
|||
Listener::ExecTimeGuard guard{i.first}; |
|||
output = importer.executeTest(); |
|||
|
|||
if (_fillin) |
|||
{ |
|||
#if ETH_FATDB |
|||
if (importer.exportTest(output)) |
|||
cerr << testname << endl; |
|||
#else |
|||
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "You can not fill tests when FATDB is switched off")); |
|||
#endif |
|||
} |
|||
else |
|||
{ |
|||
BOOST_REQUIRE(o.count("post") > 0); |
|||
BOOST_REQUIRE(o.count("out") > 0); |
|||
|
|||
// check output
|
|||
checkOutput(output, o); |
|||
|
|||
// check logs
|
|||
checkLog(importer.m_logs, importer.m_logsExpected); |
|||
|
|||
// check addresses
|
|||
#if ETH_FATDB |
|||
ImportTest::compareStates(importer.m_statePost, importedStatePost); |
|||
#endif |
|||
BOOST_CHECK_MESSAGE(importer.m_statePost.rootHash() == h256(o["postStateRoot"].get_str()), testname + "wrong post state root"); |
|||
} |
|||
} |
|||
} |
|||
} }// Namespace Close
|
|||
|
|||
BOOST_AUTO_TEST_SUITE(StateTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(stExample) |
|||
{ |
|||
dev::test::executeTests("stExample", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stSystemOperationsTest) |
|||
{ |
|||
dev::test::executeTests("stSystemOperationsTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stCallCreateCallCodeTest) |
|||
{ |
|||
dev::test::executeTests("stCallCreateCallCodeTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stPreCompiledContracts) |
|||
{ |
|||
dev::test::executeTests("stPreCompiledContracts", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stLogTests) |
|||
{ |
|||
dev::test::executeTests("stLogTests", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stRecursiveCreate) |
|||
{ |
|||
dev::test::executeTests("stRecursiveCreate", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stInitCodeTest) |
|||
{ |
|||
dev::test::executeTests("stInitCodeTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stTransactionTest) |
|||
{ |
|||
dev::test::executeTests("stTransactionTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stSpecialTest) |
|||
{ |
|||
dev::test::executeTests("stSpecialTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stRefundTest) |
|||
{ |
|||
dev::test::executeTests("stRefundTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stBlockHashTest) |
|||
{ |
|||
dev::test::executeTests("stBlockHashTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stQuadraticComplexityTest) |
|||
{ |
|||
if (test::Options::get().quadratic) |
|||
dev::test::executeTests("stQuadraticComplexityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stMemoryStressTest) |
|||
{ |
|||
if (test::Options::get().memory) |
|||
dev::test::executeTests("stMemoryStressTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stSolidityTest) |
|||
{ |
|||
dev::test::executeTests("stSolidityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stMemoryTest) |
|||
{ |
|||
dev::test::executeTests("stMemoryTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stWalletTest) |
|||
{ |
|||
dev::test::executeTests("stWalletTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stCreateTest) |
|||
{ |
|||
for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) |
|||
{ |
|||
string arg = boost::unit_test::framework::master_test_suite().argv[i]; |
|||
if (arg == "--createtest") |
|||
{ |
|||
if (boost::unit_test::framework::master_test_suite().argc <= i + 2) |
|||
{ |
|||
cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n"; |
|||
return; |
|||
} |
|||
try |
|||
{ |
|||
cnote << "Populating tests..."; |
|||
json_spirit::mValue v; |
|||
string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); |
|||
json_spirit::read_string(s, v); |
|||
dev::test::doStateTests(v, true); |
|||
writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed state test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed state test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(stRandom) |
|||
{ |
|||
test::Options::get(); // parse command line options, e.g. to enable JIT
|
|||
|
|||
string testPath = dev::test::getTestPath(); |
|||
testPath += "/StateTests/RandomTests"; |
|||
|
|||
vector<boost::filesystem::path> testFiles; |
|||
boost::filesystem::directory_iterator iterator(testPath); |
|||
for(; iterator != boost::filesystem::directory_iterator(); ++iterator) |
|||
if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() == ".json") |
|||
testFiles.push_back(iterator->path()); |
|||
|
|||
for (auto& path: testFiles) |
|||
{ |
|||
try |
|||
{ |
|||
cnote << "Testing ..." << path.filename(); |
|||
json_spirit::mValue v; |
|||
string s = asString(dev::contents(path.string())); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); |
|||
json_spirit::read_string(s, v); |
|||
test::Listener::notifySuiteStarted(path.filename().string()); |
|||
dev::test::doStateTests(v, false); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR(path.filename().string() + "Failed test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR(path.filename().string() + "Failed test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(userDefinedFileState) |
|||
{ |
|||
dev::test::userDefinedTest(dev::test::doStateTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
@ -1,113 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file stateOriginal.cpp
|
|||
* @author Gav Wood <i@gavwood.com> |
|||
* @date 2014 |
|||
* State test functions. |
|||
*/ |
|||
|
|||
#include <test/TestHelper.h> |
|||
#include <boost/test/unit_test.hpp> |
|||
#include <boost/filesystem/operations.hpp> |
|||
#include <libethereum/CanonBlockChain.h> |
|||
#include <libethereum/Block.h> |
|||
#include <libethcore/Farm.h> |
|||
#include <libethcore/BasicAuthority.h> |
|||
#include <libethereum/Defaults.h> |
|||
|
|||
using namespace std; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace test |
|||
{ |
|||
|
|||
int stateTest(); |
|||
|
|||
BOOST_AUTO_TEST_SUITE(StateIntegration) |
|||
|
|||
BOOST_AUTO_TEST_CASE(Basic) |
|||
{ |
|||
Block s; |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(Complex) |
|||
{ |
|||
//Mining Changed on block branch
|
|||
//Review this test
|
|||
|
|||
/*if (test::Options::get().nodag)
|
|||
return; |
|||
|
|||
cnote << "Testing State..."; |
|||
|
|||
KeyPair me = Secret(sha3("Gav Wood")); |
|||
KeyPair myMiner = Secret(sha3("Gav's Miner")); |
|||
// KeyPair you = sha3("123");
|
|||
|
|||
Defaults::setDBPath(boost::filesystem::temp_directory_path().string() + "/" + toString(chrono::system_clock::now().time_since_epoch().count())); |
|||
|
|||
OverlayDB stateDB = State::openDB(h256()); |
|||
CanonBlockChain<BasicAuthority> bc; |
|||
cout << bc; |
|||
|
|||
Block s = bc.genesisBlock(stateDB); |
|||
s.setBeneficiary(myMiner.address()); |
|||
cout << s; |
|||
|
|||
// Sync up - this won't do much until we use the last state.
|
|||
s.sync(bc); |
|||
|
|||
cout << s; |
|||
|
|||
// Mine to get some ether!
|
|||
mine(s, bc); |
|||
|
|||
bc.attemptImport(s.blockData(), stateDB); |
|||
|
|||
cout << bc; |
|||
|
|||
s.sync(bc); |
|||
|
|||
cout << s; |
|||
|
|||
// Inject a transaction to transfer funds from miner to me.
|
|||
Transaction t(1000, 10000, 100000, me.address(), bytes(), s.transactionsFrom(myMiner.address()), myMiner.secret()); |
|||
assert(t.sender() == myMiner.address()); |
|||
s.execute(bc.lastHashes(), t); |
|||
|
|||
cout << s; |
|||
|
|||
// Mine to get some ether and set in stone.
|
|||
s.commitToSeal(bc); |
|||
s.commitToSeal(bc); |
|||
mine(s, bc); |
|||
bc.attemptImport(s.blockData(), stateDB); |
|||
|
|||
cout << bc; |
|||
|
|||
s.sync(bc); |
|||
|
|||
cout << s;*/ |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
|
|||
} |
|||
} |
@ -1,209 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file transactionTests.cpp
|
|||
* @author Dmitrii Khokhlov <winsvega@mail.ru> |
|||
* @date 2015 |
|||
* Transaction test functions. |
|||
*/ |
|||
|
|||
#include "../TestHelper.h" |
|||
#include "test/fuzzTesting/fuzzHelper.h" |
|||
|
|||
using namespace std; |
|||
using namespace json_spirit; |
|||
using namespace dev; |
|||
using namespace dev::eth; |
|||
|
|||
namespace dev { namespace test { |
|||
|
|||
void doTransactionTests(json_spirit::mValue& _v, bool _fillin) |
|||
{ |
|||
string testname; |
|||
for (auto& i: _v.get_obj()) |
|||
{ |
|||
mObject& o = i.second.get_obj(); |
|||
if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) |
|||
{ |
|||
o.clear(); |
|||
continue; |
|||
} |
|||
|
|||
testname = "(" + i.first + ") "; |
|||
cnote << testname; |
|||
if (_fillin) |
|||
{ |
|||
BOOST_REQUIRE(o.count("transaction") > 0); |
|||
mObject tObj = o["transaction"].get_obj(); |
|||
|
|||
//Construct Rlp of the given transaction
|
|||
RLPStream rlpStream = createRLPStreamFromTransactionFields(tObj); |
|||
o["rlp"] = toHex(rlpStream.out(), 2, HexPrefix::Add); |
|||
|
|||
try |
|||
{ |
|||
Transaction txFromFields(rlpStream.out(), CheckTransaction::Everything); |
|||
if (!txFromFields.signature().isValid()) |
|||
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "transaction from RLP signature is invalid") ); |
|||
|
|||
o["sender"] = toString(txFromFields.sender()); |
|||
o["transaction"] = ImportTest::makeAllFieldsHex(tObj); |
|||
} |
|||
catch(Exception const& _e) |
|||
{ |
|||
//Transaction is InValid
|
|||
cnote << "Transaction Exception: " << diagnostic_information(_e); |
|||
o.erase(o.find("transaction")); |
|||
if (o.count("expect") > 0) |
|||
{ |
|||
bool expectInValid = (o["expect"].get_str() == "invalid"); |
|||
if (Options::get().checkState) |
|||
BOOST_CHECK_MESSAGE(expectInValid, testname + "Check state: Transaction '" << i.first << "' is expected to be valid!"); |
|||
else |
|||
BOOST_WARN_MESSAGE(expectInValid, testname + "Check state: Transaction '" << i.first << "' is expected to be valid!"); |
|||
|
|||
o.erase(o.find("expect")); |
|||
} |
|||
} |
|||
|
|||
//Transaction is Valid
|
|||
if (o.count("expect") > 0) |
|||
{ |
|||
bool expectValid = (o["expect"].get_str() == "valid"); |
|||
if (Options::get().checkState) |
|||
BOOST_CHECK_MESSAGE(expectValid, testname + "Check state: Transaction '" << i.first << "' is expected to be invalid!"); |
|||
else |
|||
BOOST_WARN_MESSAGE(expectValid, testname + "Check state: Transaction '" << i.first << "' is expected to be invalid!"); |
|||
|
|||
o.erase(o.find("expect")); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
BOOST_REQUIRE(o.count("rlp") > 0); |
|||
Transaction txFromRlp; |
|||
try |
|||
{ |
|||
bytes stream = importByteArray(o["rlp"].get_str()); |
|||
RLP rlp(stream); |
|||
txFromRlp = Transaction(rlp.data(), CheckTransaction::Everything); |
|||
if (!txFromRlp.signature().isValid()) |
|||
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment(testname + "transaction from RLP signature is invalid") ); |
|||
} |
|||
catch(Exception const& _e) |
|||
{ |
|||
cnote << i.first; |
|||
cnote << "Transaction Exception: " << diagnostic_information(_e); |
|||
BOOST_CHECK_MESSAGE(o.count("transaction") == 0, testname + "A transaction object should not be defined because the RLP is invalid!"); |
|||
continue; |
|||
} |
|||
catch(...) |
|||
{ |
|||
BOOST_CHECK_MESSAGE(o.count("transaction") == 0, testname + "A transaction object should not be defined because the RLP is invalid!"); |
|||
continue; |
|||
} |
|||
|
|||
BOOST_REQUIRE_MESSAGE(o.count("transaction") > 0, testname + "Expected a valid transaction!"); |
|||
|
|||
mObject tObj = o["transaction"].get_obj(); |
|||
Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(), CheckTransaction::Everything); |
|||
|
|||
//Check the fields restored from RLP to original fields
|
|||
BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), testname + "Data in given RLP not matching the Transaction data!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), testname + "Value in given RLP not matching the Transaction value!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), testname + "GasPrice in given RLP not matching the Transaction gasPrice!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(), testname + "Gas in given RLP not matching the Transaction gas!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(), testname + "Nonce in given RLP not matching the Transaction nonce!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), testname + "Receive address in given RLP not matching the Transaction 'to' address!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), testname + "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!"); |
|||
BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, testname + "However, txFromFields != txFromRlp!"); |
|||
BOOST_REQUIRE (o.count("sender") > 0); |
|||
|
|||
Address addressReaded = Address(o["sender"].get_str()); |
|||
BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, testname + "Signature address of sender does not match given sender address!"); |
|||
} |
|||
}//for
|
|||
}//doTransactionTests
|
|||
|
|||
} }// Namespace Close
|
|||
|
|||
|
|||
BOOST_AUTO_TEST_SUITE(TransactionTests) |
|||
|
|||
BOOST_AUTO_TEST_CASE(ttTransactionTest) |
|||
{ |
|||
dev::test::executeTests("ttTransactionTest", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ttWrongRLPTransaction) |
|||
{ |
|||
dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(tt10mbDataField) |
|||
{ |
|||
if (test::Options::get().bigData) |
|||
{ |
|||
auto start = chrono::steady_clock::now(); |
|||
|
|||
dev::test::executeTests("tt10mbDataField", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests); |
|||
|
|||
auto end = chrono::steady_clock::now(); |
|||
auto duration(chrono::duration_cast<chrono::milliseconds>(end - start)); |
|||
cnote << "test duration: " << duration.count() << " milliseconds.\n"; |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(ttCreateTest) |
|||
{ |
|||
for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) |
|||
{ |
|||
string arg = boost::unit_test::framework::master_test_suite().argv[i]; |
|||
if (arg == "--createtest") |
|||
{ |
|||
if (boost::unit_test::framework::master_test_suite().argc <= i + 2) |
|||
{ |
|||
cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n"; |
|||
return; |
|||
} |
|||
try |
|||
{ |
|||
cnote << "Populating tests..."; |
|||
json_spirit::mValue v; |
|||
string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); |
|||
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); |
|||
json_spirit::read_string(s, v); |
|||
dev::test::doTransactionTests(v, true); |
|||
writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); |
|||
} |
|||
catch (Exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed transaction test with Exception: " << diagnostic_information(_e)); |
|||
} |
|||
catch (std::exception const& _e) |
|||
{ |
|||
BOOST_ERROR("Failed transaction test with Exception: " << _e.what()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_CASE(userDefinedFile) |
|||
{ |
|||
dev::test::userDefinedTest(dev::test::doTransactionTests); |
|||
} |
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue