Browse Source

Merge pull request #2003 from winsvega/fuzz

Random Code
cl-refactor
Gav Wood 10 years ago
parent
commit
a61550b139
  1. 7
      test/TestHelper.cpp
  2. 1
      test/TestHelper.h
  3. 7
      test/fuzzTesting/CMakeLists.txt
  4. 204
      test/fuzzTesting/createRandomStateTest.cpp
  5. 224
      test/fuzzTesting/fuzzHelper.cpp
  6. 97
      test/fuzzTesting/fuzzHelper.h
  7. 2
      test/libethereum/blockchain.cpp

7
test/TestHelper.cpp

@ -328,7 +328,7 @@ void ImportTest::exportTest(bytes const& _output, State const& _statePost)
{ {
// export output // export output
m_TestObject["out"] = _output.size() > 4096 ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add); m_TestObject["out"] = (_output.size() > 4096 && !Options::get().fulloutput) ? "#" + toString(_output.size()) : toHex(_output, 2, HexPrefix::Add);
// export logs // export logs
m_TestObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries()); m_TestObject["logs"] = exportLog(_statePost.pending().size() ? _statePost.log(0) : LogEntries());
@ -588,7 +588,7 @@ void userDefinedTest(std::function<void(json_spirit::mValue&, bool)> doTests)
oSingleTest[pos->first] = pos->second; oSingleTest[pos->first] = pos->second;
json_spirit::mValue v_singleTest(oSingleTest); json_spirit::mValue v_singleTest(oSingleTest);
doTests(v_singleTest, false); doTests(v_singleTest, test::Options::get().fillTests);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
@ -760,6 +760,8 @@ Options::Options()
else else
singleTestName = std::move(name1); singleTestName = std::move(name1);
} }
else if (arg == "--fulloutput")
fulloutput = true;
} }
} }
@ -769,7 +771,6 @@ Options const& Options::get()
return instance; return instance;
} }
LastHashes lastHashes(u256 _currentBlockNumber) LastHashes lastHashes(u256 _currentBlockNumber)
{ {
LastHashes ret; LastHashes ret;

1
test/TestHelper.h

@ -184,6 +184,7 @@ public:
bool stats = false; ///< Execution time stats bool stats = false; ///< Execution time stats
std::string statsOutFile; ///< Stats output file. "out" for standard output std::string statsOutFile; ///< Stats output file. "out" for standard output
bool checkState = false;///< Throw error when checking test states bool checkState = false;///< Throw error when checking test states
bool fulloutput = false;///< Replace large output to just it's length
/// Test selection /// Test selection
/// @{ /// @{

7
test/fuzzTesting/CMakeLists.txt

@ -9,10 +9,13 @@ include_directories(${CRYPTOPP_INCLUDE_DIRS})
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
add_executable(createRandomVMTest "./createRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp") add_executable(createRandomVMTest "./createRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp")
add_executable(createRandomStateTest "./createRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp") add_executable(createRandomStateTest "./createRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp" "fuzzHelper.cpp")
add_executable(checkRandomVMTest "./checkRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp") add_executable(checkRandomVMTest "./checkRandomVMTest.cpp" "../libevm/vm.cpp" "../TestHelper.cpp" "../Stats.cpp" )
add_executable(checkRandomStateTest "./checkRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp") add_executable(checkRandomStateTest "./checkRandomStateTest.cpp" "../TestHelper.cpp" "../Stats.cpp")
list(APPEND SRCS "./fuzzHelper.cpp")
add_sources(${SRCS})
target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
target_link_libraries(createRandomVMTest ethereum) target_link_libraries(createRandomVMTest ethereum)
target_link_libraries(createRandomVMTest ethcore) target_link_libraries(createRandomVMTest ethcore)

204
test/fuzzTesting/createRandomStateTest.cpp

@ -37,24 +37,88 @@
#include <libevm/VMFactory.h> #include <libevm/VMFactory.h>
#include <test/libevm/vm.h> #include <test/libevm/vm.h>
#include <test/TestHelper.h> #include <test/TestHelper.h>
#include <test/fuzzTesting/fuzzHelper.h>
using namespace std; using namespace std;
using namespace json_spirit; using namespace json_spirit;
using namespace dev; using namespace dev;
void doStateTests(json_spirit::mValue& _v); void doStateTests(json_spirit::mValue& _v);
void doChristophAlgo();
void doRandomCodeAlgo();
string const c_testExample = R"(
{
"randomStatetest" : {
"env" : {
"currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
"currentDifficulty" : "5623894562375",
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0",
"code" : "0x6001600101600055",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "46",
"code" : "0x6000355415600957005b60203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x42",
"gasLimit" : "400000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
}
}
)";
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{
for (auto i = 0; i < argc; ++i)
{
auto arg = std::string{argv[i]};
dev::test::Options& options = const_cast<dev::test::Options&>(dev::test::Options::get());
if (arg == "--fulloutput")
options.fulloutput = true;
}
//doChristophAlgo();
doRandomCodeAlgo();
return 0;
}
void doChristophAlgo()
{ {
g_logVerbosity = 0; g_logVerbosity = 0;
// create random code // create random code
boost::random::mt19937 gen; boost::random::mt19937 gen;
auto now = chrono::steady_clock::now().time_since_epoch(); auto now = chrono::steady_clock::now().time_since_epoch();
auto timeSinceEpoch = chrono::duration_cast<chrono::nanoseconds>(now).count(); auto timeSinceEpoch = chrono::duration_cast<chrono::nanoseconds>(now).count();
gen.seed(static_cast<unsigned int>(timeSinceEpoch)); gen.seed(static_cast<unsigned int>(timeSinceEpoch));
// set min and max length of the random evm code // set min and max length of the random evm code
boost::random::uniform_int_distribution<> lengthOfCodeDist(8, 24); boost::random::uniform_int_distribution<> lengthOfCodeDist(8, 24);
boost::random::uniform_int_distribution<> reasonableInputValuesSize(0, 7); boost::random::uniform_int_distribution<> reasonableInputValuesSize(0, 7);
@ -77,18 +141,16 @@ int main(int argc, char *argv[])
reasonableInputValues.push_back(u256("0x945304eb96065b2a98b57a48a06ae28d285a71b5")); reasonableInputValues.push_back(u256("0x945304eb96065b2a98b57a48a06ae28d285a71b5"));
reasonableInputValues.push_back(randGenUniformInt()); reasonableInputValues.push_back(randGenUniformInt());
int lengthOfCode = lengthOfCodeDist(gen); int lengthOfCode = lengthOfCodeDist(gen);
string randomCode; string randomCode;
for (int i = 0; i < lengthOfCode; ++i) for (int i = 0; i < lengthOfCode; ++i)
{ {
// pre-fill stack to avoid that most of the test fail with a stackunderflow // pre-fill stack to avoid that most of the test fail with a stackunderflow
if (i < 8 && (randGen() < 192)) if (i < 8 && (randGen() < 192))
{ {
randomCode += randGen() < 32 ? toHex(toCompactBigEndian((uint8_t)randGenBlockInfoOpcode())) : "7f" + toHex(reasonableInputValues[randGenInputValue()]); randomCode += randGen() < 32 ? toHex(toCompactBigEndian((uint8_t)randGenBlockInfoOpcode())) : "7f" + toHex(reasonableInputValues[randGenInputValue()]);
continue; continue;
} }
uint8_t opcode = randGen(); uint8_t opcode = randGen();
// disregard all invalid commands, except of one (0x0c) // disregard all invalid commands, except of one (0x0c)
if ((dev::eth::isValidInstruction(dev::eth::Instruction(opcode)) || (randGen() > 250))) if ((dev::eth::isValidInstruction(dev::eth::Instruction(opcode)) || (randGen() > 250)))
@ -97,74 +159,58 @@ int main(int argc, char *argv[])
i--; i--;
} }
string const s = R"(
{
"randomStatetest" : {
"env" : {
"currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5",
"currentDifficulty" : "5623894562375",
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0",
"code" : "0x6001600101600055",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "46",
"code" : "0x6000355415600957005b60203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x42",
"gasLimit" : "400000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
}
}
)";
mValue v; mValue v;
read_string(s, v); read_string(c_testExample, v);
// insert new random code // insert new random code
v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode + (randGen() > 128 ? "55" : "") + (randGen() > 128 ? "60005155" : ""); v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode + (randGen() > 128 ? "55" : "") + (randGen() > 128 ? "60005155" : "");
// insert new data in tx // insert new data in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["data"] = "0x" + randomCode; v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["data"] = "0x" + randomCode;
// insert new value in tx // insert new value in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["value"] = toString(randGenUniformInt()); v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["value"] = toString(randGenUniformInt());
// insert new gasLimit in tx // insert new gasLimit in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["gasLimit"] = "0x" + toHex(toCompactBigEndian((int)randGenUniformInt())); v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["gasLimit"] = "0x" + toHex(toCompactBigEndian((int)randGenUniformInt()));
// fill test
doStateTests(v);
// stream to output for further handling by the bash script
cout << json_spirit::write_string(v, true);
}
void doRandomCodeAlgo()
{
g_logVerbosity = 0;
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.addAddress(Address("0xffffffffffffffffffffffffffffffffffffffff"));
options.addAddress(Address("0x1000000000000000000000000000000000000000"));
options.addAddress(Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87")); //coinbase
options.addAddress(Address("0x945304eb96065b2a98b57a48a06ae28d285a71b5"));
options.addAddress(Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"));
options.smartCodeProbability = 35;
string randomCode = dev::test::RandomCode::generate(10, options);
string randomData = dev::test::RandomCode::generate(10, options);
mValue v;
read_string(c_testExample, v);
// insert new random code
v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode;
// insert new data in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["data"] = "0x" + randomData;
// insert new value in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["value"] = dev::test::RandomCode::randomUniIntHex();
// insert new gasLimit in tx
v.get_obj().find("randomStatetest")->second.get_obj().find("transaction")->second.get_obj()["gasLimit"] = dev::test::RandomCode::randomUniIntHex();
// fill test // fill test
doStateTests(v); doStateTests(v);
// stream to output for further handling by the bash script // stream to output for further handling by the bash script
cout << json_spirit::write_string(v, true); cout << json_spirit::write_string(v, true);
return 0;
} }
void doStateTests(json_spirit::mValue& _v) void doStateTests(json_spirit::mValue& _v)
@ -179,30 +225,34 @@ void doStateTests(json_spirit::mValue& _v)
assert(o.count("env") > 0); assert(o.count("env") > 0);
assert(o.count("pre") > 0); assert(o.count("pre") > 0);
assert(o.count("transaction") > 0); assert(o.count("transaction") > 0);
test::ImportTest importer(o, true);
eth::State theState = importer.m_statePre;
bytes output; bytes output;
try try
{ {
output = theState.execute(test::lastHashes(importer.m_environment.currentBlock.number), importer.m_transaction).output; test::ImportTest importer(o, true);
} eth::State theState = importer.m_statePre;
catch (Exception const& _e) try
{ {
cnote << "state execution did throw an exception: " << diagnostic_information(_e); output = theState.execute(test::lastHashes(importer.m_environment.currentBlock.number), importer.m_transaction).output;
theState.commit(); }
} catch (Exception const& _e)
catch (std::exception const& _e) {
{ cnote << "state execution did throw an exception: " << diagnostic_information(_e);
cnote << "state execution did throw an exception: " << _e.what(); theState.commit();
} }
catch (std::exception const& _e)
{
cnote << "state execution did throw an exception: " << _e.what();
}
#if ETH_FATDB #if ETH_FATDB
importer.exportTest(output, theState); importer.exportTest(output, theState);
#else #else
cout << "You can not fill tests when FATDB is switched off"; cout << "You can not fill tests when FATDB is switched off";
#endif #endif
}
catch(...)
{
cnote << "Error filling test, probably...";
}
} }
} }

