Merge branch 'develop' into mk_jsonrpc

Conflicts:
	libqethereum/QEthereum.cpp
	libqethereum/QEthereum.h
This commit is contained in:
Marek Kotewicz 2014-10-23 02:51:58 +02:00
commit 3984f6c80c
3 changed files with 101 additions and 36 deletions

View File

@ -42,11 +42,7 @@ void doMyTests(json_spirit::mValue& v);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (argc != 2) g_logVerbosity = 0;
{
cout << "usage: createRandomTest <filename>\n";
return 0;
}
// create random code // create random code
@ -64,14 +60,48 @@ int main(int argc, char *argv[])
string randomCode; string randomCode;
for (int i = 0; i < lengthOfCode; ++i) for (int i = 0; i < lengthOfCode; ++i)
randomCode += toHex(toCompactBigEndian(randGen())); {
uint8_t opcode = randGen();
// read template test file // disregard all invalid commands, except of one (0x10)
if (dev::eth::isValidInstruction(dev::eth::Instruction(opcode)) || opcode == 0x10)
randomCode += toHex(toCompactBigEndian(opcode));
else
i--;
}
const string s =\
"{\n\
\"randomVMtest\": {\n\
\"env\" : {\n\
\"previousHash\" : \"5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6\",\n\
\"currentNumber\" : \"0\",\n\
\"currentGasLimit\" : \"1000000\",\n\
\"currentDifficulty\" : \"256\",\n\
\"currentTimestamp\" : 1,\n\
\"currentCoinbase\" : \"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba\"\n\
},\n\
\"pre\" : {\n\
\"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6\" : {\n\
\"balance\" : \"1000000000000000000\",\n\
\"nonce\" : 0,\n\
\"code\" : \"random\",\n\
\"storage\": {}\n\
}\n\
},\n\
\"exec\" : {\n\
\"address\" : \"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6\",\n\
\"origin\" : \"cd1722f3947def4cf144679da39c4c32bdc35681\",\n\
\"caller\" : \"cd1722f3947def4cf144679da39c4c32bdc35681\",\n\
\"value\" : \"1000000000000000000\",\n\
\"data\" : \"\",\n\
\"gasPrice\" : \"100000000000000\",\n\
\"gas\" : \"10000\"\n\
}\n\
}\n\
}";
mValue v; mValue v;
boost::filesystem::path p(__FILE__);
boost::filesystem::path dir = p.parent_path();
string s = asString(contents(dir.string() + "/randomTestFiller.json"));
read_string(s, v); read_string(s, v);
// insert new random code // insert new random code
@ -80,9 +110,8 @@ int main(int argc, char *argv[])
// execute code in vm // execute code in vm
doMyTests(v); doMyTests(v);
// write new test // stream to output for further handling by the bash script
string filename = argv[1]; cout << json_spirit::write_string(v, true);
writeFile(filename, asBytes(json_spirit::write_string(v, true)));
return 0; return 0;
} }

60
vm.cpp
View File

