From b9a722223ad7eee9195230a97481da0d17cfad79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 6 May 2015 13:18:52 +0200 Subject: [PATCH 01/22] SmartVM: initial implementation --- TestHelper.cpp | 7 +++---- TestHelper.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/TestHelper.cpp b/TestHelper.cpp index eecf6f80d..b14c3571c 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -288,7 +288,7 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta { addressOptions = _expectedStateOptions.at(a.first); } - catch(std::out_of_range) + catch(std::out_of_range const&) { BOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!"); break; @@ -707,10 +707,9 @@ Options::Options() { auto arg = std::string{argv[i]}; if (arg == "--jit") - { - jit = true; eth::VMFactory::setKind(eth::VMKind::JIT); - } + else if (arg == "--vm=smart") + eth::VMFactory::setKind(eth::VMKind::Smart); else if (arg == "--vmtrace") vmtrace = true; else if (arg == "--filltests") diff --git a/TestHelper.h b/TestHelper.h index 10e76aa96..834dc0562 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -179,7 +179,6 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) class Options { public: - bool jit = false; ///< Use JIT bool vmtrace = false; ///< Create EVM execution tracer // TODO: Link with log verbosity? bool fillTests = false; ///< Create JSON test files from execution results bool stats = false; ///< Execution time stats From 1e2bd8afe4633391806396ed6773c70db59a1fde Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 7 May 2015 17:10:44 +0200 Subject: [PATCH 02/22] New ethash API integration part 1 - cpp-ethereum now compiles with the new API - Proper integration with testing will come with the next commits From f7109717ed6ffbde00cbd9090cdb6e8f00c01359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 8 May 2015 11:00:17 +0200 Subject: [PATCH 03/22] testeth: fix --singletest option --- TestHelper.cpp | 95 +++++++++++++++++++++++--------------------------- TestHelper.h | 3 +- 2 files changed, 46 insertions(+), 52 deletions(-) diff --git a/TestHelper.cpp b/TestHelper.cpp index 144a1a286..e0aad310f 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -549,58 +549,50 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e } } -void userDefinedTest(string testTypeFlag, std::function doTests) +void userDefinedTest(std::function doTests) { - Options::get(); // parse command line options, e.g. to enable JIT - - for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + if (!Options::get().singleTest) { - string arg = boost::unit_test::framework::master_test_suite().argv[i]; - if (arg == testTypeFlag) - { - if (boost::unit_test::framework::master_test_suite().argc <= i + 2) - { - cnote << "Missing filename\nUsage: testeth " << testTypeFlag << " \n"; - return; - } - string filename = boost::unit_test::framework::master_test_suite().argv[i + 1]; - string testname = boost::unit_test::framework::master_test_suite().argv[i + 2]; - int currentVerbosity = g_logVerbosity; - g_logVerbosity = 12; - try - { - cnote << "Testing user defined test: " << filename; - json_spirit::mValue v; - string s = asString(contents(filename)); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. "); - json_spirit::read_string(s, v); - json_spirit::mObject oSingleTest; - - json_spirit::mObject::const_iterator pos = v.get_obj().find(testname); - if (pos == v.get_obj().end()) - { - cnote << "Could not find test: " << testname << " in " << filename << "\n"; - return; - } - else - oSingleTest[pos->first] = pos->second; - - json_spirit::mValue v_singleTest(oSingleTest); - doTests(v_singleTest, false); - } - catch (Exception const& _e) - { - BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e)); - g_logVerbosity = currentVerbosity; - } - catch (std::exception const& _e) - { - BOOST_ERROR("Failed Test with Exception: " << _e.what()); - g_logVerbosity = currentVerbosity; - } - g_logVerbosity = currentVerbosity; - } + cnote << "Missing user test specification\nUsage: testeth --singletest \n"; + return; } + + auto& filename = Options::get().singleTestFile; + auto& testname = Options::get().singleTestName; + int currentVerbosity = g_logVerbosity; + g_logVerbosity = 12; + try + { + cnote << "Testing user defined test: " << filename; + json_spirit::mValue v; + string s = asString(contents(filename)); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. "); + json_spirit::read_string(s, v); + json_spirit::mObject oSingleTest; + + json_spirit::mObject::const_iterator pos = v.get_obj().find(testname); + if (pos == v.get_obj().end()) + { + cnote << "Could not find test: " << testname << " in " << filename << "\n"; + return; + } + else + oSingleTest[pos->first] = pos->second; + + json_spirit::mValue v_singleTest(oSingleTest); + doTests(v_singleTest, false); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e)); + g_logVerbosity = currentVerbosity; + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed Test with Exception: " << _e.what()); + g_logVerbosity = currentVerbosity; + } + g_logVerbosity = currentVerbosity; } void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests) @@ -740,10 +732,11 @@ Options::Options() inputLimits = true; bigData = true; } - else if (arg == "--singletest" && i + 1 < argc) + else if (arg == "--singletest" && i + 2 < argc) { singleTest = true; - singleTestName = argv[i + 1]; + singleTestFile = argv[i + 1]; + singleTestName = argv[i + 2]; } } } diff --git a/TestHelper.h b/TestHelper.h index 02f509e4c..631bc4df2 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -157,7 +157,7 @@ void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs); void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates); void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests); -void userDefinedTest(std::string testTypeFlag, std::function doTests); +void userDefinedTest(std::function doTests); RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj); eth::LastHashes lastHashes(u256 _currentBlockNumber); json_spirit::mObject fillJsonWithState(eth::State _state); @@ -189,6 +189,7 @@ public: /// Test selection /// @{ bool singleTest = false; + std::string singleTestFile; std::string singleTestName; bool performance = false; bool quadratic = false; From b11fa5996a1d79e27da99c91183a0daee303872f Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 8 May 2015 15:55:27 +0200 Subject: [PATCH 04/22] Further fixes in Ethash integration and testing From e69cdcd2d60ab9f3b829de540f91a747d7dad3b0 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Sun, 10 May 2015 15:18:13 +0200 Subject: [PATCH 05/22] Test for Capability class Basic configuration for sending and receiving messgaes. From 2958ad88f3e75146be2e84b246733fe9dc9984c9 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 10 May 2015 15:52:25 +0200 Subject: [PATCH 06/22] Squashed 'libjsqrc/ethereumjs/' changes from 3b799d1..e908439 e908439 version 0.3.6 091c8e5 Merge branch 'develop' into tcoulter 272837e cleaned up param.js 38a13bc removed unused functions from coder.js 8e3158f Merge pull request #196 from debris/new_abi c6a57b3 cleanup and documentation 6e60e1f new solidity abi decoding 3f0d1c8 new abi proposal implementation of encoding 39d70e8 Merge pull request #195 from debris/fixed_abi f963855 removed unused functions from abi.js c59419e added new "dave" example 860ad2c fixed #194 22ca9b0 Merge branch 'develop' of https://github.com/ethereum/ethereum.js into develop 6739a1b "dave" example 08f3aae add optional nonce property to sendTransaction 2ca4240 Add error handling to synchronous methods (obligatory warning against using synchronous calls at all). 4690130 version 0.3.5 7949f6a Merge pull request #187 from debris/encoding 944c5cc removed unused test files 8a9c9c5 Merge branch 'develop' into encoding 330b0da more tests for encoding and decoding solidity params b064eab Handle this error properly. For instance, without this, if we cannot connect to the RPC client, JSON won't be able to parse the result (there is none), in which case would cause a RuntimeException. 7989607 version 0.3.4 afb61d5 Merge branch 'master' into develop 97f6e7d build files again 539ef7b Merge pull request #186 from ethereum/eventFilterFix ec0dc44 Merge pull request #188 from ethereum/develop bd73ccc added eth_hashrate baed4c8 fixed old encoding e9ec708 fixed event from and toBlock git-subtree-dir: libjsqrc/ethereumjs git-subtree-split: e90843973f3ae554069347b61cb5b393091c34d1 --- abi.inputParser.js | 515 ------------------------ abi.outputParser.js | 419 ------------------- coder.decodeParam.js | 45 ++- coder.encodeParam.js | 82 +++- contract.js | 1 + event.encode.js | 26 ++ formatters.inputTransactionFormatter.js | 70 +++- web3.eth.filter.js | 15 + web3.eth.hashRate.js | 38 ++ 9 files changed, 232 insertions(+), 979 deletions(-) delete mode 100644 abi.inputParser.js delete mode 100644 abi.outputParser.js create mode 100644 web3.eth.hashRate.js diff --git a/abi.inputParser.js b/abi.inputParser.js deleted file mode 100644 index 6700acd72..000000000 --- a/abi.inputParser.js +++ /dev/null @@ -1,515 +0,0 @@ -var chai = require('chai'); -var assert = chai.assert; -var BigNumber = require('bignumber.js'); -var abi = require('../lib/solidity/abi'); -var clone = function (object) { return JSON.parse(JSON.stringify(object)); }; - -var description = [{ - "name": "test", - "type": "function", - "inputs": [{ - "name": "a", - "type": "uint256" - } - ], - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ] -}]; - -describe('lib/solidity/abi', function () { - describe('inputParser', function () { - it('should parse input uint', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "uint" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); - assert.equal( - parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal( - parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); - assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); - - }); - - it('should parse input uint128', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "uint128" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); - assert.equal( - parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal( - parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); - assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); - - }); - - it('should parse input uint256', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "uint256" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); - assert.equal( - parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal( - parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); - assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); - - }); - - it('should parse input int', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); - assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); - assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"); - assert.equal( - parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal( - parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); - assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); - }); - - it('should parse input int128', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int128" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); - assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); - assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"); - assert.equal( - parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal( - parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); - assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); - - }); - - it('should parse input int256', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int256" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); - assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); - assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"); - assert.equal( - parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal( - parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); - assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); - assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); - - }); - - it('should parse input bool', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: 'bool' } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(true), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.test(false), "0000000000000000000000000000000000000000000000000000000000000000"); - - }); - - it('should parse input address', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "address" } - ]; - - // when - var parser = abi.inputParser(d) - - // then - assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); - - }); - - it('should parse input fixed bytes type', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "bytes" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test('hello'), - "0000000000000000000000000000000000000000000000000000000000000005" + - "68656c6c6f000000000000000000000000000000000000000000000000000000" - ); - assert.equal( - parser.test('world'), - "0000000000000000000000000000000000000000000000000000000000000005776f726c64000000000000000000000000000000000000000000000000000000" - ); - }); - - it('should parse input int followed by a fixed bytes type', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int" }, - { type: "bytes" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test(9, 'hello'), - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000009" + - "68656c6c6f000000000000000000000000000000000000000000000000000000" - ); - }); - - it('should parse input fixed bytes type followed by an int', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "bytes" }, - { type: "int" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test('hello', 9), - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000009" + - "68656c6c6f000000000000000000000000000000000000000000000000000000" - ); - }); - - it('should use proper method name', function () { - - // given - var d = clone(description); - d[0].name = 'helloworld(int)'; - d[0].inputs = [ - { type: "int" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.helloworld(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal(parser.helloworld['int'](1), "0000000000000000000000000000000000000000000000000000000000000001"); - - }); - - it('should parse multiple methods', function () { - - // given - var d = [{ - name: "test", - type: "function", - inputs: [{ type: "int" }], - outputs: [{ type: "int" }] - },{ - name: "test2", - type: "function", - inputs: [{ type: "bytes" }], - outputs: [{ type: "bytes" }] - }]; - - // when - var parser = abi.inputParser(d); - - //then - assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); - assert.equal( - parser.test2('hello'), - "000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000" - ); - - }); - - it('should parse input array of ints', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int[]" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test([5, 6]), - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000006" - ); - }); - - it('should parse an array followed by an int', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int[]" }, - { type: "int" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test([5, 6], 3), - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000003" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000006" - ); - }); - - it('should parse an int followed by an array', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int" }, - { type: "int[]" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test(3, [5, 6]), - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000003" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000006" - ); - }); - - it('should parse mixture of arrays and ints', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "int" }, - { type: "int[]" }, - { type: "int" }, - { type: "int[]" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal( - parser.test(3, [5, 6, 1, 2], 7, [8, 9]), - "0000000000000000000000000000000000000000000000000000000000000004" + - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000003" + - "0000000000000000000000000000000000000000000000000000000000000007" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000006" + - "0000000000000000000000000000000000000000000000000000000000000001" + - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000008" + - "0000000000000000000000000000000000000000000000000000000000000009" - ); - }); - - it('should parse input real', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: 'real' } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000100000000000000000000000000000000"); - assert.equal(parser.test(2.125), "0000000000000000000000000000000220000000000000000000000000000000"); - assert.equal(parser.test(8.5), "0000000000000000000000000000000880000000000000000000000000000000"); - assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffff00000000000000000000000000000000"); - - }); - - it('should parse input ureal', function () { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: 'ureal' } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test(1), "0000000000000000000000000000000100000000000000000000000000000000"); - assert.equal(parser.test(2.125), "0000000000000000000000000000000220000000000000000000000000000000"); - assert.equal(parser.test(8.5), "0000000000000000000000000000000880000000000000000000000000000000"); - - }); - - it('should throw an incorrect type error', function () { - - // given - var d = clone(description); - d[0].inputs = [ - { type: 'uin' } - ] - - // when - var parser = abi.inputParser(d); - - // then - assert.throws(function () {parser.test('0x')}, Error); - - }); - - }); -}); diff --git a/abi.outputParser.js b/abi.outputParser.js deleted file mode 100644 index 5fe23e28a..000000000 --- a/abi.outputParser.js +++ /dev/null @@ -1,419 +0,0 @@ -var assert = require('assert'); -var BigNumber = require('bignumber.js'); -var abi = require('../lib/solidity/abi.js'); -var clone = function (object) { return JSON.parse(JSON.stringify(object)); }; - -var description = [{ - "name": "test", - "type": "function", - "inputs": [{ - "name": "a", - "type": "uint256" - } - ], - "outputs": [ - { - "name": "d", - "type": "uint256" - } - ] -}]; - -describe('lib/solidity/abi', function() { - describe('outputParser', function() { - it('should parse output fixed bytes type', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: "bytes" } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal( - parser.test( - "0000000000000000000000000000000000000000000000000000000000000005" + - "68656c6c6f000000000000000000000000000000000000000000000000000000")[0], - 'hello' - ); - assert.equal( - parser.test( - "0000000000000000000000000000000000000000000000000000000000000005" + - "776f726c64000000000000000000000000000000000000000000000000000000")[0], - 'world' - ); - - }); - - it('should parse output uint', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'uint' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10); - assert.equal( - parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10), - new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10) - ); - assert.equal( - parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10), - new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10) - ); - }); - - it('should parse output uint256', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'uint256' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10); - assert.equal( - parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10), - new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10) - ); - assert.equal( - parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10), - new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10) - ); - }); - - it('should parse output uint128', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'uint128' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10); - assert.equal( - parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10), - new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10) - ); - assert.equal( - parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10), - new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10) - ); - }); - - it('should parse output int', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'int' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10); - assert.equal(parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1); - assert.equal(parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); - }); - - it('should parse output int256', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'int256' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10); - assert.equal(parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1); - assert.equal(parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); - }); - - it('should parse output int128', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'int128' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test("000000000000000000000000000000000000000000000000000000000000000a")[0], 10); - assert.equal(parser.test("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1); - assert.equal(parser.test("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); - }); - - it('should parse output address', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'address' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal( - parser.test("000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], - "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - ); - }); - - it('should parse output bool', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'bool' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], true); - assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000000")[0], false); - - - }); - - it('should parse output real', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'real' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000100000000000000000000000000000000")[0], 1); - assert.equal(parser.test("0000000000000000000000000000000220000000000000000000000000000000")[0], 2.125); - assert.equal(parser.test("0000000000000000000000000000000880000000000000000000000000000000")[0], 8.5); - assert.equal(parser.test("ffffffffffffffffffffffffffffffff00000000000000000000000000000000")[0], -1); - - }); - - it('should parse output ureal', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'ureal' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0000000000000000000000000000000100000000000000000000000000000000")[0], 1); - assert.equal(parser.test("0000000000000000000000000000000220000000000000000000000000000000")[0], 2.125); - assert.equal(parser.test("0000000000000000000000000000000880000000000000000000000000000000")[0], 8.5); - - }); - - - it('should parse multiple output fixed bytes type', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: "bytes" }, - { type: "bytes" } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal( - parser.test( - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "68656c6c6f000000000000000000000000000000000000000000000000000000" + - "776f726c64000000000000000000000000000000000000000000000000000000")[0], - 'hello' - ); - assert.equal( - parser.test( - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "68656c6c6f000000000000000000000000000000000000000000000000000000" + - "776f726c64000000000000000000000000000000000000000000000000000000")[1], - 'world' - ); - - }); - - it('should use proper method name', function () { - - // given - var d = clone(description); - d[0].name = 'helloworld(int)'; - d[0].outputs = [ - { type: "int" } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.helloworld("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.helloworld['int']("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); - - }); - - - it('should parse multiple methods', function () { - - // given - var d = [{ - name: "test", - type: "function", - inputs: [{ type: "int" }], - outputs: [{ type: "int" }] - },{ - name: "test2", - type: "function", - inputs: [{ type: "bytes" }], - outputs: [{ type: "bytes" }] - }]; - - // when - var parser = abi.outputParser(d); - - //then - assert.equal(parser.test("00000000000000000000000000000000000000000000000000000000000001")[0], 1); - assert.equal(parser.test2( - "0000000000000000000000000000000000000000000000000000000000000005" + - "68656c6c6f000000000000000000000000000000000000000000000000000000")[0], - "hello" - ); - - }); - - it('should parse output array', function () { - - // given - var d = clone(description); - d[0].outputs = [ - { type: 'int[]' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test( - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000006")[0][0], - 5 - ); - assert.equal(parser.test( - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000005" + - "0000000000000000000000000000000000000000000000000000000000000006")[0][1], - 6 - ); - - }); - - it('should parse 0x0 value', function () { - - // given - var d = clone(description); - d[0].outputs = [ - { type: 'int' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0x0")[0], 0); - - }); - - it('should parse 0x0 value', function () { - - // given - var d = clone(description); - d[0].outputs = [ - { type: 'uint' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal(parser.test("0x0")[0], 0); - - }); - - it('should throw an incorrect type error', function () { - - // given - var d = clone(description); - d[0].outputs = [ - { type: 'uin' } - ] - - // when - var parser = abi.outputParser(d); - - // then - assert.throws(function () {parser.test('0x')}, Error); - - }); - - }); -}); - diff --git a/coder.decodeParam.js b/coder.decodeParam.js index 3eea9dd6f..23b0228eb 100644 --- a/coder.decodeParam.js +++ b/coder.decodeParam.js @@ -21,17 +21,32 @@ describe('lib/solidity/coder', function () { test({ type: 'int256', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'bytes32', expected: 'gavofyork', value: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000009' + + test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); test({ type: 'int[]', expected: [new bn(1), new bn(2), new bn(3)], - value: '0000000000000000000000000000000000000000000000000000000000000003' + + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003'}); + test({ type: 'bool', expected: true, value: '0000000000000000000000000000000000000000000000000000000000000001'}); + test({ type: 'bool', expected: false, value: '0000000000000000000000000000000000000000000000000000000000000000'}); + test({ type: 'real', expected: new bn(1), value: '0000000000000000000000000000000100000000000000000000000000000000'}); + test({ type: 'real', expected: new bn(2.125), value: '0000000000000000000000000000000220000000000000000000000000000000'}); + test({ type: 'real', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'}); + test({ type: 'real', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffff00000000000000000000000000000000'}); + test({ type: 'ureal', expected: new bn(1), value: '0000000000000000000000000000000100000000000000000000000000000000'}); + test({ type: 'ureal', expected: new bn(2.125), value: '0000000000000000000000000000000220000000000000000000000000000000'}); + test({ type: 'ureal', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'}); + test({ type: 'address', expected: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', + value: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'}); }); }); @@ -53,16 +68,18 @@ describe('lib/solidity/coder', function () { '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], expected: [new bn(1), 'gavofyork', new bn(2), new bn(3), new bn(4), [new bn(5), new bn(6), new bn(7)]], - values: '0000000000000000000000000000000000000000000000000000000000000009' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000001' + - '0000000000000000000000000000000000000000000000000000000000000002' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000004' + - '6761766f66796f726b0000000000000000000000000000000000000000000000' + - '0000000000000000000000000000000000000000000000000000000000000005' + - '0000000000000000000000000000000000000000000000000000000000000006' + - '0000000000000000000000000000000000000000000000000000000000000007'}); + values: '0000000000000000000000000000000000000000000000000000000000000001' + + '00000000000000000000000000000000000000000000000000000000000000c0' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000004' + + '0000000000000000000000000000000000000000000000000000000000000100' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000006' + + '0000000000000000000000000000000000000000000000000000000000000007'}); }); }); diff --git a/coder.encodeParam.js b/coder.encodeParam.js index a9e11ab9e..60d1c618e 100644 --- a/coder.encodeParam.js +++ b/coder.encodeParam.js @@ -15,20 +15,37 @@ describe('lib/solidity/coder', function () { test({ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); + test({ type: 'int', value: 0.1, expected: '0000000000000000000000000000000000000000000000000000000000000000'}); + test({ type: 'int', value: 3.9, expected: '0000000000000000000000000000000000000000000000000000000000000003'}); test({ type: 'int256', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int256', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ type: 'bytes32', value: 'gavofyork', expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000009' + + test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000003' + + test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003'}); + test({ type: 'bool', value: true, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); + test({ type: 'bool', value: false, expected: '0000000000000000000000000000000000000000000000000000000000000000'}); + test({ type: 'address', value: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', + expected: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'}); + test({ type: 'real', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'}); + test({ type: 'real', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'}); + test({ type: 'real', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'}); + test({ type: 'real', value: -1, expected: 'ffffffffffffffffffffffffffffffff00000000000000000000000000000000'}); + test({ type: 'ureal', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'}); + test({ type: 'ureal', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'}); + test({ type: 'ureal', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'}); }); }); @@ -49,16 +66,29 @@ describe('lib/solidity/coder', function () { test({ types: ['int256'], values: [16], expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ types: ['int256'], values: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); test({ types: ['bytes32'], values: ['gavofyork'], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000009' + + test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + + test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000003' + + test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003'}); + test({ types: ['int[]', 'int[]'], values: [[1,2], [3,4]], + expected: '0000000000000000000000000000000000000000000000000000000000000040' + + '00000000000000000000000000000000000000000000000000000000000000a0' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000004'}); test({ types: ['bytes32', 'int'], values: ['gavofyork', 5], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000005'}); @@ -66,25 +96,47 @@ describe('lib/solidity/coder', function () { expected: '0000000000000000000000000000000000000000000000000000000000000005' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['bytes', 'int'], values: ['gavofyork', 5], - expected: '0000000000000000000000000000000000000000000000000000000000000009' + + expected: '0000000000000000000000000000000000000000000000000000000000000040' + '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ types: ['bytes', 'bool', 'int[]'], values: ['gavofyork', true, [1, 2, 3]], + expected: '0000000000000000000000000000000000000000000000000000000000000060' + + '0000000000000000000000000000000000000000000000000000000000000001' + + '00000000000000000000000000000000000000000000000000000000000000a0' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000003'}); + test({ types: ['bytes', 'int[]'], values: ['gavofyork', [1, 2, 3]], + expected: '0000000000000000000000000000000000000000000000000000000000000040' + + '0000000000000000000000000000000000000000000000000000000000000080' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000003'}); test({ types: ['int', 'bytes'], values: [5, 'gavofyork'], - expected: '0000000000000000000000000000000000000000000000000000000000000009' + - '0000000000000000000000000000000000000000000000000000000000000005' + + expected: '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]], - expected: '0000000000000000000000000000000000000000000000000000000000000009' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000001' + + expected: '0000000000000000000000000000000000000000000000000000000000000001' + + '00000000000000000000000000000000000000000000000000000000000000c0' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000004' + + '0000000000000000000000000000000000000000000000000000000000000100' + + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000006' + '0000000000000000000000000000000000000000000000000000000000000007'}); - }); }); diff --git a/contract.js b/contract.js index 8a2ea109d..0dcaa1003 100644 --- a/contract.js +++ b/contract.js @@ -345,6 +345,7 @@ describe('web3.eth.contract', function () { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3.slice(0, 10) + + '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003', to: address diff --git a/event.encode.js b/event.encode.js index c28588c2e..6d9850c00 100644 --- a/event.encode.js +++ b/event.encode.js @@ -119,6 +119,32 @@ var tests = [{ ] } }, { + abi: { + name: 'event1', + inputs: [{ + type: 'int', + name: 'a', + indexed: true + }] + }, + indexed: { + a: 1 + }, + options: { + fromBlock: 'latest', + toBlock: 'pending' + }, + expected: { + address: address, + fromBlock: 'latest', + toBlock: 'pending', + topics: [ + signature, + '0x0000000000000000000000000000000000000000000000000000000000000001' + ] + } +}, +{ abi: { name: 'event1', inputs: [{ diff --git a/formatters.inputTransactionFormatter.js b/formatters.inputTransactionFormatter.js index 2f7f8c2e5..44c3534d3 100644 --- a/formatters.inputTransactionFormatter.js +++ b/formatters.inputTransactionFormatter.js @@ -3,24 +3,62 @@ var assert = chai.assert; var formatters = require('../lib/web3/formatters.js'); var BigNumber = require('bignumber.js'); +var tests = [{ + input: { + data: '0x34234bf23bf4234', + value: new BigNumber(100), + from: '0x00000', + to: '0x00000', + nonce: 1000, + gas: 1000, + gasPrice: new BigNumber(1000) + }, + result: { + data: '0x34234bf23bf4234', + value: '0x64', + from: '0x00000', + to: '0x00000', + nonce: '0x3e8', + gas: '0x3e8', + gasPrice: '0x3e8' + } +},{ + input: { + data: '0x34234bf23bf4234', + value: new BigNumber(100), + from: '0x00000', + to: '0x00000', + }, + result: { + data: '0x34234bf23bf4234', + value: '0x64', + from: '0x00000', + to: '0x00000', + } +},{ + input: { + data: '0x34234bf23bf4234', + value: new BigNumber(100), + from: '0x00000', + to: '0x00000', + gas: '1000', + gasPrice: new BigNumber(1000) + }, + result: { + data: '0x34234bf23bf4234', + value: '0x64', + from: '0x00000', + to: '0x00000', + gas: '0x3e8', + gasPrice: '0x3e8' + } +}]; + describe('formatters', function () { describe('inputTransactionFormatter', function () { - it('should return the correct value', function () { - - assert.deepEqual(formatters.inputTransactionFormatter({ - data: '0x34234bf23bf4234', - value: new BigNumber(100), - from: '0x00000', - to: '0x00000', - gas: 1000, - gasPrice: new BigNumber(1000) - }), { - data: '0x34234bf23bf4234', - value: '0x64', - from: '0x00000', - to: '0x00000', - gas: '0x3e8', - gasPrice: '0x3e8' + tests.forEach(function(test){ + it('should return the correct value', function () { + assert.deepEqual(formatters.inputTransactionFormatter(test.input), test.result); }); }); }); diff --git a/web3.eth.filter.js b/web3.eth.filter.js index d8b37311a..7a355b50c 100644 --- a/web3.eth.filter.js +++ b/web3.eth.filter.js @@ -21,6 +21,21 @@ var tests = [{ result: '0xf', formattedResult: '0xf', call: 'eth_newFilter' +},{ + args: [{ + fromBlock: 'latest', + toBlock: 'latest', + address: '0x47d33b27bb249a2dbab4c0612bf9caf4c1950855' + }], + formattedArgs: [{ + fromBlock: 'latest', + toBlock: 'latest', + address: '0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', + topics: [] + }], + result: '0xf', + formattedResult: '0xf', + call: 'eth_newFilter' },{ args: ['pending'], formattedArgs: ['pending'], diff --git a/web3.eth.hashRate.js b/web3.eth.hashRate.js new file mode 100644 index 000000000..ec01bfad1 --- /dev/null +++ b/web3.eth.hashRate.js @@ -0,0 +1,38 @@ +var chai = require('chai'); +var assert = chai.assert; +var web3 = require('../index'); +var FakeHttpProvider = require('./helpers/FakeHttpProvider'); + +var method = 'hashrate'; + +var tests = [{ + result: '0x788a8', + formattedResult: 493736, + call: 'eth_'+ method +}]; + +describe('web3.eth', function () { + describe(method, function () { + tests.forEach(function (test, index) { + it('property test: ' + index, function () { + + // given + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + provider.injectResult(test.result); + provider.injectValidation(function (payload) { + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, test.call); + assert.deepEqual(payload.params, []); + }); + + // when + var result = web3.eth[method]; + + // then + assert.strictEqual(test.formattedResult, result); + }); + }); + }); +}); + From 520dcc7e70f77290318dba6cd62faf371a9f1bee Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Mon, 11 May 2015 12:39:37 +0200 Subject: [PATCH 07/22] Coding Standards fix From cc6647e671044d442a57c92119fabcc902c1a189 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 8 May 2015 12:40:11 +0200 Subject: [PATCH 08/22] Tests. --- libsolidity/SolidityOptimizer.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index 3cb6a536a..4986b1469 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -251,6 +251,27 @@ BOOST_AUTO_TEST_CASE(function_calls) compareVersions("f(uint256)", 36); } +BOOST_AUTO_TEST_CASE(storage_write_in_loops) +{ + char const* sourceCode = R"( + contract test { + uint d; + function f(uint a) returns (uint r) { + var x = d; + for (uint i = 1; i < a * a; i++) { + r = d; + d = i; + } + + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("f(uint256)", 0); + compareVersions("f(uint256)", 10); + compareVersions("f(uint256)", 36); +} + BOOST_AUTO_TEST_CASE(cse_intermediate_swap) { eth::KnownState state; From af9dbf9520ada4155d654f445bac05612d6fc259 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 11 May 2015 14:26:27 +0200 Subject: [PATCH 09/22] reorganize inout Limits tests From 54bc7dda5310b165d0dc2ecbbe5f770cfb290fe5 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 11 May 2015 16:40:28 +0200 Subject: [PATCH 10/22] Compute state intersection. --- libsolidity/SolidityOptimizer.cpp | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index 4986b1469..e50469dd6 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -272,6 +272,42 @@ BOOST_AUTO_TEST_CASE(storage_write_in_loops) compareVersions("f(uint256)", 36); } +BOOST_AUTO_TEST_CASE(retain_information_in_branches) +{ + // This tests that the optimizer knows that we already have "z == sha3(y)" inside both branches. + char const* sourceCode = R"( + contract c { + bytes32 d; + uint a; + function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) { + bytes32 z = sha3(y); + if (x > 8) { + z = sha3(y); + a = x; + } else { + z = sha3(y); + a = x; + } + r_a = a; + r_d = d; + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("f(uint256,bytes32)", 0, "abc"); + compareVersions("f(uint256,bytes32)", 8, "def"); + compareVersions("f(uint256,bytes32)", 10, "ghi"); + + m_optimize = true; + bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c"); + size_t numSHA3s = 0; + eth::eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { + if (_instr == eth::Instruction::SHA3) + numSHA3s++; + }); + BOOST_CHECK_EQUAL(1, numSHA3s); +} + BOOST_AUTO_TEST_CASE(cse_intermediate_swap) { eth::KnownState state; From ccc3d56542d76ce19ce994716e8d7afc339e7472 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 11 May 2015 13:47:21 +0200 Subject: [PATCH 11/22] bug in abi. fixed external type for return parameters --- libsolidity/SolidityABIJSON.cpp | 48 ++++++++++++++++++- libsolidity/SolidityNameAndTypeResolution.cpp | 22 +++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/libsolidity/SolidityABIJSON.cpp b/libsolidity/SolidityABIJSON.cpp index 26d0110b8..6c1025d6a 100644 --- a/libsolidity/SolidityABIJSON.cpp +++ b/libsolidity/SolidityABIJSON.cpp @@ -499,7 +499,8 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { char const* sourceCode = R"( contract test { - function test(uint param1, test param2, bool param3) {} + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test(uint param1, test param2, bool param3, ActionChoices param4) {} } )"; @@ -517,6 +518,51 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { "name": "param3", "type": "bool" + }, + { + "name": "param4", + "type": "uint8" + } + ], + "type": "constructor" + } + ])"; + checkInterface(sourceCode, interface); +} + + +BOOST_AUTO_TEST_CASE(return_param_in_abi) +{ + // bug #1801 + char const* sourceCode = R"( + contract test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function test(ActionChoices param) {} + function ret() returns(ActionChoices){ + ActionChoices action = ActionChoices.GoLeft; + return action; + } + } + )"; + + char const* interface = R"([ + { + "constant" : false, + "inputs" : [], + "name" : "ret", + "outputs" : [ + { + "name" : "", + "type" : "uint8" + } + ], + "type" : "function" + }, + { + "inputs": [ + { + "name": "param", + "type": "uint8" } ], "type": "constructor" diff --git a/libsolidity/SolidityNameAndTypeResolution.cpp b/libsolidity/SolidityNameAndTypeResolution.cpp index c317dad97..c59c1f56f 100644 --- a/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/libsolidity/SolidityNameAndTypeResolution.cpp @@ -508,6 +508,28 @@ BOOST_AUTO_TEST_CASE(function_external_types) } } +BOOST_AUTO_TEST_CASE(enum_external_type) +{ + // bug #1801 + ASTPointer sourceUnit; + char const* text = R"( + contract Test { + enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } + function boo(ActionChoices enumArg) external returns (uint ret) { + ret = 5; + } + })"; + ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed"); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + { + auto functions = contract->getDefinedFunctions(); + if (functions.empty()) + continue; + BOOST_CHECK_EQUAL("boo(uint8)", functions[0]->externalSignature()); + } +} + BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion) { char const* text = R"( From 23925040a11a7b4dad3286a9832822cae8baeb95 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 11 May 2015 16:24:04 +0200 Subject: [PATCH 12/22] updated unit test --- libsolidity/SolidityABIJSON.cpp | 55 +++++++++---------- libsolidity/SolidityNameAndTypeResolution.cpp | 2 +- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/libsolidity/SolidityABIJSON.cpp b/libsolidity/SolidityABIJSON.cpp index 6c1025d6a..fe8b791c5 100644 --- a/libsolidity/SolidityABIJSON.cpp +++ b/libsolidity/SolidityABIJSON.cpp @@ -499,8 +499,7 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { char const* sourceCode = R"( contract test { - enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - function test(uint param1, test param2, bool param3, ActionChoices param4) {} + function test(uint param1, test param2, bool param3) {} } )"; @@ -518,10 +517,6 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { "name": "param3", "type": "bool" - }, - { - "name": "param4", - "type": "uint8" } ], "type": "constructor" @@ -545,29 +540,31 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) } )"; - char const* interface = R"([ - { - "constant" : false, - "inputs" : [], - "name" : "ret", - "outputs" : [ - { - "name" : "", - "type" : "uint8" - } - ], - "type" : "function" - }, - { - "inputs": [ - { - "name": "param", - "type": "uint8" - } - ], - "type": "constructor" - } - ])"; + char const* interface = R"( + [ + { + "constant" : false, + "inputs" : [], + "name" : "ret", + "outputs" : [ + { + "name" : "", + "type" : "uint8" + } + ], + "type" : "function" + }, + { + "inputs": [ + { + "name": "param", + "type": "uint8" + } + ], + "type": "constructor" + } + ] + )"; checkInterface(sourceCode, interface); } diff --git a/libsolidity/SolidityNameAndTypeResolution.cpp b/libsolidity/SolidityNameAndTypeResolution.cpp index c59c1f56f..4ec7b8bda 100644 --- a/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/libsolidity/SolidityNameAndTypeResolution.cpp @@ -516,7 +516,7 @@ BOOST_AUTO_TEST_CASE(enum_external_type) contract Test { enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } function boo(ActionChoices enumArg) external returns (uint ret) { - ret = 5; + ret = 5; } })"; ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed"); From 14b30c87ab7c043028fee1058116b63488d0e128 Mon Sep 17 00:00:00 2001 From: Liana Husikyan Date: Mon, 11 May 2015 17:17:50 +0200 Subject: [PATCH 13/22] Update SolidityABIJSON.cpp --- libsolidity/SolidityABIJSON.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/SolidityABIJSON.cpp b/libsolidity/SolidityABIJSON.cpp index fe8b791c5..f9bf78d0a 100644 --- a/libsolidity/SolidityABIJSON.cpp +++ b/libsolidity/SolidityABIJSON.cpp @@ -546,7 +546,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) "constant" : false, "inputs" : [], "name" : "ret", - "outputs" : [ + "outputs" : [ { "name" : "", "type" : "uint8" From a4d4cf89dacdea17335a41cabc78d382300379ff Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Mon, 11 May 2015 17:27:11 +0200 Subject: [PATCH 14/22] Coding Standards fix From 976b64f66076217c60642675262c9bdea30fc0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 11 May 2015 17:40:00 +0200 Subject: [PATCH 15/22] Create symlink to old testeth location to make bildbot happy --- CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39a235c58..bedbe42f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,12 @@ if (JSONRPC) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) endif() +if (UNIX) # Create symlink to old testeth location to make bildbot happy + add_custom_command(TARGET testeth POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_BINARY_DIR}/bin/testeth ${CMAKE_BINARY_DIR}/test/testeth + ) +endif() + enable_testing() set(CTEST_OUTPUT_ON_FAILURE TRUE) @@ -110,7 +116,6 @@ eth_add_test(ClientBase ) eth_add_test(JsonRpc - ARGS --eth_testfile=BlockTests/bcJS_API_Test + ARGS --eth_testfile=BlockTests/bcJS_API_Test ARGS --eth_testfile=BlockTests/bcValidBlockTest ) - From cf23eea716f16ab05e10c8bb63978083a2cbe5a6 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 10 May 2015 18:22:45 +0300 Subject: [PATCH 16/22] Integrate KeyManager. From e365643edc9ecb3f5e3f9a142ffead87c10b3176 Mon Sep 17 00:00:00 2001 From: Vlad Gluhovsky Date: Mon, 11 May 2015 22:54:12 +0200 Subject: [PATCH 17/22] Fixed warning: unused parameter From 2e169a99472ec8e2f9b4f4cc7ab12fb90a598e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 12 May 2015 09:37:39 +0200 Subject: [PATCH 18/22] testeth: support for --singletest option with only test name param. --- TestHelper.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/TestHelper.cpp b/TestHelper.cpp index e0aad310f..1d7734e35 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -552,6 +552,9 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e void userDefinedTest(std::function doTests) { if (!Options::get().singleTest) + return; + + if (Options::get().singleTestFile.empty() || Options::get().singleTestName.empty()) { cnote << "Missing user test specification\nUsage: testeth --singletest \n"; return; @@ -732,11 +735,23 @@ Options::Options() inputLimits = true; bigData = true; } - else if (arg == "--singletest" && i + 2 < argc) + else if (arg == "--singletest" && i + 1 < argc) { singleTest = true; - singleTestFile = argv[i + 1]; - singleTestName = argv[i + 2]; + auto name1 = std::string{argv[i + 1]}; + if (i + 1 < argc) // two params + { + auto name2 = std::string{argv[i + 2]}; + if (name2[0] == '-') // not param, another option + singleTestName = std::move(name1); + else + { + singleTestFile = std::move(name1); + singleTestName = std::move(name2); + } + } + else + singleTestName = std::move(name1); } } } From 0785602ad5d1a07cba81011669519476a551e516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 12 May 2015 16:14:18 +0200 Subject: [PATCH 19/22] Ping buildbot From ca73a4017054ed33d125b0ee661f8b5682c9538b Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 12 May 2015 16:16:44 +0200 Subject: [PATCH 20/22] Unify blocks with shared code. --- libsolidity/SolidityOptimizer.cpp | 38 ++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index e50469dd6..efc9316b0 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -29,6 +29,7 @@ #include #include #include +#include using namespace std; using namespace dev::eth; @@ -125,7 +126,7 @@ public: BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } - void checkCFG(AssemblyItems const& _input, AssemblyItems const& _expectation) + AssemblyItems getCFG(AssemblyItems const& _input) { AssemblyItems output = _input; // Running it four times should be enough for these tests. @@ -138,6 +139,12 @@ public: back_inserter(optItems)); output = move(optItems); } + return output; + } + + void checkCFG(AssemblyItems const& _input, AssemblyItems const& _expectation) + { + AssemblyItems output = getCFG(_input); BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } @@ -925,6 +932,35 @@ BOOST_AUTO_TEST_CASE(control_flow_graph_do_not_remove_returned_to) checkCFG(input, {u256(2)}); } +BOOST_AUTO_TEST_CASE(block_deduplicator) +{ + AssemblyItems input{ + AssemblyItem(PushTag, 2), + AssemblyItem(PushTag, 1), + AssemblyItem(PushTag, 3), + u256(6), + eth::Instruction::SWAP3, + eth::Instruction::JUMP, + AssemblyItem(Tag, 1), + u256(6), + eth::Instruction::SWAP3, + eth::Instruction::JUMP, + AssemblyItem(Tag, 2), + u256(6), + eth::Instruction::SWAP3, + eth::Instruction::JUMP, + AssemblyItem(Tag, 3) + }; + BlockDeduplicator dedup(input); + dedup.deduplicate(); + + set pushTags; + for (AssemblyItem const& item: input) + if (item.type() == PushTag) + pushTags.insert(item.data()); + BOOST_CHECK_EQUAL(pushTags.size(), 2); +} + BOOST_AUTO_TEST_SUITE_END() } From 43338fac9f1adfdbcb2bdfdb156dd72073d7eb73 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 12 May 2015 17:50:41 +0200 Subject: [PATCH 21/22] Reverse if and else body. --- libsolidity/SolidityCompiler.cpp | 59 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/libsolidity/SolidityCompiler.cpp b/libsolidity/SolidityCompiler.cpp index aa83c4650..dda7847ed 100644 --- a/libsolidity/SolidityCompiler.cpp +++ b/libsolidity/SolidityCompiler.cpp @@ -116,36 +116,35 @@ BOOST_AUTO_TEST_CASE(ifStatement) bytes code = compileContract(sourceCode); unsigned shift = 60; unsigned boilerplateSize = 73; - bytes expectation({byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x0, - byte(Instruction::DUP1), - byte(Instruction::PUSH1), byte(0x1b + shift), // "true" target - byte(Instruction::JUMPI), - // new check "else if" condition - byte(Instruction::DUP1), - byte(Instruction::ISZERO), - byte(Instruction::PUSH1), byte(0x13 + shift), - byte(Instruction::JUMPI), - // "else" body - byte(Instruction::PUSH1), 0x4f, - byte(Instruction::POP), - byte(Instruction::PUSH1), byte(0x17 + shift), // exit path of second part - byte(Instruction::JUMP), - // "else if" body - byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x4e, - byte(Instruction::POP), - byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), byte(0x1f + shift), - byte(Instruction::JUMP), - // "if" body - byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x4d, - byte(Instruction::POP), - byte(Instruction::JUMPDEST), - byte(Instruction::JUMPDEST), - byte(Instruction::POP), - byte(Instruction::JUMP)}); + bytes expectation({ + byte(Instruction::JUMPDEST), + byte(Instruction::PUSH1), 0x0, + byte(Instruction::DUP1), + byte(Instruction::ISZERO), + byte(Instruction::PUSH1), byte(0x0f + shift), // "false" target + byte(Instruction::JUMPI), + // "if" body + byte(Instruction::PUSH1), 0x4d, + byte(Instruction::POP), + byte(Instruction::PUSH1), byte(0x21 + shift), + byte(Instruction::JUMP), + // new check "else if" condition + byte(Instruction::JUMPDEST), + byte(Instruction::DUP1), + byte(Instruction::ISZERO), + byte(Instruction::ISZERO), + byte(Instruction::PUSH1), byte(0x1c + shift), + byte(Instruction::JUMPI), + // "else if" body + byte(Instruction::PUSH1), 0x4e, + byte(Instruction::POP), + byte(Instruction::PUSH1), byte(0x20 + shift), + byte(Instruction::JUMP), + // "else" body + byte(Instruction::JUMPDEST), + byte(Instruction::PUSH1), 0x4f, + byte(Instruction::POP), + }); checkCodePresentAt(code, expectation, boilerplateSize); } From a5fcf4ecd02c6a0b22d4e4c51c962dabf945454c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 13 May 2015 00:26:43 +0300 Subject: [PATCH 22/22] Extra diagnostics, assertions and fail-safes for tracking BadRoot bug.