From 7c517e6338107830f5469abb73df66dafae1a41c Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 24 Oct 2014 17:39:43 +0200 Subject: [PATCH 01/16] SIGNEXTEND opcode. --- libevm/VM.h | 14 ++++++++++++++ libevmface/Instruction.cpp | 2 ++ libevmface/Instruction.h | 1 + libserpent/opcodes.h | 5 +++-- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index ce8001bbf..1df85ef3c 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -261,6 +261,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::OR: case Instruction::XOR: case Instruction::BYTE: + case Instruction::SIGNEXTEND: case Instruction::JUMPI: require(2); break; @@ -420,6 +421,19 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con m_stack.pop_back(); m_stack.pop_back(); break; + case Instruction::SIGNEXTEND: + if (m_stack.back() < 255) + { + unsigned const bit(m_stack.back()); + u256& number = m_stack[m_stack.size() - 2]; + u256 mask = ((u256(1) << bit) - 1); + if (boost::multiprecision::bit_test(number, bit)) + number |= ~mask; + else + number &= mask; + } + m_stack.pop_back(); + break; case Instruction::SHA3: { unsigned inOff = (unsigned)m_stack.back(); diff --git a/libevmface/Instruction.cpp b/libevmface/Instruction.cpp index 7b253f388..238b21512 100644 --- a/libevmface/Instruction.cpp +++ b/libevmface/Instruction.cpp @@ -52,6 +52,7 @@ const std::map dev::eth::c_instructions = { "BYTE", Instruction::BYTE }, { "ADDMOD", Instruction::ADDMOD }, { "MULMOD", Instruction::MULMOD }, + { "SIGNEXTEND", Instruction::SIGNEXTEND }, { "SHA3", Instruction::SHA3 }, { "ADDRESS", Instruction::ADDRESS }, { "BALANCE", Instruction::BALANCE }, @@ -179,6 +180,7 @@ static const std::map c_instructionInfo = { Instruction::BYTE, { "BYTE", 0, 2, 1 } }, { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1 } }, { Instruction::MULMOD, { "MULMOD", 0, 3, 1 } }, + { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1 } }, { Instruction::SHA3, { "SHA3", 0, 2, 1 } }, { Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } }, { Instruction::BALANCE, { "BALANCE", 0, 1, 1 } }, diff --git a/libevmface/Instruction.h b/libevmface/Instruction.h index b6aa477b1..ce587dfaf 100644 --- a/libevmface/Instruction.h +++ b/libevmface/Instruction.h @@ -58,6 +58,7 @@ enum class Instruction: uint8_t BYTE, ///< retrieve single byte from word ADDMOD, ///< unsigned modular addition MULMOD, ///< unsigned modular multiplication + SIGNEXTEND, ///< perform sign extension starting at given bit SHA3 = 0x20, ///< compute SHA3-256 hash ADDRESS = 0x30, ///< get address of currently executing account diff --git a/libserpent/opcodes.h b/libserpent/opcodes.h index f55834efa..63031130e 100644 --- a/libserpent/opcodes.h +++ b/libserpent/opcodes.h @@ -42,8 +42,9 @@ Mapping mapping[] = { Mapping("XOR", 0x12, 2, 1), Mapping("BYTE", 0x13, 2, 1), Mapping("ADDMOD", 0x14, 3, 1), - Mapping("MULMOD", 0x15, 3, 1), - Mapping("SHA3", 0x20, 2, 1), + Mapping("MULMOD", 0x15, 3, 1), + Mapping("SIGNEXTEND", 0x16, 2, 1), + Mapping("SHA3", 0x20, 2, 1), Mapping("ADDRESS", 0x30, 0, 1), Mapping("BALANCE", 0x31, 1, 1), Mapping("ORIGIN", 0x32, 0, 1), From 2f6a20cbb1650ec7d3d9824dc6ac7c73b7e0bb1d Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Mon, 27 Oct 2014 12:45:29 +0100 Subject: [PATCH 02/16] Add VMTRACE to user defined vm test --- test/vm.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++--- test/vm.h | 3 +++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index 2e4571be5..572af2266 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -20,9 +20,9 @@ * vm test functions. */ -#include "vm.h" -#include #include +#include +#include "vm.h" //#define FILL_TESTS @@ -418,6 +418,26 @@ void FakeExtVM::importCallCreates(mArray& _callcreates) } } +OnOpFunc FakeExtVM::simpleTrace() +{ + return [](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, void* voidVM, void const* voidExt) + { + FakeExtVM const& ext = *(FakeExtVM const*)voidExt; + VM& vm = *(VM*)voidVM; + + ostringstream o; + o << endl << " STACK" << endl; + for (auto i: vm.stack()) + o << (h256)i << endl; + o << " MEMORY" << endl << memDump(vm.memory()); + o << " STORAGE" << endl; + for (auto const& i: ext.state().storage(ext.myAddress)) + o << showbase << hex << i.first << ": " << i.second << endl; + dev::LogOutputStream(true) << o.str(); + dev::LogOutputStream(false) << " | " << dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << dec << vm.gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32" << " ]"; + }; +} + h160 FakeState::createNewAddress(Address _newAddress, Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, std::set
* o_suicides, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level) { if (!_origin) @@ -484,6 +504,7 @@ h160 FakeState::createNewAddress(Address _newAddress, Address _sender, u256 _end + namespace dev { namespace test { void doTests(json_spirit::mValue& v, bool _fillin) @@ -515,7 +536,7 @@ void doTests(json_spirit::mValue& v, bool _fillin) VM vm(fev.gas); try { - output = vm.go(fev).toVector(); + output = vm.go(fev, fev.simpleTrace()).toVector(); } catch (Exception const& _e) { @@ -751,3 +772,30 @@ BOOST_AUTO_TEST_CASE(vmSystemOperationsTest) { dev::test::executeTests("vmSystemOperationsTest"); } + +BOOST_AUTO_TEST_CASE(userDefinedFile) +{ + + if (boost::unit_test::framework::master_test_suite().argc == 2) + { + string filename = boost::unit_test::framework::master_test_suite().argv[1]; + g_logVerbosity = 12; + try + { + cnote << "Testing VM..." << "user defined test"; + 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); + dev::test::doTests(v, false); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed VM Test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed VM Test with Exception: " << _e.what()); + } + } +} diff --git a/test/vm.h b/test/vm.h index d9dca1d7a..baf5986bc 100644 --- a/test/vm.h +++ b/test/vm.h @@ -80,6 +80,9 @@ public: json_spirit::mArray exportCallCreates(); void importCallCreates(json_spirit::mArray& _callcreates); + static eth::OnOpFunc simpleTrace(); + FakeState state() const { return m_s; } + std::map, bytes>> addresses; eth::Transactions callcreates; bytes thisTxData; From d045b281cee2fc438bfdaaeed96dde537234aeae Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Mon, 27 Oct 2014 13:54:59 +0100 Subject: [PATCH 03/16] VMTRACE for internal calls --- test/vm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vm.cpp b/test/vm.cpp index 572af2266..cb97dff9c 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -131,7 +131,7 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, m_ms.internal.resize(m_ms.internal.size() + 1); - auto ret = m_s.call(_receiveAddress,_codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _value, gasPrice, _data, _gas, _out, origin, &suicides, &(m_ms.internal.back()), OnOpFunc(), 1); + auto ret = m_s.call(_receiveAddress,_codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _value, gasPrice, _data, _gas, _out, origin, &suicides, &(m_ms.internal.back()), Executive::simpleTrace(), 1); if (!m_ms.internal.back().from) m_ms.internal.pop_back(); From 20ce32d4dc2db21afecf2755f9baf522b7dd9bd2 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 27 Oct 2014 16:54:50 +0100 Subject: [PATCH 04/16] Interpret the second argument as byte number, not bit number. --- libevm/VM.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index 1df85ef3c..eed1988bb 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -422,12 +422,12 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con m_stack.pop_back(); break; case Instruction::SIGNEXTEND: - if (m_stack.back() < 255) + if (m_stack.back() < 31) { - unsigned const bit(m_stack.back()); + unsigned const testBit(m_stack.back() * 8 + 7); u256& number = m_stack[m_stack.size() - 2]; - u256 mask = ((u256(1) << bit) - 1); - if (boost::multiprecision::bit_test(number, bit)) + u256 mask = ((u256(1) << testBit) - 1); + if (boost::multiprecision::bit_test(number, testBit)) number |= ~mask; else number &= mask; From f8bf9b4f1213c99f1f4267e9ce4fe324400fd8b1 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Mon, 27 Oct 2014 17:04:18 +0100 Subject: [PATCH 05/16] use ETHEREUM_TEST_PATH in all tests --- test/genesis.cpp | 13 ++++++++++++- test/hexPrefix.cpp | 13 ++++++++++++- test/rlp.cpp | 13 ++++++++++++- test/trie.cpp | 13 ++++++++++++- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/test/genesis.cpp b/test/genesis.cpp index 5f17d2762..16ffb1859 100644 --- a/test/genesis.cpp +++ b/test/genesis.cpp @@ -35,9 +35,20 @@ namespace js = json_spirit; BOOST_AUTO_TEST_CASE(genesis_tests) { + const char* ptestPath = getenv("ETHEREUM_TEST_PATH"); + string testPath; + + if (ptestPath == NULL) + { + cnote << " could not find environment variable ETHEREUM_TEST_PATH \n"; + testPath = "../../../tests"; + } + else + testPath = ptestPath; + cnote << "Testing Genesis block..."; js::mValue v; - string s = asString(contents("../../../tests/genesishashestest.json")); + string s = asString(contents(testPath + "/genesishashestest.json")); BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'genesishashestest.json' is empty. Have you cloned the 'tests' repo branch develop?"); js::read_string(s, v); diff --git a/test/hexPrefix.cpp b/test/hexPrefix.cpp index fb2fbc826..99207ab97 100644 --- a/test/hexPrefix.cpp +++ b/test/hexPrefix.cpp @@ -33,9 +33,20 @@ namespace js = json_spirit; BOOST_AUTO_TEST_CASE(hexPrefix_test) { + const char* ptestPath = getenv("ETHEREUM_TEST_PATH"); + string testPath; + + if (ptestPath == NULL) + { + cnote << " could not find environment variable ETHEREUM_TEST_PATH \n"; + testPath = "../../../tests"; + } + else + testPath = ptestPath; + cnote << "Testing Hex-Prefix-Encode..."; js::mValue v; - string s = asString(contents("../../../tests/hexencodetest.json")); + string s = asString(contents(testPath + "/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()) diff --git a/test/rlp.cpp b/test/rlp.cpp index 69360ad66..608a8499e 100644 --- a/test/rlp.cpp +++ b/test/rlp.cpp @@ -61,7 +61,18 @@ namespace dev static void getRLPTestCases(js::mValue& v) { - string s = asString(contents("../../../tests/rlptest.json")); + const char* ptestPath = getenv("ETHEREUM_TEST_PATH"); + string testPath; + + if (ptestPath == NULL) + { + cnote << " could not find environment variable ETHEREUM_TEST_PATH \n"; + testPath = "../../../tests"; + } + else + testPath = ptestPath; + + string s = asString(contents(testPath + "/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); diff --git a/test/trie.cpp b/test/trie.cpp index 899eb1f60..f8ebd10c8 100644 --- a/test/trie.cpp +++ b/test/trie.cpp @@ -49,9 +49,20 @@ static unsigned fac(unsigned _i) BOOST_AUTO_TEST_CASE(trie_tests) { + const char* ptestPath = getenv("ETHEREUM_TEST_PATH"); + string testPath; + + if (ptestPath == NULL) + { + cnote << " could not find environment variable ETHEREUM_TEST_PATH \n"; + testPath = "../../../tests"; + } + else + testPath = ptestPath; + cnote << "Testing Trie..."; js::mValue v; - string s = asString(contents("../../../tests/trietest.json")); + string s = asString(contents(testPath + "/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()) From 68328e90d175a289660179b0d4462e276e3fe094 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Mon, 27 Oct 2014 17:23:17 +0100 Subject: [PATCH 06/16] bugfix --- test/vm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vm.cpp b/test/vm.cpp index cb97dff9c..13efa18e3 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -56,7 +56,7 @@ h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFun get<3>(addresses[ret]) = m_s.code(ret); } - t.receiveAddress = ret; + t.receiveAddress = Address(); callcreates.push_back(t); return ret; } From 372936172bd6e4d4b6fe8a1840a14a96b0c2763a Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Tue, 28 Oct 2014 08:50:05 +0100 Subject: [PATCH 07/16] Added tests for SIGNEXTEND and BNOT --- test/vmArithmeticTestFiller.json | 12 +- test/vmBitwiseLogicOperationTestFiller.json | 280 ++++++++++++++++++++ 2 files changed, 286 insertions(+), 6 deletions(-) diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json index 9e9538386..97bf57b8e 100644 --- a/test/vmArithmeticTestFiller.json +++ b/test/vmArithmeticTestFiller.json @@ -1332,7 +1332,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (NEG 0 )}", + "code" : "{ [[ 0 ]] (BNOT 0 )}", "storage": {} } }, @@ -1360,7 +1360,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (NEG 2 )}", + "code" : "{ [[ 0 ]] (BNOT 2 )}", "storage": {} } }, @@ -1388,7 +1388,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (NEG 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", + "code" : "{ [[ 0 ]] (BNOT 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } }, @@ -1416,7 +1416,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (NEG (- 0 2) )}", + "code" : "{ [[ 0 ]] (BNOT (- 0 2) )}", "storage": {} } }, @@ -1444,7 +1444,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (NEG (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) )}", + "code" : "{ [[ 0 ]] (BNOT (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) )}", "storage": {} } }, @@ -1472,7 +1472,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (NEG (- 0 0) )}", + "code" : "{ [[ 0 ]] (BNOT (- 0 0) )}", "storage": {} } }, diff --git a/test/vmBitwiseLogicOperationTestFiller.json b/test/vmBitwiseLogicOperationTestFiller.json index ee00d9784..58882a8ad 100644 --- a/test/vmBitwiseLogicOperationTestFiller.json +++ b/test/vmBitwiseLogicOperationTestFiller.json @@ -1224,6 +1224,286 @@ "gasPrice" : "100000000000000", "gas" : "10000" } + }, + + "signextend0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x61122f600516600057", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x61121f600516600057", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x61122f600016600057", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x611220600516600057", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend4": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x6112206101ff16600057", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend5": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (SIGNEXTEND 0 0) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend6": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (SIGNEXTEND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend6": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (SIGNEXTEND 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend7": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (SIGNEXTEND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + + "signextend8": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (SIGNEXTEND 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } } } From a03e7ab8a8bd349ff6cb3b6348469b78a492454b Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Tue, 28 Oct 2014 12:11:52 +0100 Subject: [PATCH 08/16] Fixed storage output in VMTRACE for vm tests --- test/vm.cpp | 37 +++++++++++++++++++++++++++++++++++-- test/vm.h | 29 ----------------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index 40a0a862b..e6c82349c 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -130,7 +130,7 @@ bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, m_ms.internal.resize(m_ms.internal.size() + 1); - auto ret = m_s.call(_receiveAddress,_codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _value, gasPrice, _data, _gas, _out, origin, &sub, &(m_ms.internal.back()), simpleTrace(), 1); + auto ret = m_s.call(_receiveAddress,_codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _value, gasPrice, _data, _gas, _out, origin, &sub, &(m_ms.internal.back()), Executive::simpleTrace(), 1); if (!m_ms.internal.back().from) m_ms.internal.pop_back(); @@ -421,6 +421,39 @@ void FakeExtVM::importCallCreates(mArray& _callcreates) } } +eth::OnOpFunc FakeExtVM::simpleTrace() +{ + return [](uint64_t steps, eth::Instruction inst, bigint newMemSize, bigint gasCost, void* voidVM, void const* voidExt) + { + FakeExtVM const& ext = *(FakeExtVM const*)voidExt; + eth::VM& vm = *(eth::VM*)voidVM; + + std::ostringstream o; + o << std::endl << " STACK" << std::endl; + for (auto i: vm.stack()) + o << (h256)i << std::endl; + o << " MEMORY" << std::endl << memDump(vm.memory()); + o << " STORAGE" << std::endl; + + for (auto const& i: ext.state().storage(ext.myAddress)) + o << std::showbase << std::hex << i.first << ": " << i.second << std::endl; + + for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second)) + o << std::showbase << std::hex << i.first << ": " << i.second << std::endl; + + dev::LogOutputStream(true) << o.str(); + dev::LogOutputStream(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]"; + + if (eth::VMTraceChannel::verbosity <= g_logVerbosity) + { + std::ofstream f; + f.open("./vmtrace.log", std::ofstream::app); + f << o.str(); + f << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32"; + } + }; +} + // THIS IS BROKEN AND NEEDS TO BE REMOVED. h160 FakeState::createNewAddress(Address _newAddress, Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, SubState* o_sub, Manifest* o_ms, OnOpFunc const& _onOp, unsigned _level) { @@ -517,7 +550,7 @@ void doTests(json_spirit::mValue& v, bool _fillin) VM vm(fev.gas); try { - output = vm.go(fev, fev.simpleTrace()).toVector(); + output = vm.go(fev, fev.simpleTrace()).toVector(); } catch (Exception const& _e) { diff --git a/test/vm.h b/test/vm.h index f3aae694a..ddc6ddb3e 100644 --- a/test/vm.h +++ b/test/vm.h @@ -81,9 +81,7 @@ public: json_spirit::mArray exportCallCreates(); void importCallCreates(json_spirit::mArray& _callcreates); - template eth::OnOpFunc simpleTrace(); - FakeState state() const { return m_s; } std::map, bytes>> addresses; @@ -97,32 +95,5 @@ private: eth::Manifest m_ms; }; -template -eth::OnOpFunc FakeExtVM::simpleTrace() -{ - return [](uint64_t steps, eth::Instruction inst, bigint newMemSize, bigint gasCost, void* voidVM, void const* voidExt) - { - ExtVMType const& ext = *(ExtVMType const*)voidExt; - eth::VM& vm = *(eth::VM*)voidVM; - - std::ostringstream o; - o << std::endl << " STACK" << std::endl; - for (auto i: vm.stack()) - o << (h256)i << std::endl; - o << " MEMORY" << std::endl << memDump(vm.memory()); - o << " STORAGE" << std::endl; - for (auto const& i: ext.state().storage(ext.myAddress)) - o << std::showbase << std::hex << i.first << ": " << i.second << std::endl; - dev::LogOutputStream(true) << o.str(); - dev::LogOutputStream(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]"; - if (eth::VMTraceChannel::verbosity <= g_logVerbosity) - { - std::ofstream f; - f.open("./vmtrace.log", std::ofstream::app); - f << o.str(); - f << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32"; - } - }; -} } } // Namespace Close From a89e2def348f33a98ac636bbdae46dd026a501ae Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Tue, 28 Oct 2014 12:17:53 +0100 Subject: [PATCH 09/16] merge --- libserpent/opcodes.h | 5 +- test/vmArithmeticTestFiller.json | 12 +- test/vmBitwiseLogicOperationTestFiller.json | 280 -------------------- 3 files changed, 8 insertions(+), 289 deletions(-) diff --git a/libserpent/opcodes.h b/libserpent/opcodes.h index f02a5aa6d..552364731 100644 --- a/libserpent/opcodes.h +++ b/libserpent/opcodes.h @@ -42,9 +42,8 @@ Mapping mapping[] = { Mapping("XOR", 0x12, 2, 1), Mapping("BYTE", 0x13, 2, 1), Mapping("ADDMOD", 0x14, 3, 1), - Mapping("MULMOD", 0x15, 3, 1), - Mapping("SIGNEXTEND", 0x16, 2, 1), - Mapping("SHA3", 0x20, 2, 1), + Mapping("MULMOD", 0x15, 3, 1), + Mapping("SHA3", 0x20, 2, 1), Mapping("ADDRESS", 0x30, 0, 1), Mapping("BALANCE", 0x31, 1, 1), Mapping("ORIGIN", 0x32, 0, 1), diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json index 97bf57b8e..9e9538386 100644 --- a/test/vmArithmeticTestFiller.json +++ b/test/vmArithmeticTestFiller.json @@ -1332,7 +1332,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (BNOT 0 )}", + "code" : "{ [[ 0 ]] (NEG 0 )}", "storage": {} } }, @@ -1360,7 +1360,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (BNOT 2 )}", + "code" : "{ [[ 0 ]] (NEG 2 )}", "storage": {} } }, @@ -1388,7 +1388,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (BNOT 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", + "code" : "{ [[ 0 ]] (NEG 115792089237316195423570985008687907853269984665640564039457584007913129639935 )}", "storage": {} } }, @@ -1416,7 +1416,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (BNOT (- 0 2) )}", + "code" : "{ [[ 0 ]] (NEG (- 0 2) )}", "storage": {} } }, @@ -1444,7 +1444,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (BNOT (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) )}", + "code" : "{ [[ 0 ]] (NEG (- 0 115792089237316195423570985008687907853269984665640564039457584007913129639935) )}", "storage": {} } }, @@ -1472,7 +1472,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : 0, - "code" : "{ [[ 0 ]] (BNOT (- 0 0) )}", + "code" : "{ [[ 0 ]] (NEG (- 0 0) )}", "storage": {} } }, diff --git a/test/vmBitwiseLogicOperationTestFiller.json b/test/vmBitwiseLogicOperationTestFiller.json index 58882a8ad..ee00d9784 100644 --- a/test/vmBitwiseLogicOperationTestFiller.json +++ b/test/vmBitwiseLogicOperationTestFiller.json @@ -1224,286 +1224,6 @@ "gasPrice" : "100000000000000", "gas" : "10000" } - }, - - "signextend0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "0x61122f600516600057", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "0x61121f600516600057", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "0x61122f600016600057", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "0x611220600516600057", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend4": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "0x6112206101ff16600057", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend5": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "{ [[ 0 ]] (SIGNEXTEND 0 0) } ", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend6": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "{ [[ 0 ]] (SIGNEXTEND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0) } ", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend6": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "{ [[ 0 ]] (SIGNEXTEND 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend7": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "{ [[ 0 ]] (SIGNEXTEND 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) } ", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - }, - - "signextend8": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : 0, - "code" : "{ [[ 0 ]] (SIGNEXTEND 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) } ", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } } } From d359afe34b68fb39c9016634674eb1eb106f0d36 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 28 Oct 2014 13:28:17 +0100 Subject: [PATCH 10/16] Reverse operators for SIGNEXTEND and bugfix for k > 2**64. --- libevm/VM.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index e81ddb475..85a623b71 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -449,16 +449,15 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::SIGNEXTEND: { - unsigned k = m_stack[m_stack.size() - 2]; - if (k > 31) - m_stack[m_stack.size() - 2] = m_stack.back(); - else + if (m_stack.back() < 31) { - u256 b = m_stack.back(); - if ((b >> (k * 8)) & 0x80) - for (int i = 31; i > k; --i) - b |= (u256(0xff) << i); - m_stack[m_stack.size() - 2] = b; + unsigned const testBit(m_stack.back() * 8 + 7); + u256& number = m_stack[m_stack.size() - 2]; + u256 mask = ((u256(1) << testBit) - 1); + if (boost::multiprecision::bit_test(number, testBit)) + number |= ~mask; + else + number &= mask; } m_stack.pop_back(); break; From 0baf92d52e4eb311836c40a44db612afa5eda1ff Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 29 Oct 2014 12:59:06 +0100 Subject: [PATCH 11/16] Parser fix: Consume break and continue. --- libsolidity/Parser.cpp | 2 ++ test/solidityParser.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 1ea413ee9..44f0a54ad 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -266,9 +266,11 @@ ASTPointer Parser::parseStatement() // starting from here, all statements must be terminated by a semicolon case Token::CONTINUE: statement = ASTNodeFactory(*this).createNode(); + m_scanner->next(); break; case Token::BREAK: statement = ASTNodeFactory(*this).createNode(); + m_scanner->next(); break; case Token::RETURN: { diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index 025cd74d1..701a6e76c 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(while_loop) { char const* text = "contract test {\n" " function fun(uint256 a) {\n" - " uint256 x = (1 + 4).member(++67) || true;\n" + " while (true) { uint256 x = 1; break; continue; } x = 9;\n" " }\n" "}\n"; BOOST_CHECK_NO_THROW(parseText(text)); From 1d3b26617abe72cc422e2a79a414e8e213b75a2d Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 29 Oct 2014 00:13:26 +0100 Subject: [PATCH 12/16] Bugfix: Tag takes one byte (for JUMPDEST) --- liblll/Assembly.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liblll/Assembly.cpp b/liblll/Assembly.cpp index 5b10138d1..7ad84682f 100644 --- a/liblll/Assembly.cpp +++ b/liblll/Assembly.cpp @@ -54,6 +54,7 @@ unsigned Assembly::bytesRequired() const switch (i.m_type) { case Operation: + case Tag: // 1 byte for the JUMPDEST ret++; break; case PushString: @@ -69,7 +70,6 @@ unsigned Assembly::bytesRequired() const case PushData: case PushSub: ret += 1 + br; - case Tag:; default:; } if (dev::bytesRequired(ret) <= br) From b87bde0f310f03922206887fc5acd134f5603f67 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 29 Oct 2014 14:03:58 +0100 Subject: [PATCH 13/16] Updated genesis block to new block format. --- alethzero/MainWin.cpp | 6 +++--- libdevcore/Common.cpp | 2 +- libethcore/CommonEth.cpp | 2 +- libethereum/AddressState.h | 24 +++++++++++++++++------- libethereum/BlockChain.cpp | 2 +- libethereum/State.cpp | 20 ++++++++++++-------- libethereum/State.h | 8 ++++++-- 7 files changed, 41 insertions(+), 23 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 4da7026fe..2853536b9 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -974,7 +974,7 @@ void Main::refreshBlockChain() auto b = bc.block(h); for (auto const& i: RLP(b)[1]) { - Transaction t(i[0].data()); + Transaction t(i.data()); if (bm || transactionMatch(filter, t)) { QString s = t.receiveAddress ? @@ -1235,13 +1235,13 @@ void Main::on_blocks_currentItemChanged() else s << "
Pre: Nothing is before the Gensesis"; for (auto const& i: block[1]) - s << "
" << sha3(i[0].data()).abridged() << ": " << i[1].toHash() << " [" << i[2].toInt() << " used]"; + s << "
" << sha3(i.data()).abridged();// << ": " << i[1].toHash() << " [" << i[2].toInt() << " used]"; s << "
Post: " << info.stateRoot << ""; } else { unsigned txi = item->data(Qt::UserRole + 1).toInt(); - Transaction tx(block[1][txi][0].data()); + Transaction tx(block[1][txi].data()); auto ss = tx.safeSender(); h256 th = sha3(rlpList(ss, tx.nonce)); s << "

" << th << "

"; diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index a32125354..9d2ae55d7 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.7.7"; +char const* Version = "0.7.8"; } diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 44ebe19c5..e7223d896 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -34,7 +34,7 @@ namespace dev namespace eth { -const unsigned c_protocolVersion = 37; +const unsigned c_protocolVersion = 38; const unsigned c_databaseVersion = 3; static const vector> g_units = diff --git a/libethereum/AddressState.h b/libethereum/AddressState.h index 668e9225f..8b4505909 100644 --- a/libethereum/AddressState.h +++ b/libethereum/AddressState.h @@ -23,6 +23,7 @@ #include #include +#include #include namespace dev @@ -35,10 +36,19 @@ namespace eth class AddressState { public: - AddressState(): m_isAlive(false), m_nonce(0), m_balance(0) {} + enum NewAccountType { NormalCreation, ContractConception }; + + /// Construct a dead AddressState. + AddressState() {} + /// Construct an alive AddressState, with given endowment, for either a normal (non-contract) account or for a contract account in the + /// conception phase, where the code is not yet known. + AddressState(u256 _balance, NewAccountType _t): m_isAlive(true), m_balance(_balance), m_codeHash(_t == NormalCreation ? h256() : EmptySHA3) {} + /// Explicit constructor for wierd cases of construction of a normal account. + AddressState(u256 _nonce, u256 _balance): m_isAlive(true), m_nonce(_nonce), m_balance(_balance) {} + /// Explicit constructor for wierd cases of construction or a contract account. AddressState(u256 _nonce, u256 _balance, h256 _contractRoot, h256 _codeHash): m_isAlive(true), m_nonce(_nonce), m_balance(_balance), m_storageRoot(_contractRoot), m_codeHash(_codeHash) {} - void kill() { m_isAlive = false; m_storageOverlay.clear(); m_codeHash = EmptySHA3; m_storageRoot = h256(); m_balance = 0; m_nonce = 0; } + void kill() { m_isAlive = false; m_storageOverlay.clear(); m_codeHash = EmptySHA3; m_storageRoot = EmptyTrie; m_balance = 0; m_nonce = 0; } bool isAlive() const { return m_isAlive; } u256& balance() { return m_balance; } @@ -62,17 +72,17 @@ public: void noteCode(bytesConstRef _code) { assert(sha3(_code) == m_codeHash); m_codeCache = _code.toBytes(); } private: - bool m_isAlive; - u256 m_nonce; - u256 m_balance; + bool m_isAlive = false; + u256 m_nonce = 0; + u256 m_balance = 0; /// The base storage root. Used with the state DB to give a base to the storage. m_storageOverlay is overlaid on this and takes precedence for all values set. - h256 m_storageRoot; + h256 m_storageRoot = EmptyTrie; /// If 0 then we're in the limbo where we're running the initialisation code. We expect a setCode() at some point later. /// If EmptySHA3, then m_code, which should be empty, is valid. /// If anything else, then m_code is valid iff it's not empty, otherwise, State::ensureCached() needs to be called with the correct args. - h256 m_codeHash; + h256 m_codeHash = EmptySHA3; // TODO: change to unordered_map. std::map m_storageOverlay; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index a9bdbf247..9672f722c 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -67,7 +67,7 @@ std::map const& dev::eth::genesisState() "6c386a4b26f73c802f34673f7248bb118f97424a", "e4157b34ea9615cfbde6b4fda419828124b70c78" })) - s_ret[Address(fromHex(i))] = AddressState(0, u256(1) << 200, h256(), EmptySHA3); + s_ret[Address(fromHex(i))] = AddressState(u256(1) << 200, AddressState::NormalCreation); return s_ret; } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 11400b755..e823a95a7 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -324,6 +324,9 @@ StateDiff State::diff(State const& _c) const for (auto i: _c.m_cache) ads.insert(i.first); + cnote << *this; + cnote << _c; + for (auto i: ads) { auto it = m_cache.find(i); @@ -355,7 +358,7 @@ void State::ensureCached(std::map& _cache, Address _a, bo RLP state(stateBack); AddressState s; if (state.isNull()) - s = AddressState(0, 0, EmptyTrie, EmptySHA3); + s = AddressState(0, AddressState::NormalCreation); else s = AddressState(state[0].toInt(), state[1].toInt(), state[2].toHash(), state[3].toHash()); bool ok; @@ -622,8 +625,6 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce) RLPStream k; k << i; - RLPStream txrlp; - m_transactions[i].streamRLP(txrlp); transactionsTrie.insert(&k.out(), tr.data()); // cnote << m_state.root() << m_state; @@ -960,8 +961,12 @@ void State::noteSending(Address _id) { ensureCached(_id, false, false); auto it = m_cache.find(_id); - if (it == m_cache.end()) - m_cache[_id] = AddressState(1, 0, h256(), EmptySHA3); + if (asserts(it != m_cache.end())) + { + cwarn << "Sending from non-existant account. How did it pay!?!"; + // this is impossible. but we'll continue regardless... + m_cache[_id] = AddressState(1, 0); + } else it->second.incNonce(); } @@ -971,7 +976,7 @@ void State::addBalance(Address _id, u256 _amount) ensureCached(_id, false, false); auto it = m_cache.find(_id); if (it == m_cache.end()) - m_cache[_id] = AddressState(0, _amount, h256(), EmptySHA3); + m_cache[_id] = AddressState(_amount, AddressState::NormalCreation); else it->second.addBalance(_amount); } @@ -1262,7 +1267,7 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, Address newAddress = right160(sha3(rlpList(_sender, transactionsFrom(_sender) - 1))); // Set up new account... - m_cache[newAddress] = AddressState(0, balance(newAddress) + _endowment, h256(), h256()); + m_cache[newAddress] = AddressState(balance(newAddress) + _endowment, AddressState::ContractConception); // Execute init code. VM vm(*_gas); @@ -1376,7 +1381,6 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s) stringstream contout; - /// For POC6, 3rd value of account is code and will be empty if code is not present. if ((cache && cache->codeBearing()) || (!cache && r && !r[3].isEmpty())) { std::map mem; diff --git a/libethereum/State.h b/libethereum/State.h index b32bb6c7c..a90812880 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -376,7 +376,10 @@ void commit(std::map const& _cache, DB& _db, TrieDB storageDB(&_db, i.second.baseRoot()); @@ -385,7 +388,8 @@ void commit(std::map const& _cache, DB& _db, TrieDB Date: Wed, 29 Oct 2014 20:03:32 +0100 Subject: [PATCH 14/16] Update astyle options: - "delete-empty-lines" removed as it removes single empty lines also - "keep-one-line-blocks" added to keep one-line inline methods implementations - "close-templates" added - places template angle bracket together --- astylerc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/astylerc b/astylerc index 0b407b9fe..d4e1188eb 100644 --- a/astylerc +++ b/astylerc @@ -6,6 +6,6 @@ min-conditional-indent=1 pad-oper pad-header unpad-paren -delete-empty-lines align-pointer=type - +keep-one-line-blocks +close-templates From 37fc024c0b2b98bf3fcebaf0597e75f8f1d6bd40 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 29 Oct 2014 21:48:02 +0100 Subject: [PATCH 15/16] Paranoia mode fixed for the new trie format. --- libethereum/State.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index e823a95a7..183b2b8de 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1089,7 +1089,7 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const RLP r(i.second); TrieDB storageDB(const_cast(&m_db), r[2].toHash()); // promise not to alter OverlayDB. for (auto const& j: storageDB) { (void)j; } - if (!e && r[3].toHash() && m_db.lookup(r[3].toHash()).empty()) + if (!e && r[3].toHash() != EmptySHA3 && m_db.lookup(r[3].toHash()).empty()) return false; } } From 9faa42dfdad56994bb43fb418209f2003f63d55e Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 30 Oct 2014 02:27:33 +0100 Subject: [PATCH 16/16] h256 to EmtpryTrie when creating contract --- libethereum/Executive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 5a983b66e..8f52b4c36 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -138,7 +138,7 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1))); // Set up new account... - m_s.m_cache[m_newAddress] = AddressState(0, m_s.balance(m_newAddress) + _endowment, h256(), h256()); + m_s.m_cache[m_newAddress] = AddressState(0, m_s.balance(m_newAddress) + _endowment, EmptyTrie, h256()); // Execute _init. m_vm = new VM(_gas);