From 052e28705cbe1d0373b787602376d5dc10f8c9f2 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Fri, 18 Apr 2014 11:46:26 -0700 Subject: [PATCH 01/13] Changed spaces to tabs to be compliant with coding standards document. --- CMakeLists.txt | 104 ++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b95d9fbe3..80dc424f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,54 +86,54 @@ endif () if (${TARGET_PLATFORM} STREQUAL "w64") else () - # Look for available Crypto++ version and if it is >= 5.6.2 - find_path(ID cryptlib.h - /usr/include/cryptopp - /usr/include/crypto++ - /usr/local/include/cryptopp - /usr/local/include/crypto++ - /opt/local/include/cryptopp - /opt/local/include/crypto++ - ) - find_library(LS NAMES cryptoppeth cryptopp - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - ) - - if(ID AND LS) - message(STATUS "Found Crypto++: ${ID}, ${LS}") - set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h) - if(EXISTS ${_CRYPTOPP_VERSION_HEADER}) - file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") - string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION}) - if(${_CRYPTOPP_VERSION} LESS 562) - message(STATUS "System Crypto++ version found is smaller than 5.6.2.") - else() - set(CRYPTOPP_INCLUDE_DIR ${ID} CACHE FILEPATH "" FORCE) - set(CRYPTOPP_LIBRARIES ${LS} CACHE FILEPATH "" FORCE) - set(CRYPTOPP_FOUND TRUE) - message(STATUS "System Crypto++ found and version greater or equal to 5.6.2") - endif() - endif() - endif() - - if(NOT CRYPTOPP_FOUND) - set(CRYPTOPP_INCLUDE_DIR "../cryptopp562" CACHE FILEPATH "" FORCE) - find_library(LSLOC NAMES cryptoppeth cryptopp - PATHS ../cryptopp562 - NO_DEFAULT_PATH - ) - set(CRYPTOPP_LIBRARIES ${LSLOC} CACHE FILEPATH "" FORCE) - message(STATUS "System Crypto++ not found, broken or too old. We use ${LSLOC}") - endif() - - # Not really worth caching. We want to reevaluate anyway. - mark_as_advanced(CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARIES) - - # Always "found", given last block. - include_directories(${CRYPTOPP_INCLUDE_DIR}) + # Look for available Crypto++ version and if it is >= 5.6.2 + find_path(ID cryptlib.h + /usr/include/cryptopp + /usr/include/crypto++ + /usr/local/include/cryptopp + /usr/local/include/crypto++ + /opt/local/include/cryptopp + /opt/local/include/crypto++ + ) + find_library(LS NAMES cryptoppeth cryptopp + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + ) + + if(ID AND LS) + message(STATUS "Found Crypto++: ${ID}, ${LS}") + set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h) + if(EXISTS ${_CRYPTOPP_VERSION_HEADER}) + file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") + string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION}) + if(${_CRYPTOPP_VERSION} LESS 562) + message(STATUS "System Crypto++ version found is smaller than 5.6.2.") + else() + set(CRYPTOPP_INCLUDE_DIR ${ID} CACHE FILEPATH "" FORCE) + set(CRYPTOPP_LIBRARIES ${LS} CACHE FILEPATH "" FORCE) + set(CRYPTOPP_FOUND TRUE) + message(STATUS "System Crypto++ found and version greater or equal to 5.6.2") + endif() + endif() + endif() + + if(NOT CRYPTOPP_FOUND) + set(CRYPTOPP_INCLUDE_DIR "../cryptopp562" CACHE FILEPATH "" FORCE) + find_library(LSLOC NAMES cryptoppeth cryptopp + PATHS ../cryptopp562 + NO_DEFAULT_PATH + ) + set(CRYPTOPP_LIBRARIES ${LSLOC} CACHE FILEPATH "" FORCE) + message(STATUS "System Crypto++ not found, broken or too old. We use ${LSLOC}") + endif() + + # Not really worth caching. We want to reevaluate anyway. + mark_as_advanced(CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARIES) + + # Always "found", given last block. + include_directories(${CRYPTOPP_INCLUDE_DIR}) if(NOT APPLE) link_directories(${CRYPTOPP_LIBRARIES}) @@ -154,12 +154,12 @@ add_subdirectory(test) add_subdirectory(eth) if ("${TARGET_PLATFORM}" STREQUAL "w64") else () - add_subdirectory(neth) + add_subdirectory(neth) endif () if (NOT HEADLESS) - add_subdirectory(libqethereum) - add_subdirectory(alethzero) - add_subdirectory(walleth) + add_subdirectory(libqethereum) + add_subdirectory(alethzero) + add_subdirectory(walleth) endif () enable_testing() From a6256a5c045513a23b069efe94f944e6ad003414 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Fri, 18 Apr 2014 11:54:30 -0700 Subject: [PATCH 02/13] Added check for the leveldb and miniupnpc dev libraries --- CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80dc424f5..57f018dba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,54 @@ else () if(NOT APPLE) link_directories(${CRYPTOPP_LIBRARIES}) endif() + + find_path( LEVELDB_ID leveldb/db.h + /usr/include + /usr/local/include + ) + if ( LEVELDB_ID ) + message(STATUS "Found LevelDB Headers") + else () + message(FATAL_ERROR "Failed to find the LevelDB headers") + endif () + + # Check for accessory dev libraries leveldb and miniupnpc + find_library( LEVELDB_LS NAMES leveldb + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + if ( LEVELDB_LS ) + message(STATUS "Found LevelDB Library: ${LEVELDB_LS}") + else () + message(FATAL_ERROR "Failed to find the LevelDB Library!") + endif () + + find_path( MINIUPNPC_ID miniupnpc/miniwget.h + /usr/include/miniupnpc + /usr/local/include/miniupnpc + ) + if ( MINIUPNPC_ID ) + message(STATUS "Found miniupnpc headers") + else () + message(FATAL_ERROR "Failed to find the miniupnpc headers!") + endif () + + find_library( MINIUPNPC_LS NAMES miniupnpc + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + if ( MINIUPNPC_LS ) + message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}") + else () + message(FATAL_ERROR "Failed to find the miniupnpc library!") + endif () + endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") From c7a1c2b0d28461c541c900ec6d020358a5f12d41 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 09:30:44 -0700 Subject: [PATCH 03/13] converted RLP test to a separate boost test case. --- test/main.cpp | 1 - test/rlp.cpp | 87 +++++++++++++++++++++++---------------------------- 2 files changed, 40 insertions(+), 48 deletions(-) diff --git a/test/main.cpp b/test/main.cpp index 4cfb71ced..fc8eecd52 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -46,7 +46,6 @@ BOOST_AUTO_TEST_CASE(basic_tests) int r = 0; r += hexPrefixTest(); - r += rlpTest(); r += trieTest(); r += vmTest(); r += cryptoTest(); // TODO: Put in tests repo. diff --git a/test/rlp.cpp b/test/rlp.cpp index f6c244423..e13965daf 100644 --- a/test/rlp.cpp +++ b/test/rlp.cpp @@ -24,66 +24,59 @@ #include "JsonSpiritHeaders.h" #include #include +#include + using namespace std; using namespace eth; namespace js = json_spirit; -namespace eth -{ - -template <> class UnitTest<2> +namespace eth { -public: - static void buildRLP(js::mValue& _v, RLPStream& _rlp) + namespace test { - if (_v.type() == js::array_type) + static void buildRLP(js::mValue& _v, RLPStream& _rlp) { - 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); - } - } - - int operator()() - { - js::mValue v; - string s = asString(contents("../../tests/rlptest.json")); - js::read_string(s, v); - bool passed = true; - for (auto& i: v.get_obj()) - { - js::mObject& o = i.second.get_obj(); - cnote << i.first; - RLPStream s; - buildRLP(o["in"], s); - if (!o["out"].is_null() && o["out"].get_str() != toHex(s.out())) + if (_v.type() == js::array_type) { - cwarn << "Test failed."; - cwarn << "Test says:" << o["out"].get_str(); - cwarn << "Impl says:" << toHex(s.out()); - passed = false; + 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); } } - return passed ? 0 : 1; } +} -}; - -} -int rlpTest() +BOOST_AUTO_TEST_CASE(rlp_test) { cnote << "Testing RLP..."; - return UnitTest<2>()(); + js::mValue v; + string s = asString(contents("../../tests/rlptest.json")); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'rlptest.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; + RLPStream s; + eth::test::buildRLP(o["in"], s); + BOOST_REQUIRE(!o["out"].is_null()); + BOOST_CHECK(o["out"].get_str() == toHex(s.out()) ); + } + } + + + + From 29cbfec31c060565c3c1ef8c620429e5cc16c699 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 09:31:37 -0700 Subject: [PATCH 04/13] Converted the hexPrefix test to a separate boost test case. --- test/hexPrefix.cpp | 52 +++++++++++++++------------------------------- test/main.cpp | 1 - 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/test/hexPrefix.cpp b/test/hexPrefix.cpp index 0db8e75e9..a3de61d2e 100644 --- a/test/hexPrefix.cpp +++ b/test/hexPrefix.cpp @@ -24,47 +24,29 @@ #include "JsonSpiritHeaders.h" #include "TrieCommon.h" #include "Log.h" +#include + using namespace std; using namespace eth; namespace js = json_spirit; -namespace eth -{ - -template <> class UnitTest<3> +BOOST_AUTO_TEST_CASE(hexPrefix_test) { -public: - int operator()() + cnote << "Testing Hex-Prefix-Encode..."; + js::mValue v; + string s = asString(contents("../../tests/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::mValue v; - string s = asString(contents("../../tests/hexencodetest.json")); - js::read_string(s, v); - bool passed = true; - 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()); - if (!o["out"].is_null() && o["out"].get_str() != toHex(e)) - { - cwarn << "Test failed."; - cwarn << "Test says:" << o["out"].get_str(); - cwarn << "Impl says:" << toHex(e); - passed = false; - } - } - return passed ? 0 : 1; + 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) ); } - -}; - } -int hexPrefixTest() -{ - cnote << "Testing Hex-Prefix-Encode..."; - return UnitTest<3>()(); -} diff --git a/test/main.cpp b/test/main.cpp index fc8eecd52..92ec9a4f2 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -45,7 +45,6 @@ BOOST_AUTO_TEST_CASE(basic_tests) std::cout << sha3(s.out()) << std::endl;*/ int r = 0; - r += hexPrefixTest(); r += trieTest(); r += vmTest(); r += cryptoTest(); // TODO: Put in tests repo. From 7f2d8f9925412c552b0ce5a327258fe09b679c72 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 10:52:08 -0700 Subject: [PATCH 05/13] Broke trie tests out as separate boost auto test case. --- test/main.cpp | 1 - test/trie.cpp | 74 +++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/test/main.cpp b/test/main.cpp index 92ec9a4f2..9fdee1819 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -45,7 +45,6 @@ BOOST_AUTO_TEST_CASE(basic_tests) std::cout << sha3(s.out()) << std::endl;*/ int r = 0; - r += trieTest(); r += vmTest(); r += cryptoTest(); // TODO: Put in tests repo. // r += daggerTest(); diff --git a/test/trie.cpp b/test/trie.cpp index 5e3cfcb6c..785bcc728 100644 --- a/test/trie.cpp +++ b/test/trie.cpp @@ -26,56 +26,56 @@ #include #include "TrieHash.h" #include "MemTrie.h" +#include + using namespace std; using namespace eth; namespace js = json_spirit; -namespace eth -{ +namespace eth +{ + namespace test + { + static unsigned fac(unsigned _i) + { + return _i > 2 ? _i * fac(_i - 1) : _i; + } -unsigned fac(unsigned _i) { return _i > 2 ? _i * fac(_i - 1) : _i; } + } +} -template <> class UnitTest<4> + +BOOST_AUTO_TEST_CASE(trie_tests) { -public: - int operator()() + cnote << "Testing Trie..."; + + js::mValue v; + string s = asString(contents("../../tests/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()) { - js::mValue v; - string s = asString(contents("../../tests/trietest.json")); - js::read_string(s, v); - bool passed = true; - for (auto& i: v.get_obj()) + js::mObject& o = i.second.get_obj(); + cnote << i.first; + vector> ss; + for (auto& i: o["in"].get_obj()) + ss.push_back(make_pair(i.first, i.second.get_str())); + for (unsigned j = 0; j < eth::test::fac((unsigned)ss.size()); ++j) { - js::mObject& o = i.second.get_obj(); - cnote << i.first; - vector> ss; - for (auto& i: o["in"].get_obj()) - ss.push_back(make_pair(i.first, i.second.get_str())); - for (unsigned j = 0; j < fac((unsigned)ss.size()); ++j) - { - next_permutation(ss.begin(), ss.end()); - BasicMap m; - GenericTrieDB t(&m); - t.init(); - for (auto const& k: ss) - t.insert(k.first, k.second); - if (!o["root"].is_null() && o["root"].get_str() != toHex(t.root().asArray())) - { - cwarn << "Test failed on permutation " << j; - cwarn << "Test says:" << o["root"].get_str(); - cwarn << "Impl says:" << toHex(t.root().asArray()); - passed = false; - } - } + next_permutation(ss.begin(), ss.end()); + BasicMap m; + GenericTrieDB t(&m); + t.init(); + for (auto const& k: ss) + t.insert(k.first, k.second); + BOOST_REQUIRE(!o["root"].is_null()); + BOOST_CHECK(o["root"].get_str() == toHex(t.root().asArray()) ); } - return passed ? 0 : 1; } - -}; - } + inline h256 stringMapHash256(StringMap const& _s) { return hash256(_s); @@ -83,8 +83,6 @@ inline h256 stringMapHash256(StringMap const& _s) int trieTest() { - cnote << "Testing Trie..."; - return UnitTest<4>()(); // More tests... { From de1e41608594ec7a35821bcd272f12251a614932 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 10:53:48 -0700 Subject: [PATCH 06/13] Broke the crypto test out into a separate boost auto test case. --- test/crypto.cpp | 29 +++++++++++++++++++++++++++++ test/main.cpp | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/test/crypto.cpp b/test/crypto.cpp index 7896a0b13..5dac1fced 100644 --- a/test/crypto.cpp +++ b/test/crypto.cpp @@ -26,9 +26,38 @@ #include #include #include +#include + using namespace std; using namespace eth; + +BOOST_AUTO_TEST_CASE(crypto_tests) +{ + cnote << "Testing Crypto..."; + secp256k1_start(); + + KeyPair p(Secret(fromHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"))); + BOOST_REQUIRE(p.pub() == Public(fromHex("97466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f"))); + BOOST_REQUIRE(p.address() == Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075"))); + { + Transaction t; + t.nonce = 0; + t.receiveAddress = h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b")); + t.value = 1000; + cnote << RLP(t.rlp(false)); + cnote << toHex(t.rlp(false)); + cnote << t.sha3(false); + t.sign(p.secret()); + cnote << RLP(t.rlp(true)); + cnote << toHex(t.rlp(true)); + cnote << t.sha3(true); + BOOST_REQUIRE(t.sender() == p.address()); + } + +} + + int cryptoTest() { cnote << "Testing Crypto..."; diff --git a/test/main.cpp b/test/main.cpp index 9fdee1819..f5cab4789 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(basic_tests) int r = 0; r += vmTest(); - r += cryptoTest(); // TODO: Put in tests repo. + // r += daggerTest(); // r += stateTest(); // r += peerTest(argc, argv); From eb78b1d5077116bb5fb302cf15fde4f7a82c1a1f Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 10:55:20 -0700 Subject: [PATCH 07/13] Broke the virtual machine unit test out into a separate Boost auto test case. --- test/main.cpp | 3 +- test/vm.cpp | 81 +++++++++++++++++++-------------------------------- 2 files changed, 31 insertions(+), 53 deletions(-) diff --git a/test/main.cpp b/test/main.cpp index f5cab4789..4205c6a44 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -45,11 +45,10 @@ BOOST_AUTO_TEST_CASE(basic_tests) std::cout << sha3(s.out()) << std::endl;*/ int r = 0; - r += vmTest(); // r += daggerTest(); // r += stateTest(); // r += peerTest(argc, argv); - BOOST_REQUIRE(!r); +// BOOST_REQUIRE(!r); } diff --git a/test/vm.cpp b/test/vm.cpp index a0b268639..3fe5b399d 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -27,12 +27,13 @@ #include #include #include "JsonSpiritHeaders.h" +#include + using namespace std; using namespace json_spirit; using namespace eth; -namespace eth -{ +namespace eth { namespace test { class FakeExtVM: public ExtVMFace { @@ -311,37 +312,16 @@ public: bytes thisTxData; }; -#define CREATE_TESTS 0 - -template <> class UnitTest<1> -{ -public: - int operator()() - { - json_spirit::mValue v; -#if CREATE_TESTS - string s = asString(contents("../../cpp-ethereum/test/vmtests.json")); - json_spirit::read_string(s, v); - bool passed = doTests(v, true); - cout << json_spirit::write_string(v, true) << endl; -#else - string s = asString(contents("../../tests/vmtests.json")); - json_spirit::read_string(s, v); - bool passed = doTests(v, false); -#endif - return passed ? 0 : 1; - } - - bool doTests(json_spirit::mValue& v, bool _fillin) + void doTests(json_spirit::mValue& v, bool _fillin) { - bool passed = true; for (auto& i: v.get_obj()) + { cnote << i.first; mObject& o = i.second.get_obj(); VM vm; - FakeExtVM fev; + eth::test::FakeExtVM fev; fev.importEnv(o["env"].get_obj()); fev.importState(o["pre"].get_obj()); @@ -365,37 +345,40 @@ public: } else { - FakeExtVM test; + eth::test::FakeExtVM test; test.importState(o["post"].get_obj()); test.importTxs(o["txs"].get_array()); int i = 0; for (auto const& d: o["out"].get_array()) { - if (output[i] != FakeExtVM::toInt(d)) - { - cwarn << "Test failed: output byte" << i << "different."; - passed = false; - } + BOOST_CHECK_MESSAGE( output[i] == FakeExtVM::toInt(d), "Output byte [" << i << "] different!"); ++i; } - - if (test.addresses != fev.addresses) - { - cwarn << "Test failed: state different."; - passed = false; - } - if (test.txs != fev.txs) - { - cwarn << "Test failed: tx list different:"; - cwarn << test.txs; - cwarn << fev.txs; - passed = false; - } + BOOST_CHECK( test.addresses == fev.addresses); + BOOST_CHECK( test.txs == fev.txs ); } } - return passed; } +} } // Namespace Close + +BOOST_AUTO_TEST_CASE(vm_tests) +{ + try + { + cnote << "Testing VM..."; + json_spirit::mValue v; + string s = asString(contents("../../tests/vmtests.json")); + BOOST_REQUIRE_MESSAGE( s.length() > 0, "Contents of 'vmtests.json' is empty. Have you cloned the 'tests' repo branch develop?" ); + json_spirit::read_string(s, v); + eth::test::doTests(v, false); + } + catch( std::exception& e) + { + BOOST_ERROR("Failed VM Test with Exception: " << e.what()); + } +} +#if 0 string makeTestCase() { json_spirit::mObject o; @@ -427,9 +410,5 @@ public: } -int vmTest() -{ - cnote << "Testing VM..."; - return UnitTest<1>()(); -} +#endif From 5064acdc28413a5050361b7cc150a16541e301b7 Mon Sep 17 00:00:00 2001 From: Vincent Gariepy Date: Sat, 19 Apr 2014 17:56:21 -0400 Subject: [PATCH 08/13] neth: add -m option for mining and fix contract creation --- neth/main.cpp | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/neth/main.cpp b/neth/main.cpp index 965e8685f..7a97dc9bc 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -65,14 +65,15 @@ void help() << " /Etherum or Library/Application Support/Ethereum)." << endl << " -h,--help Show this help message and exit." << endl << " -l,--listen Listen on the given port for incoming connected (default: 30303)." << endl + << " -m,--mining Enable mining (default: off)" << endl << " -n,--upnp Use upnp for NAT (default: on)." << endl << " -o,--mode Start a full node or a peer node (Default: full)." << endl << " -p,--port Connect to remote port (default: 30303)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl - << " -v,--verbosity <0..9> Set the log verbosity from 0 to 9 (Default: 8)." << endl - << " -x,--peers Attempt to connect to given number of peers (Default: 5)." << endl + << " -v,--verbosity <0..9> Set the log verbosity from 0 to 9 (tmp forced to 1)." << endl + << " -x,--peers Attempt to connect to given number of peers (default: 5)." << endl << " -V,--version Show the version and exit." << endl; exit(0); } @@ -94,8 +95,8 @@ void interactiveHelp() << " transact Execute a given transaction." << endl << " send Execute a given transaction with current secret." << endl << " contract Create a new contract with current secret." << endl - << " inspect Dumps a contract to /.evm." << endl - << " exit Exits the application." << endl; + << " inspect Dumps a contract to /.evm." << endl + << " exit Exits the application." << endl; } string credits() @@ -284,6 +285,7 @@ int main(int argc, char** argv) string remoteHost; unsigned short remotePort = 30303; string dbPath; + bool mining = false; NodeMode mode = NodeMode::Full; unsigned peers = 5; string publicIP; @@ -344,6 +346,18 @@ int main(int argc, char** argv) us = KeyPair(h256(fromHex(argv[++i]))); else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) dbPath = argv[++i]; + else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) + { + string m = argv[++i]; + if (isTrue(m)) + mining = true; + else if (isFalse(m)) + mining = false; + else + { + cerr << "Unknown mining option: " << m << endl; + } + } else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) @@ -437,6 +451,8 @@ int main(int argc, char** argv) if (!remoteHost.empty()) c.startNetwork(listenPort, remoteHost, remotePort, mode, peers, publicIP, upnp); + if (mining) + c.startMining(); while (true) { @@ -632,8 +648,8 @@ int main(int argc, char** argv) l.push_back("Gas price"); l.push_back("Gas"); vector b; - b.push_back("Code"); - b.push_back("Init"); + b.push_back("Code (hex)"); + b.push_back("Init (hex)"); c.lock(); vector fields = form_dialog(s, l, b, height, width, cmd); c.unlock(); @@ -671,22 +687,17 @@ int main(int argc, char** argv) else { bytes data; - // bytes code = compileLisp(scode, false, data); - // scode = asString(code); - bytes code = assemble(scode); + bytes code = fromHex(scode); cnote << "Assembled:"; stringstream ssc; ssc << disassemble(code); cnote << ssc.str(); - // int ssize = sinit.length(); - // bytes init = compileLisp(sinit, false, data); - // sinit = asString(init); - bytes init = assemble(sinit); + bytes init = fromHex(sinit); ssc.str(string()); ssc << disassemble(init); cnote << "Init:"; cnote << ssc.str(); - c.transact(us.secret(), endowment, data, init, gas, gasPrice); + c.transact(us.secret(), endowment, code, init, gas, gasPrice); } } } From 6f8eb048877f061d73354bbffe8c8acfd9bedcbd Mon Sep 17 00:00:00 2001 From: Vincent Gariepy Date: Sat, 19 Apr 2014 18:16:38 -0400 Subject: [PATCH 09/13] no need for data here --- neth/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/neth/main.cpp b/neth/main.cpp index 7a97dc9bc..ff10365fe 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -686,7 +686,6 @@ int main(int argc, char** argv) cwarn << "No code submitted"; else { - bytes data; bytes code = fromHex(scode); cnote << "Assembled:"; stringstream ssc; From 6d925c75dd95ad20193899d480ffe827dfc952b1 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 16:27:24 -0700 Subject: [PATCH 10/13] Added new test case for decoding the RLP data in the rlptest.json --- test/rlp.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 7 deletions(-) diff --git a/test/rlp.cpp b/test/rlp.cpp index e13965daf..1271d7ff9 100644 --- a/test/rlp.cpp +++ b/test/rlp.cpp @@ -21,10 +21,13 @@ */ #include +#include #include "JsonSpiritHeaders.h" #include #include +#include #include +#include using namespace std; using namespace eth; @@ -54,29 +57,137 @@ namespace eth _rlp.append(s); } } + + static void getRLPTestCases(js::mValue& v) + { + string s = asString(contents("../../tests/rlptest.json")); + BOOST_REQUIRE_MESSAGE( s.length() > 0, + "Contents of 'rlptest.json' is empty. Have you cloned the 'tests' repo branch develop?"); + js::read_string(s, v); + } + + static void checkRLPTestCase(js::mObject& o) + { + BOOST_REQUIRE( o.count("in") > 0 ); + BOOST_REQUIRE( o.count("out") > 0 ); + BOOST_REQUIRE(!o["out"].is_null()); + } + + static void checkRLPAgainstJson(js::mValue& v, RLP& u) + { + if ( v.type() == js::str_type ) + { + const std::string& expectedText = v.get_str(); + if ( expectedText.front() == '#' ) + { + // Deal with bigint instead of a raw string + std::string bigIntStr = expectedText.substr(1,expectedText.length()-1); + std::stringstream bintStream(bigIntStr); + bigint val; + bintStream >> val; + BOOST_CHECK( !u.isList() ); + BOOST_CHECK( !u.isNull() ); + BOOST_CHECK( u ); // operator bool() + BOOST_CHECK(u == val); + } + else + { + BOOST_CHECK( !u.isList() ); + BOOST_CHECK( !u.isNull() ); + BOOST_CHECK( u.isData() ); + BOOST_CHECK( u ); + 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 ); // operator bool() + 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() ); + uint 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_CASE(rlp_test) +BOOST_AUTO_TEST_CASE(rlp_encoding_test) { - cnote << "Testing RLP..."; + cnote << "Testing RLP Encoding..."; js::mValue v; - string s = asString(contents("../../tests/rlptest.json")); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'rlptest.json' is empty. Have you cloned the 'tests' repo branch develop?"); - js::read_string(s, v); + eth::test::getRLPTestCases(v); + for (auto& i: v.get_obj()) { js::mObject& o = i.second.get_obj(); cnote << i.first; + eth::test::checkRLPTestCase(o); + RLPStream s; eth::test::buildRLP(o["in"], s); - BOOST_REQUIRE(!o["out"].is_null()); - BOOST_CHECK(o["out"].get_str() == toHex(s.out()) ); + + std::string expectedText(o["out"].get_str()); + std::transform(expectedText.begin(), expectedText.end(), expectedText.begin(), ::tolower ); + + const std::string& computedText = toHex(s.out()); + + std::stringstream msg; + msg << "Encoding Failed: expected: " << expectedText << std::endl; + msg << " But Computed: " << computedText; + + BOOST_CHECK_MESSAGE( + expectedText == computedText, + msg.str() + ); } } +BOOST_AUTO_TEST_CASE(rlp_decoding_test) +{ + cnote << "Testing RLP decoding..."; + // 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. + js::mValue v; + eth::test::getRLPTestCases(v); + for (auto& i: v.get_obj()) + { + js::mObject& o = i.second.get_obj(); + cnote << i.first; + eth::test::checkRLPTestCase(o); + + js::mValue& inputData = o["in"]; + bytes payloadToDecode = fromHex(o["out"].get_str()); + + RLP payload(payloadToDecode); + + eth::test::checkRLPAgainstJson(inputData, payload); + } +} From 585ffb1025fc81007ca6a15908ec16f2cdbfbf13 Mon Sep 17 00:00:00 2001 From: Vincent Gariepy Date: Sat, 19 Apr 2014 21:55:29 -0400 Subject: [PATCH 11/13] neth: use streams for inputs --- neth/main.cpp | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/neth/main.cpp b/neth/main.cpp index ff10365fe..cb974acda 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -564,9 +564,18 @@ int main(int argc, char** argv) fields[4].erase(std::remove(fields[4].begin(), fields[4].end(), ' '), fields[4].end()); fields[5].erase(std::find_if(fields[5].rbegin(), fields[5].rend(), std::bind1st(std::not_equal_to(), ' ')).base(), fields[5].end()); int size = fields[0].length(); - u256 amount = atoll(fields[1].c_str()); - u256 gasPrice = atoll(fields[2].c_str()); - u256 gas = atoll(fields[3].c_str()); + u256 amount; + u256 gasPrice; + u256 gas; + stringstream ssa; + ssa << fields[1]; + ssa >> amount; + stringstream ssg; + ssg << fields[3]; + ssg >> gas; + stringstream ssp; + ssp << fields[2]; + ssp >> gasPrice; string sechex = fields[4]; string sdata = fields[5]; cnote << "Data:"; @@ -623,7 +632,10 @@ int main(int argc, char** argv) { fields[0].erase(std::remove(fields[0].begin(), fields[0].end(), ' '), fields[0].end()); int size = fields[0].length(); - u256 amount = atoll(fields[1].c_str()); + u256 amount; + stringstream sss; + sss << fields[1]; + sss >> amount; if (size < 40) { if (size > 0) @@ -661,9 +673,18 @@ int main(int argc, char** argv) } else { - u256 endowment = atoll(fields[0].c_str()); - u256 gas = atoll(fields[2].c_str()); - u256 gasPrice = atoll(fields[1].c_str()); + u256 endowment; + u256 gas; + u256 gasPrice; + stringstream sse; + sse << fields[0]; + sse >> endowment; + stringstream ssg; + ssg << fields[2]; + ssg >> gas; + stringstream ssp; + ssp << fields[1]; + ssp >> gasPrice; if (endowment < 0) cwarn << "Invalid endowment"; else if (gasPrice < c_minGasPrice) From b889401386c9d8d7e908cc23faf54715f18e007e Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sat, 19 Apr 2014 22:09:41 -0700 Subject: [PATCH 12/13] Added some checks on parameters of the objects imported from the json files to make debugging easier. --- test/vm.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/vm.cpp b/test/vm.cpp index 3fe5b399d..a3242b573 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -136,6 +136,12 @@ public: void importEnv(mObject& _o) { + BOOST_REQUIRE(_o.count("previousHash") > 0 ); + BOOST_REQUIRE(_o.count("previousNonce") > 0 ); + BOOST_REQUIRE(_o.count("currentDifficulty") > 0 ); + BOOST_REQUIRE(_o.count("currentTimestamp") > 0 ); + BOOST_REQUIRE(_o.count("currentCoinbase") > 0 ); + previousBlock.hash = h256(_o["previousHash"].get_str()); previousBlock.nonce = h256(_o["previousNonce"].get_str()); currentBlock.difficulty = toInt(_o["currentDifficulty"]); @@ -229,6 +235,10 @@ public: for (auto const& i: _o) { mObject o = i.second.get_obj(); + BOOST_REQUIRE(o.count("balance") > 0 ); + BOOST_REQUIRE(o.count("nonce") > 0 ); + BOOST_REQUIRE(o.count("store") > 0 ); + auto& a = addresses[Address(i.first)]; get<0>(a) = toInt(o["balance"]); get<1>(a) = toInt(o["nonce"]); @@ -250,6 +260,7 @@ public: mObject exportExec() { + mObject ret; ret["address"] = toString(myAddress); ret["caller"] = toString(caller); @@ -265,6 +276,13 @@ public: void importExec(mObject& _o) { + BOOST_REQUIRE(_o.count("address")> 0); + BOOST_REQUIRE(_o.count("caller") > 0); + BOOST_REQUIRE(_o.count("origin") > 0); + BOOST_REQUIRE(_o.count("value") > 0); + BOOST_REQUIRE(_o.count("gasPrice") > 0); + BOOST_REQUIRE(_o.count("data") > 0 ); + myAddress = Address(_o["address"].get_str()); caller = Address(_o["caller"].get_str()); origin = Address(_o["origin"].get_str()); @@ -298,6 +316,9 @@ public: for (mValue& v: _txs) { auto tx = v.get_obj(); + BOOST_REQUIRE(tx.count("destination") > 0); + BOOST_REQUIRE(tx.count("value") > 0 ); + BOOST_REQUIRE(tx.count("data") > 0 ); Transaction t; t.receiveAddress = Address(tx["destination"].get_str()); t.value = toInt(tx["value"]); @@ -320,6 +341,10 @@ public: 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("exec") > 0 ); + VM vm; eth::test::FakeExtVM fev; fev.importEnv(o["env"].get_obj()); @@ -345,6 +370,10 @@ public: } else { + BOOST_REQUIRE( o.count("post") > 0 ); + BOOST_REQUIRE( o.count("txs") > 0 ); + BOOST_REQUIRE( o.count("out") > 0 ); + eth::test::FakeExtVM test; test.importState(o["post"].get_obj()); test.importTxs(o["txs"].get_array()); From b17182a86938cb544861c40defe2f4847413c084 Mon Sep 17 00:00:00 2001 From: Carl Allendorph Date: Sun, 20 Apr 2014 11:00:49 -0700 Subject: [PATCH 13/13] Formatted the instruction information list. --- libethereum/Instruction.cpp | 162 ++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/libethereum/Instruction.cpp b/libethereum/Instruction.cpp index 5f11f33af..3fd81b695 100644 --- a/libethereum/Instruction.cpp +++ b/libethereum/Instruction.cpp @@ -115,89 +115,89 @@ const std::map eth::c_instructions = }; const std::map eth::c_instructionInfo = -{ - { Instruction::STOP, { "STOP", 0, 0, 0 } }, - { Instruction::ADD, { "ADD", 0, 2, 1 } }, - { Instruction::SUB, { "SUB", 0, 2, 1 } }, - { Instruction::MUL, { "MUL", 0, 2, 1 } }, - { Instruction::DIV, { "DIV", 0, 2, 1 } }, - { Instruction::SDIV, { "SDIV", 0, 2, 1 } }, - { Instruction::MOD, { "MOD", 0, 2, 1 } }, - { Instruction::SMOD, { "SMOD", 0, 2, 1 } }, - { Instruction::EXP, { "EXP", 0, 2, 1 } }, - { Instruction::NEG, { "NEG", 0, 1, 1 } }, - { Instruction::LT, { "LT", 0, 2, 1 } }, - { Instruction::GT, { "GT", 0, 2, 1 } }, - { Instruction::EQ, { "EQ", 0, 2, 1 } }, - { Instruction::NOT, { "NOT", 0, 1, 1 } }, - { Instruction::AND, { "AND", 0, 2, 1 } }, - { Instruction::OR, { "OR", 0, 2, 1 } }, - { Instruction::XOR, { "XOR", 0, 2, 1 } }, - { Instruction::BYTE, { "BYTE", 0, 2, 1 } }, - { Instruction::SHA3, { "SHA3", 0, 2, 1 } }, - { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } }, - { Instruction::BALANCE, { "BALANCE", 0, 1, 1 } }, - { Instruction::ORIGIN, { "ORIGIN", 0, 1, 1 } }, - { Instruction::CALLER, { "CALLER", 0, 0, 1 } }, - { Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } }, +{ // Add, Args, Ret + { Instruction::STOP, { "STOP", 0, 0, 0 } }, + { Instruction::ADD, { "ADD", 0, 2, 1 } }, + { Instruction::SUB, { "SUB", 0, 2, 1 } }, + { Instruction::MUL, { "MUL", 0, 2, 1 } }, + { Instruction::DIV, { "DIV", 0, 2, 1 } }, + { Instruction::SDIV, { "SDIV", 0, 2, 1 } }, + { Instruction::MOD, { "MOD", 0, 2, 1 } }, + { Instruction::SMOD, { "SMOD", 0, 2, 1 } }, + { Instruction::EXP, { "EXP", 0, 2, 1 } }, + { Instruction::NEG, { "NEG", 0, 1, 1 } }, + { Instruction::LT, { "LT", 0, 2, 1 } }, + { Instruction::GT, { "GT", 0, 2, 1 } }, + { Instruction::EQ, { "EQ", 0, 2, 1 } }, + { Instruction::NOT, { "NOT", 0, 1, 1 } }, + { Instruction::AND, { "AND", 0, 2, 1 } }, + { Instruction::OR, { "OR", 0, 2, 1 } }, + { Instruction::XOR, { "XOR", 0, 2, 1 } }, + { Instruction::BYTE, { "BYTE", 0, 2, 1 } }, + { Instruction::SHA3, { "SHA3", 0, 2, 1 } }, + { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } }, + { Instruction::BALANCE, { "BALANCE", 0, 1, 1 } }, + { Instruction::ORIGIN, { "ORIGIN", 0, 1, 1 } }, + { Instruction::CALLER, { "CALLER", 0, 0, 1 } }, + { Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } }, { Instruction::CALLDATALOAD, { "CALLDATALOAD", 0, 1, 1 } }, { Instruction::CALLDATASIZE, { "CALLDATASIZE", 0, 0, 1 } }, - { Instruction::GASPRICE, { "BASEFEE", 0, 0, 1 } }, - { Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } }, - { Instruction::COINBASE, { "COINBASE", 0, 0, 1 } }, - { Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } }, - { Instruction::NUMBER, { "NUMBER", 0, 0, 1 } }, - { Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } }, - { Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } }, - { Instruction::POP, { "POP", 0, 1, 0 } }, - { Instruction::DUP, { "DUP", 0, 1, 2 } }, - { Instruction::SWAP, { "SWAP", 0, 2, 2 } }, - { Instruction::MLOAD, { "MLOAD", 0, 1, 1 } }, - { Instruction::MSTORE, { "MSTORE", 0, 2, 0 } }, - { Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } }, - { Instruction::SLOAD, { "SLOAD", 0, 1, 1 } }, - { Instruction::SSTORE, { "SSTORE", 0, 2, 0 } }, - { Instruction::JUMP, { "JUMP", 0, 1, 0 } }, - { Instruction::JUMPI, { "JUMPI", 0, 2, 0 } }, - { Instruction::PC, { "PC", 0, 0, 1 } }, - { Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } }, - { Instruction::GAS, { "GAS", 0, 0, 1 } }, - { Instruction::PUSH1, { "PUSH1", 1, 0, 1 } }, - { Instruction::PUSH2, { "PUSH2", 2, 0, 1 } }, - { Instruction::PUSH3, { "PUSH3", 3, 0, 1 } }, - { Instruction::PUSH4, { "PUSH4", 4, 0, 1 } }, - { Instruction::PUSH5, { "PUSH5", 5, 0, 1 } }, - { Instruction::PUSH6, { "PUSH6", 6, 0, 1 } }, - { Instruction::PUSH7, { "PUSH7", 7, 0, 1 } }, - { Instruction::PUSH8, { "PUSH8", 8, 0, 1 } }, - { Instruction::PUSH9, { "PUSH9", 9, 0, 1 } }, - { Instruction::PUSH10, { "PUSH10", 10, 0, 1 } }, - { Instruction::PUSH11, { "PUSH11", 11, 0, 1 } }, - { Instruction::PUSH12, { "PUSH12", 12, 0, 1 } }, - { Instruction::PUSH13, { "PUSH13", 13, 0, 1 } }, - { Instruction::PUSH14, { "PUSH14", 14, 0, 1 } }, - { Instruction::PUSH15, { "PUSH15", 15, 0, 1 } }, - { Instruction::PUSH16, { "PUSH16", 16, 0, 1 } }, - { Instruction::PUSH17, { "PUSH17", 17, 0, 1 } }, - { Instruction::PUSH18, { "PUSH18", 18, 0, 1 } }, - { Instruction::PUSH19, { "PUSH19", 19, 0, 1 } }, - { Instruction::PUSH20, { "PUSH20", 20, 0, 1 } }, - { Instruction::PUSH21, { "PUSH21", 21, 0, 1 } }, - { Instruction::PUSH22, { "PUSH22", 22, 0, 1 } }, - { Instruction::PUSH23, { "PUSH23", 23, 0, 1 } }, - { Instruction::PUSH24, { "PUSH24", 24, 0, 1 } }, - { Instruction::PUSH25, { "PUSH25", 25, 0, 1 } }, - { Instruction::PUSH26, { "PUSH26", 26, 0, 1 } }, - { Instruction::PUSH27, { "PUSH27", 27, 0, 1 } }, - { Instruction::PUSH28, { "PUSH28", 28, 0, 1 } }, - { Instruction::PUSH29, { "PUSH29", 29, 0, 1 } }, - { Instruction::PUSH30, { "PUSH30", 30, 0, 1 } }, - { Instruction::PUSH31, { "PUSH31", 31, 0, 1 } }, - { Instruction::PUSH32, { "PUSH32", 32, 0, 1 } }, - { Instruction::CREATE, { "CREATE", 0, 3, 1 } }, - { Instruction::CALL, { "CALL", 0, 7, 1 } }, - { Instruction::RETURN, { "RETURN", 0, 2, 0 } }, - { Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} } + { Instruction::GASPRICE, { "BASEFEE", 0, 0, 1 } }, + { Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } }, + { Instruction::COINBASE, { "COINBASE", 0, 0, 1 } }, + { Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } }, + { Instruction::NUMBER, { "NUMBER", 0, 0, 1 } }, + { Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } }, + { Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } }, + { Instruction::POP, { "POP", 0, 1, 0 } }, + { Instruction::DUP, { "DUP", 0, 1, 2 } }, + { Instruction::SWAP, { "SWAP", 0, 2, 2 } }, + { Instruction::MLOAD, { "MLOAD", 0, 1, 1 } }, + { Instruction::MSTORE, { "MSTORE", 0, 2, 0 } }, + { Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } }, + { Instruction::SLOAD, { "SLOAD", 0, 1, 1 } }, + { Instruction::SSTORE, { "SSTORE", 0, 2, 0 } }, + { Instruction::JUMP, { "JUMP", 0, 1, 0 } }, + { Instruction::JUMPI, { "JUMPI", 0, 2, 0 } }, + { Instruction::PC, { "PC", 0, 0, 1 } }, + { Instruction::MEMSIZE, { "MEMSIZE", 0, 0, 1 } }, + { Instruction::GAS, { "GAS", 0, 0, 1 } }, + { Instruction::PUSH1, { "PUSH1", 1, 0, 1 } }, + { Instruction::PUSH2, { "PUSH2", 2, 0, 1 } }, + { Instruction::PUSH3, { "PUSH3", 3, 0, 1 } }, + { Instruction::PUSH4, { "PUSH4", 4, 0, 1 } }, + { Instruction::PUSH5, { "PUSH5", 5, 0, 1 } }, + { Instruction::PUSH6, { "PUSH6", 6, 0, 1 } }, + { Instruction::PUSH7, { "PUSH7", 7, 0, 1 } }, + { Instruction::PUSH8, { "PUSH8", 8, 0, 1 } }, + { Instruction::PUSH9, { "PUSH9", 9, 0, 1 } }, + { Instruction::PUSH10, { "PUSH10", 10, 0, 1 } }, + { Instruction::PUSH11, { "PUSH11", 11, 0, 1 } }, + { Instruction::PUSH12, { "PUSH12", 12, 0, 1 } }, + { Instruction::PUSH13, { "PUSH13", 13, 0, 1 } }, + { Instruction::PUSH14, { "PUSH14", 14, 0, 1 } }, + { Instruction::PUSH15, { "PUSH15", 15, 0, 1 } }, + { Instruction::PUSH16, { "PUSH16", 16, 0, 1 } }, + { Instruction::PUSH17, { "PUSH17", 17, 0, 1 } }, + { Instruction::PUSH18, { "PUSH18", 18, 0, 1 } }, + { Instruction::PUSH19, { "PUSH19", 19, 0, 1 } }, + { Instruction::PUSH20, { "PUSH20", 20, 0, 1 } }, + { Instruction::PUSH21, { "PUSH21", 21, 0, 1 } }, + { Instruction::PUSH22, { "PUSH22", 22, 0, 1 } }, + { Instruction::PUSH23, { "PUSH23", 23, 0, 1 } }, + { Instruction::PUSH24, { "PUSH24", 24, 0, 1 } }, + { Instruction::PUSH25, { "PUSH25", 25, 0, 1 } }, + { Instruction::PUSH26, { "PUSH26", 26, 0, 1 } }, + { Instruction::PUSH27, { "PUSH27", 27, 0, 1 } }, + { Instruction::PUSH28, { "PUSH28", 28, 0, 1 } }, + { Instruction::PUSH29, { "PUSH29", 29, 0, 1 } }, + { Instruction::PUSH30, { "PUSH30", 30, 0, 1 } }, + { Instruction::PUSH31, { "PUSH31", 31, 0, 1 } }, + { Instruction::PUSH32, { "PUSH32", 32, 0, 1 } }, + { Instruction::CREATE, { "CREATE", 0, 3, 1 } }, + { Instruction::CALL, { "CALL", 0, 7, 1 } }, + { Instruction::RETURN, { "RETURN", 0, 2, 0 } }, + { Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} } }; static string readQuoted(char const*& o_d, char const* _e)