224
test/fuzzTesting/fuzzHelper.cpp

@ -0,0 +1,224 @@
/*
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);
boostIntGenerator RandomCode::randOpCodeGen = boostIntGenerator(gen, opCodeDist);
boostIntGenerator RandomCode::randOpLengGen = boostIntGenerator(gen, opLengDist);
boostIntGenerator RandomCode::randUniIntGen = boostIntGenerator(gen, uniIntDist);
std::string RandomCode::rndByteSequence(int _length, SizeStrictness _sizeType)
{
refreshSeed();
std::string hash;
_length = (_sizeType == SizeStrictness::Strict) ? std::max(1, _length) : randomUniInt() % _length;
for (auto i = 0; i < _length; i++)
{
uint8_t byte = randOpCodeGen();
hash += toCompactHex(byte);
}
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_first_of("INVALID_INSTRUCTION") > 0)
{
//Byte code is yet not implemented
if (_options.useUndefinedOpCodes == false)
{
i--;
continue;
}
}
else
code += fillArguments((dev::eth::Instruction) opcode, _options);
std::string byte = toCompactHex(opcode);
code += (byte == "") ? "00" : byte;
}
return code;
}
std::string RandomCode::randomUniIntHex()
{
refreshSeed();
return "0x" + toCompactHex((int)randUniIntGen());
}
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)
{
switch (_opcode)
{
case dev::eth::Instruction::CALL:
//(CALL gaslimit address value memstart1 memlen1 memstart2 memlen2)
code += getPushCode(randUniIntGen() % 32); //memlen2
code += getPushCode(randUniIntGen() % 32); //memstart2
code += getPushCode(randUniIntGen() % 32); //memlen1
code += getPushCode(randUniIntGen() % 32); //memlen1
code += getPushCode(randUniIntGen()); //value
code += getPushCode(toString(_options.getRandomAddress()));//address
code += getPushCode(randUniIntGen()); //gaslimit
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;
std::cerr << "Testing Random Code: ";
try
{
code = dev::test::RandomCode::generate(10);
}
catch(...)
{
BOOST_ERROR("Exception thrown when generating random code!");
}
std::cerr << code;
}
BOOST_AUTO_TEST_SUITE_END()
}
}

97
test/fuzzTesting/fuzzHelper.h

@ -0,0 +1,97 @@
/*
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::random::variate_generator<boost::mt19937&, boostIntDistrib > boostIntGenerator;
typedef boost::random::variate_generator<boost::mt19937&, boostDescreteDistrib > boostWeightGenerator;
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
};
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 uniForm Int with reasonable value 0..0x7fffffff
static std::string randomUniIntHex();
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 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 boostIntGenerator randUniIntGen; ///< Generate random UniformInt from uniIntDist
static boostIntGenerator randOpCodeGen; ///< Generate random value from opCodeDist
static boostIntGenerator randOpLengGen; ///< Generate random length from opLengDist
};
}
}

2
test/libethereum/blockchain.cpp

@ -19,7 +19,7 @@
* @date 2015 * @date 2015
* block test functions. * block test functions.
*/ */
#include "test/fuzzTesting/fuzzHelper.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <libdevcore/FileSystem.h> #include <libdevcore/FileSystem.h>
#include <libdevcore/TransientDirectory.h> #include <libdevcore/TransientDirectory.h>

Loading…
Cancel
Save