diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 3a1a22165..4ec917bca 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -976,7 +976,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 ? @@ -1236,13 +1236,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/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 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/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); diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 11400b755..183b2b8de 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); } @@ -1084,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; } } @@ -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 dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con m_stack.pop_back(); break; case Instruction::SIGNEXTEND: - { - unsigned k = m_stack.back(); + if (m_stack.back() < 31) + { + 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(); - auto& b = m_stack.back(); - if (k <= 31) - if ((b >> (k * 8)) & 0x80) - for (int i = 31; i > k; --i) - b |= (u256(0xff) << i); break; - } case Instruction::SHA3: { unsigned inOff = (unsigned)m_stack.back(); 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) 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)); diff --git a/test/vm.cpp b/test/vm.cpp index d69f03fda..76ed41a44 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