diff options
Diffstat (limited to 'state.cpp')
-rw-r--r-- | state.cpp | 150 |
1 files changed, 95 insertions, 55 deletions
@@ -15,81 +15,121 @@ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. */ /** @file state.cpp - * @author Gav Wood <i@gavwood.com> + * @author Christoph Jentzsch <cj@ethdev.com> * @date 2014 * State test functions. */ #include <boost/filesystem/operations.hpp> -#include <secp256k1/secp256k1.h> +#include <boost/test/unit_test.hpp> +#include "JsonSpiritHeaders.h" +#include <libdevcore/CommonIO.h> #include <libethereum/BlockChain.h> #include <libethereum/State.h> +#include <libethereum/ExtVM.h> #include <libethereum/Defaults.h> +#include <libevm/VM.h> +#include "TestHelper.h" + using namespace std; +using namespace json_spirit; using namespace dev; using namespace dev::eth; +using namespace dev::eth; -int stateTest() -{ - cnote << "Testing State..."; - - KeyPair me = sha3("Gav Wood"); - KeyPair myMiner = sha3("Gav's Miner"); -// KeyPair you = sha3("123"); - - Defaults::setDBPath(boost::filesystem::temp_directory_path().string()); - - OverlayDB stateDB = State::openDB(); - BlockChain bc; - State s(myMiner.address(), stateDB); - - cout << bc; - - // Sync up - this won't do much until we use the last state. - s.sync(bc); - - cout << s; - - // Mine to get some ether! - s.commitToMine(bc); - while (!s.mine(100).completed) {} - s.completeMine(); - bc.attemptImport(s.blockData(), stateDB); - - cout << bc; +namespace dev { namespace test { - s.sync(bc); - cout << s; - // Inject a transaction to transfer funds from miner to me. - bytes tx; +void doStateTests(json_spirit::mValue& v, bool _fillin) +{ + cout << "start state test\n"; + for (auto& i: v.get_obj()) { - Transaction t; - t.nonce = s.transactionsFrom(myMiner.address()); - t.value = 1000; // 1e3 wei. - t.type = eth::Transaction::MessageCall; - t.receiveAddress = me.address(); - t.sign(myMiner.secret()); - assert(t.sender() == myMiner.address()); - tx = t.rlp(); + cnote << i.first; + mObject& o = i.second.get_obj(); + + BOOST_REQUIRE(o.count("env") > 0); + BOOST_REQUIRE(o.count("pre") > 0); + BOOST_REQUIRE(o.count("transaction") > 0); + + ImportTest importer(o, _fillin); + + if (_fillin) + { + importer.code = importer.m_statePre.code(importer.m_environment.myAddress); + importer.m_environment.code = &importer.code; + } + + State theState = importer.m_statePre; + bytes tx = importer.m_transaction.rlp(); + bytes output; + + try + { + theState.execute(tx, &output); + } + catch (Exception const& _e) + { + cnote << "state execution did throw an exception: " << diagnostic_information(_e); + } + catch (std::exception const& _e) + { + cnote << "state execution did throw an exception: " << _e.what(); + } + + if (_fillin) + importer.exportTest(output, theState); + else + { + BOOST_REQUIRE(o.count("post") > 0); + BOOST_REQUIRE(o.count("out") > 0); + + // check output + checkOutput(output, o); + + // check addresses + auto expectedAddrs = importer.m_statePost.addresses(); + auto resultAddrs = theState.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 + { + BOOST_CHECK_MESSAGE(importer.m_statePost.balance(expectedAddr) == theState.balance(expectedAddr), expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr)); + BOOST_CHECK_MESSAGE(importer.m_statePost.transactionsFrom(expectedAddr) == theState.transactionsFrom(expectedAddr), expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr)); + BOOST_CHECK_MESSAGE(importer.m_statePost.code(expectedAddr) == theState.code(expectedAddr), expectedAddr << ": incorrect code"); + + checkStorage(importer.m_statePost.storage(expectedAddr), theState.storage(expectedAddr), expectedAddr); + } + } + checkAddresses<map<Address, u256> >(expectedAddrs, resultAddrs); + } } - s.execute(tx); - - cout << s; - - // Mine to get some ether and set in stone. - s.commitToMine(bc); - while (!s.mine(100).completed) {} - s.completeMine(); - bc.attemptImport(s.blockData(), stateDB); +} +} }// Namespace Close - cout << bc; +BOOST_AUTO_TEST_SUITE(StateTests) - s.sync(bc); +BOOST_AUTO_TEST_CASE(stExample) +{ + dev::test::executeTests("stExample", "/StateTests", dev::test::doStateTests); +} - cout << s; +BOOST_AUTO_TEST_CASE(stSystemOperationsTest) +{ + dev::test::executeTests("stSystemOperationsTest", "/StateTests", dev::test::doStateTests); +} - return 0; +BOOST_AUTO_TEST_CASE(tmp) +{ + int currentVerbosity = g_logVerbosity; + g_logVerbosity = 12; + dev::test::executeTests("tmp", "/StateTests", dev::test::doStateTests); + g_logVerbosity = currentVerbosity; } +BOOST_AUTO_TEST_SUITE_END() |