@ -35,7 +35,7 @@ using namespace dev::test;
FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix.
ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock, _depth) {} ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock, _depth) {}
h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFunc) h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFunc const&)
{ {
Transaction t; Transaction t;
t.value = _endowment; t.value = _endowment;
@ -45,7 +45,7 @@ h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFun
m_s.noteSending(myAddress); m_s.noteSending(myAddress);
m_ms.internal.resize(m_ms.internal.size() + 1); m_ms.internal.resize(m_ms.internal.size() + 1);
auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _init, origin, &suicides, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1); auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _init, origin, &suicides, &m_ms ? &(m_ms.internal.back()) : nullptr, {}, 1);
if (!m_ms.internal.back().from) if (!m_ms.internal.back().from)
m_ms.internal.pop_back(); m_ms.internal.pop_back();
@ -61,7 +61,7 @@ h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFun
return ret; return ret;
} }
bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc, Address _myAddressOverride = Address(), Address _codeAddressOverride = Address()) bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride)
{ {
u256 contractgas = 0xffff; u256 contractgas = 0xffff;
@ -91,7 +91,7 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data,
if (!m_s.addresses().count(myAddress)) if (!m_s.addresses().count(myAddress))
{ {
m_ms.internal.resize(m_ms.internal.size() + 1); m_ms.internal.resize(m_ms.internal.size() + 1);
auto na = m_s.createNewAddress(myAddress, myAddress, balance(myAddress), gasPrice, &contractgas, init, origin, &suicides, &m_ms ? &(m_ms.internal.back()) : nullptr, OnOpFunc(), 1); auto na = m_s.createNewAddress(myAddress, myAddress, balance(myAddress), gasPrice, &contractgas, init, origin, &suicides, &m_ms ? &(m_ms.internal.back()) : nullptr, {}, 1);
if (!m_ms.internal.back().from) if (!m_ms.internal.back().from)
m_ms.internal.pop_back(); m_ms.internal.pop_back();
if (na != myAddress) if (na != myAddress)
@ -512,12 +512,10 @@ void doTests(json_spirit::mValue& v, bool _fillin)
} }
bytes output; bytes output;
u256 gas; VM vm(fev.gas);
try try
{ {
VM vm(fev.gas);
output = vm.go(fev).toVector(); output = vm.go(fev).toVector();
gas = vm.gas(); // Get the remaining gas
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
@ -554,7 +552,7 @@ void doTests(json_spirit::mValue& v, bool _fillin)
o["post"] = mValue(fev.exportState()); o["post"] = mValue(fev.exportState());
o["callcreates"] = fev.exportCallCreates(); o["callcreates"] = fev.exportCallCreates();
o["out"] = "0x" + toHex(output); o["out"] = "0x" + toHex(output);
fev.push(o, "gas", gas); fev.push(o, "gas", vm.gas());
} }
else else
{ {
@ -578,8 +576,44 @@ void doTests(json_spirit::mValue& v, bool _fillin)
else else
BOOST_CHECK(output == fromHex(o["out"].get_str())); BOOST_CHECK(output == fromHex(o["out"].get_str()));
BOOST_CHECK(test.toInt(o["gas"]) == gas); BOOST_CHECK_EQUAL(test.toInt(o["gas"]), vm.gas());
BOOST_CHECK(test.addresses == fev.addresses);
auto& expectedAddrs = test.addresses;
auto& resultAddrs = fev.addresses;
for (auto&& expectedPair : expectedAddrs)
{
auto& expectedAddr = expectedPair.first;
auto resultAddrIt = resultAddrs.find(expectedAddr);
if (resultAddrIt == resultAddrs.end())
BOOST_ERROR("Missing expected address " << expectedAddr);
else
{
auto& expectedState = expectedPair.second;
auto& resultState = resultAddrIt->second;
BOOST_CHECK_MESSAGE(std::get<0>(expectedState) == std::get<0>(resultState), expectedAddr << ": incorrect balance " << std::get<0>(resultState) << ", expected " << std::get<0>(expectedState));
BOOST_CHECK_MESSAGE(std::get<1>(expectedState) == std::get<1>(resultState), expectedAddr << ": incorrect txCount " << std::get<1>(resultState) << ", expected " << std::get<1>(expectedState));
BOOST_CHECK_MESSAGE(std::get<3>(expectedState) == std::get<3>(resultState), expectedAddr << ": incorrect code");
auto&& expectedStore = std::get<2>(expectedState);
auto&& resultStore = std::get<2>(resultState);
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(test.addresses == fev.addresses); // Just to make sure nothing missed
BOOST_CHECK(test.callcreates == fev.callcreates); BOOST_CHECK(test.callcreates == fev.callcreates);
} }
} }
@ -621,11 +655,13 @@ void executeTests(const string& _name)
if (ptestPath == NULL) if (ptestPath == NULL)
{ {
cnote << " could not find environment variable ETHEREUM_TEST_PATH \n"; cnote << " could not find environment variable ETHEREUM_TEST_PATH \n";
testPath = "../../../tests/vmtests"; testPath = "../../../tests";
} }
else else
testPath = ptestPath; testPath = ptestPath;
testPath += "/vmtests";
#ifdef FILL_TESTS #ifdef FILL_TESTS
try try
{ {
@ -654,7 +690,7 @@ void executeTests(const string& _name)
cnote << "Testing VM..." << _name; cnote << "Testing VM..." << _name;
json_spirit::mValue v; json_spirit::mValue v;
string s = asString(contents(testPath + "/" + _name + ".json")); string s = asString(contents(testPath + "/" + _name + ".json"));
BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + _name + ".json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); 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); json_spirit::read_string(s, v);
dev::test::doTests(v, false); dev::test::doTests(v, false);
} }

22
vm.h
View File

@ -44,24 +44,24 @@ class FakeState: public eth::State
{ {
public: public:
/// Execute a contract-creation transaction. /// Execute a contract-creation transaction.
h160 createNewAddress(Address _newAddress, Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = Address(), std::set<Address>* o_suicides = nullptr, eth::Manifest* o_ms = nullptr, eth::OnOpFunc const& _onOp = eth::OnOpFunc(), unsigned _level = 0); h160 createNewAddress(Address _newAddress, Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = {}, std::set<Address>* o_suicides = nullptr, eth::Manifest* o_ms = nullptr, eth::OnOpFunc const& _onOp = {}, unsigned _level = 0);
}; };
class FakeExtVM: public eth::ExtVMFace class FakeExtVM: public eth::ExtVMFace
{ {
public: public:
FakeExtVM() {} FakeExtVM() = default;
FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth = 0); FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth = 0);
u256 store(u256 _n) { return std::get<2>(addresses[myAddress])[_n]; } virtual u256 store(u256 _n) override { return std::get<2>(addresses[myAddress])[_n]; }
void setStore(u256 _n, u256 _v) { std::get<2>(addresses[myAddress])[_n] = _v; } virtual void setStore(u256 _n, u256 _v) override { std::get<2>(addresses[myAddress])[_n] = _v; }
u256 balance(Address _a) { return std::get<0>(addresses[_a]); } virtual u256 balance(Address _a) override { return std::get<0>(addresses[_a]); }
void subBalance(u256 _a) { std::get<0>(addresses[myAddress]) -= _a; } virtual void subBalance(u256 _a) override { std::get<0>(addresses[myAddress]) -= _a; }
u256 txCount(Address _a) { return std::get<1>(addresses[_a]); } virtual u256 txCount(Address _a) override { return std::get<1>(addresses[_a]); }
void suicide(Address _a) { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); } virtual void suicide(Address _a) override { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); }
bytes const& codeAt(Address _a) { return std::get<3>(addresses[_a]); } virtual bytes const& codeAt(Address _a) override { return std::get<3>(addresses[_a]); }
h160 create(u256 _endowment, u256* _gas, bytesConstRef _init, eth::OnOpFunc); virtual h160 create(u256 _endowment, u256* _gas, bytesConstRef _init, eth::OnOpFunc const&) override;
bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, eth::OnOpFunc, Address, Address); virtual bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, eth::OnOpFunc const&, Address, Address) override;
void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data); void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data);
void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code); void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code);
void set(Address _a, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code); void set(Address _a, u256 _myBalance, u256 _myNonce, std::map<u256, u256> const& _storage, bytes const& _code);