Browse Source

fix spaces->tab, detailed callcreate check

cl-refactor
CJentzsch 10 years ago
parent
commit
f401d34ac8
  1. 474
      test/checkRandomTest.cpp

474
test/checkRandomTest.cpp

@ -1,18 +1,18 @@
/* /*
This file is part of cpp-ethereum. This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful, cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file checkRandomTest.cpp /** @file checkRandomTest.cpp
* @author Christoph Jentzsch <jentzsch.simulationsoftware@gmail.com> * @author Christoph Jentzsch <jentzsch.simulationsoftware@gmail.com>
@ -36,244 +36,262 @@ bool doVMTest(mValue& v);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
g_logVerbosity = 0; g_logVerbosity = 0;
bool ret = false; bool ret = false;
try try
{ {
mValue v; mValue v;
string s; string s;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
s += argv[i]; s += argv[i];
if (asserts(s.length() > 0)) if (asserts(s.length() > 0))
{ {
cout << "Content of argument is empty\n"; cout << "Content of argument is empty\n";
return 1; return 1;
} }
read_string(s, v); read_string(s, v);
ret = doVMTest(v); ret = doVMTest(v);
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
cout << "Failed test with Exception: " << diagnostic_information(_e) << endl; cout << "Failed test with Exception: " << diagnostic_information(_e) << endl;
ret = false; ret = false;
} }
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
cout << "Failed test with Exception: " << _e.what() << endl; cout << "Failed test with Exception: " << _e.what() << endl;
ret = false; ret = false;
} }
return ret; return ret;
} }
bool doVMTest(mValue& v) bool doVMTest(mValue& v)
{ {
eth::VMFactory::setKind(eth::VMKind::JIT); eth::VMFactory::setKind(eth::VMKind::JIT);
for (auto& i: v.get_obj()) for (auto& i: v.get_obj())
{ {
cnote << i.first; cnote << i.first;
mObject& o = i.second.get_obj(); mObject& o = i.second.get_obj();
assert(o.count("env") > 0); assert(o.count("env") > 0);
assert(o.count("pre") > 0); assert(o.count("pre") > 0);
assert(o.count("exec") > 0); assert(o.count("exec") > 0);
FakeExtVM fev; FakeExtVM fev;
fev.importEnv(o["env"].get_obj()); fev.importEnv(o["env"].get_obj());
fev.importState(o["pre"].get_obj()); fev.importState(o["pre"].get_obj());
fev.importExec(o["exec"].get_obj()); fev.importExec(o["exec"].get_obj());
if (fev.code.empty()) if (fev.code.empty())
{ {
fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress)); fev.thisTxCode = get<3>(fev.addresses.at(fev.myAddress));
fev.code = fev.thisTxCode; fev.code = fev.thisTxCode;
} }
bytes output; bytes output;
u256 gas; u256 gas;
bool vmExceptionOccured = false; bool vmExceptionOccured = false;
try try
{ {
auto vm = eth::VMFactory::create(fev.gas); auto vm = eth::VMFactory::create(fev.gas);
output = vm->go(fev, fev.simpleTrace()).toBytes(); output = vm->go(fev, fev.simpleTrace()).toBytes();
gas = vm->gas(); gas = vm->gas();
} }
catch (eth::VMException const& _e) catch (eth::VMException)
{ {
cnote << "Safe VM Exception"; cnote << "Safe VM Exception";
vmExceptionOccured = true; vmExceptionOccured = true;
} }
catch (Exception const& _e) catch (Exception const& _e)
{ {
cnote << "VM did throw an exception: " << diagnostic_information(_e); cnote << "VM did throw an exception: " << diagnostic_information(_e);
cnote << "Failed VM Test with Exception: " << _e.what(); cnote << "Failed VM Test with Exception: " << _e.what();
return 1; return 1;
} }
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
cnote << "VM did throw an exception: " << _e.what(); cnote << "VM did throw an exception: " << _e.what();
cnote << "Failed VM Test with Exception: " << _e.what(); cnote << "Failed VM Test with Exception: " << _e.what();
return 1; return 1;
} }
// delete null entries in storage for the sake of comparison // delete null entries in storage for the sake of comparison
for (auto &a: fev.addresses) for (auto &a: fev.addresses)
{ {
vector<u256> keystoDelete; vector<u256> keystoDelete;
for (auto &s: get<2>(a.second)) for (auto &s: get<2>(a.second))
{ {
if (s.second == 0) if (s.second == 0)
keystoDelete.push_back(s.first); keystoDelete.push_back(s.first);
} }
for (auto const key: keystoDelete ) for (auto const key: keystoDelete )
{ {
get<2>(a.second).erase(key); get<2>(a.second).erase(key);
} }
} }
if (o.count("post") > 0) // No exceptions expected if (o.count("post") > 0) // No exceptions expected
{ {
if (asserts(!vmExceptionOccured) || asserts(o.count("post") > 0) || asserts(o.count("callcreates") > 0) || asserts(o.count("out") > 0) || asserts(o.count("gas") > 0) || asserts(o.count("logs") > 0)) if (asserts(!vmExceptionOccured) || asserts(o.count("post") > 0) || asserts(o.count("callcreates") > 0) || asserts(o.count("out") > 0) || asserts(o.count("gas") > 0) || asserts(o.count("logs") > 0))
return 1; return 1;
dev::test::FakeExtVM test; dev::test::FakeExtVM test;
test.importState(o["post"].get_obj()); test.importState(o["post"].get_obj());
test.importCallCreates(o["callcreates"].get_array()); test.importCallCreates(o["callcreates"].get_array());
test.sub.logs = importLog(o["logs"].get_array()); test.sub.logs = importLog(o["logs"].get_array());
//checkOutput(output, o); //checkOutput(output, o);
int j = 0; int j = 0;
if (o["out"].type() == array_type) if (o["out"].type() == array_type)
for (auto const& d: o["out"].get_array()) for (auto const& d: o["out"].get_array())
{ {
if (asserts(output[j] == toInt(d))) if (asserts(output[j] == toInt(d)))
{ {
cout << "Output byte [" << j << "] different!"; cout << "Output byte [" << j << "] different!";
return 1; return 1;
} }
++j; ++j;
} }
else if (o["out"].get_str().find("0x") == 0) else if (o["out"].get_str().find("0x") == 0)
{ {
if (asserts(output == fromHex(o["out"].get_str().substr(2)))) if (asserts(output == fromHex(o["out"].get_str().substr(2))))
return 1; return 1;
} }
else else
{ {
if (asserts(output == fromHex(o["out"].get_str()))) if (asserts(output == fromHex(o["out"].get_str())))
return 1; return 1;
} }
if (asserts(toInt(o["gas"]) == gas)) if (asserts(toInt(o["gas"]) == gas))
return 1; return 1;
auto& expectedAddrs = test.addresses; auto& expectedAddrs = test.addresses;
auto& resultAddrs = fev.addresses; auto& resultAddrs = fev.addresses;
for (auto&& expectedPair : expectedAddrs) for (auto&& expectedPair : expectedAddrs)
{ {
auto& expectedAddr = expectedPair.first; auto& expectedAddr = expectedPair.first;
auto resultAddrIt = resultAddrs.find(expectedAddr); auto resultAddrIt = resultAddrs.find(expectedAddr);
if (resultAddrIt == resultAddrs.end()) if (resultAddrIt == resultAddrs.end())
{ {
cout << "Missing expected address " << expectedAddr; cout << "Missing expected address " << expectedAddr;
return 1; return 1;
} }
else else
{ {
auto& expectedState = expectedPair.second; auto& expectedState = expectedPair.second;
auto& resultState = resultAddrIt->second; auto& resultState = resultAddrIt->second;
if (asserts(std::get<0>(expectedState) == std::get<0>(resultState))) if (asserts(std::get<0>(expectedState) == std::get<0>(resultState)))
{ {
cout << expectedAddr << ": incorrect balance " << std::get<0>(resultState) << ", expected " << std::get<0>(expectedState); cout << expectedAddr << ": incorrect balance " << std::get<0>(resultState) << ", expected " << std::get<0>(expectedState);
return 1; return 1;
} }
if (asserts(std::get<1>(expectedState) == std::get<1>(resultState))) if (asserts(std::get<1>(expectedState) == std::get<1>(resultState)))
{ {
cout << expectedAddr << ": incorrect txCount " << std::get<1>(resultState) << ", expected " << std::get<1>(expectedState); cout << expectedAddr << ": incorrect txCount " << std::get<1>(resultState) << ", expected " << std::get<1>(expectedState);
return 1; return 1;
} }
if (asserts(std::get<3>(expectedState) == std::get<3>(resultState))) if (asserts(std::get<3>(expectedState) == std::get<3>(resultState)))
{ {
cout << expectedAddr << ": incorrect code"; cout << expectedAddr << ": incorrect code";
return 1; return 1;
} }
//checkStorage(std::get<2>(expectedState), std::get<2>(resultState), expectedAddr); //checkStorage(std::get<2>(expectedState), std::get<2>(resultState), expectedAddr);
for (auto&& expectedStorePair : std::get<2>(expectedState)) for (auto&& expectedStorePair : std::get<2>(expectedState))
{ {
auto& expectedStoreKey = expectedStorePair.first; auto& expectedStoreKey = expectedStorePair.first;
auto resultStoreIt = std::get<2>(resultState).find(expectedStoreKey); auto resultStoreIt = std::get<2>(resultState).find(expectedStoreKey);
if (resultStoreIt == std::get<2>(resultState).end()) if (resultStoreIt == std::get<2>(resultState).end())
{ {
cout << expectedAddr << ": missing store key " << expectedStoreKey << endl; cout << expectedAddr << ": missing store key " << expectedStoreKey << endl;
return 1; return 1;
} }
else else
{ {
auto& expectedStoreValue = expectedStorePair.second; auto& expectedStoreValue = expectedStorePair.second;
auto& resultStoreValue = resultStoreIt->second; auto& resultStoreValue = resultStoreIt->second;
if (asserts(expectedStoreValue == resultStoreValue)) if (asserts(expectedStoreValue == resultStoreValue))
{ {
cout << expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue << endl; cout << expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue << endl;
return 1; return 1;
} }
} }
} }
if (assertsEqual(std::get<2>(resultState).size(), std::get<2>(expectedState).size())) if (assertsEqual(std::get<2>(resultState).size(), std::get<2>(expectedState).size()))
return 1; return 1;
for (auto&& resultStorePair: std::get<2>(resultState)) for (auto&& resultStorePair: std::get<2>(resultState))
{ {
if (!std::get<2>(expectedState).count(resultStorePair.first)) if (!std::get<2>(expectedState).count(resultStorePair.first))
{ {
cout << expectedAddr << ": unexpected store key " << resultStorePair.first << endl; cout << expectedAddr << ": unexpected store key " << resultStorePair.first << endl;
return 1; return 1;
} }
} }
} }
} }
//checkAddresses<std::map<Address, std::tuple<u256, u256, std::map<u256, u256>, bytes> > >(test.addresses, fev.addresses); //checkAddresses<std::map<Address, std::tuple<u256, u256, std::map<u256, u256>, bytes> > >(test.addresses, fev.addresses);
for (auto& resultPair : fev.addresses) for (auto& resultPair : fev.addresses)
{ {
auto& resultAddr = resultPair.first; auto& resultAddr = resultPair.first;
auto expectedAddrIt = test.addresses.find(resultAddr); auto expectedAddrIt = test.addresses.find(resultAddr);
if (expectedAddrIt == test.addresses.end()) if (expectedAddrIt == test.addresses.end())
{ {
cout << "Missing result address " << resultAddr << endl; cout << "Missing result address " << resultAddr << endl;
return 1; return 1;
} }
} }
if (asserts(test.addresses == fev.addresses)) if (asserts(test.addresses == fev.addresses))
return 1; return 1;
if (asserts(test.callcreates == fev.callcreates)) if (asserts(test.callcreates == fev.callcreates))
return 1; return 1;
//checkLog(fev.sub.logs, test.sub.logs); //checkCallCreates(fev.callcreates, test.callcreates);
{ {
if (assertsEqual(fev.sub.logs.size(), test.sub.logs.size())) if (assertsEqual(test.callcreates.size(), fev.callcreates.size()))
return 1; return 1;
for (size_t i = 0; i < fev.sub.logs.size(); ++i) for (size_t i = 0; i < test.callcreates.size(); ++i)
{ {
if (assertsEqual(fev.sub.logs[i].address, test.sub.logs[i].address)) if (asserts(test.callcreates[i].data() == fev.callcreates[i].data()))
return 1; return 1;
if (assertsEqual(fev.sub.logs[i].topics, test.sub.logs[i].topics)) if (asserts(test.callcreates[i].receiveAddress() == fev.callcreates[i].receiveAddress()))
return 1; return 1;
if (asserts(fev.sub.logs[i].data == test.sub.logs[i].data)) if (asserts(test.callcreates[i].gas() == fev.callcreates[i].gas()))
return 1; return 1;
} if (asserts(test.callcreates[i].value() == fev.callcreates[i].value()))
} return 1;
}
}
} //checkLog(fev.sub.logs, test.sub.logs);
else // Exception expected {
{ if (assertsEqual(fev.sub.logs.size(), test.sub.logs.size()))
if (asserts(vmExceptionOccured)) return 1;
return 1;
} for (size_t i = 0; i < fev.sub.logs.size(); ++i)
} {
// test passed if (assertsEqual(fev.sub.logs[i].address, test.sub.logs[i].address))
return 0; return 1;
if (assertsEqual(fev.sub.logs[i].topics, test.sub.logs[i].topics))
return 1;
if (asserts(fev.sub.logs[i].data == test.sub.logs[i].data))
return 1;
}
}
}
else // Exception expected
{
if (asserts(vmExceptionOccured))
return 1;
}
}
// test passed
return 0;
} }

Loading…
Cancel
Save