diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 5455c27ea..89768f559 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1257,10 +1257,10 @@ void Main::populateDebugger(dev::bytesConstRef _r) if (!m_codes.count(lastDataHash)) m_codes[lastDataHash] = ext.data.toBytes(); } - if (levels.size() < ext.level) + if (levels.size() < ext.depth) levels.push_back(&m_history.back()); else - levels.resize(ext.level); + levels.resize(ext.depth); m_history.append(WorldState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), lastHash, lastDataHash, vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); }; m_currentExecution->go(onOp); diff --git a/eth/main.cpp b/eth/main.cpp index 03be8b969..2b9f30ad7 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -627,7 +627,7 @@ int main(int argc, char** argv) f << " STORAGE" << endl; for (auto const& i: ext->state().storage(ext->myAddress)) f << showbase << hex << i.first << ": " << i.second << endl; - f << dec << ext->level << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << vm->gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32"; + f << dec << ext->depth << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << vm->gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32"; }; else if (format == "standard") oof = [&](uint64_t, Instruction instr, bigint, bigint, void* vvm, void const* vextVM) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 61d179ed8..93900b51e 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -158,7 +158,7 @@ OnOpFunc Executive::simpleTrace() 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.level << " | " << ext.myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << dec << vm.gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32" << " ]"; + 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" << " ]"; }; } diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index 3b4b7161f..612164d13 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -39,8 +39,8 @@ class ExtVM: public ExtVMFace { public: /// Full constructor. - ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, Manifest* o_ms, unsigned _level = 0): - ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code, _s.m_previousBlock, _s.m_currentBlock), level(_level), m_s(_s), m_origCache(_s.m_cache), m_ms(o_ms) + ExtVM(State& _s, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, Manifest* o_ms, unsigned _depth = 0): + ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code, _s.m_previousBlock, _s.m_currentBlock, _depth), m_s(_s), m_origCache(_s.m_cache), m_ms(o_ms) { m_s.ensureCached(_myAddress, true, true); } @@ -61,7 +61,7 @@ public: m_s.noteSending(myAddress); if (m_ms) m_ms->internal.resize(m_ms->internal.size() + 1); - auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &suicides, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1); + auto ret = m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &suicides, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, depth + 1); if (m_ms && !m_ms->internal.back().from) m_ms->internal.pop_back(); return ret; @@ -72,7 +72,7 @@ public: { if (m_ms) m_ms->internal.resize(m_ms->internal.size() + 1); - auto ret = m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &suicides, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, level + 1); + auto ret = m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &suicides, m_ms ? &(m_ms->internal.back()) : nullptr, _onOp, depth + 1); if (m_ms && !m_ms->internal.back().from) m_ms->internal.pop_back(); return ret; @@ -100,9 +100,6 @@ public: State& state() const { return m_s; } - /// @note not a part of the main API; just for use by tracing/debug stuff. - unsigned level = 0; - private: State& m_s; ///< A reference to the base state. std::map m_origCache; ///< The cache of the address states (i.e. the externalities) as-was prior to the execution. diff --git a/libevm/ExtVMFace.cpp b/libevm/ExtVMFace.cpp index 7c938417a..da189d899 100644 --- a/libevm/ExtVMFace.cpp +++ b/libevm/ExtVMFace.cpp @@ -25,7 +25,7 @@ using namespace std; using namespace dev; using namespace dev::eth; -ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock): +ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth): myAddress(_myAddress), caller(_caller), origin(_origin), @@ -34,6 +34,7 @@ ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 data(_data), code(_code), previousBlock(_previousBlock), - currentBlock(_currentBlock) + currentBlock(_currentBlock), + depth(_depth) {} diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index f78cb82cb..1b0f9eaf5 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -54,7 +54,7 @@ public: ExtVMFace() {} /// Full constructor. - ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock); + ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, unsigned _depth); /// Get the code at the given location in code ROM. byte getCode(u256 _n) const { return _n < code.size() ? code[(unsigned)_n] : 0; } @@ -99,6 +99,7 @@ public: BlockInfo previousBlock; ///< The previous block's information. BlockInfo currentBlock; ///< The current block's information. std::set
suicides; ///< Any accounts that have suicided. + unsigned depth; ///< Depth of the present call. }; } diff --git a/libevm/VM.h b/libevm/VM.h index 982b97394..456e949c7 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -606,6 +606,8 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con if (_ext.balance(_ext.myAddress) >= endowment) { + if (_ext.depth == 1024) + BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(endowment); m_stack.push_back((u160)_ext.create(endowment, &m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp)); } @@ -636,6 +638,8 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con if (_ext.balance(_ext.myAddress) >= value) { + if (_ext.depth == 1024) + BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(value); m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), &gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), receiveAddress)); } diff --git a/test/vm.cpp b/test/vm.cpp index a90b122e2..7829aa66b 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -31,8 +31,8 @@ using namespace dev; using namespace dev::eth; using namespace dev::test; -FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock): - ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock) {} +FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. + ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytesConstRef(), _previousBlock, _currentBlock, _depth) {} h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFunc) { diff --git a/test/vm.h b/test/vm.h index 5bad9d7d4..a71477437 100644 --- a/test/vm.h +++ b/test/vm.h @@ -44,7 +44,7 @@ class FakeExtVM: public eth::ExtVMFace { public: FakeExtVM() {} - FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock); + FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth = 0); u256 store(u256 _n) { return std::get<2>(addresses[myAddress])[_n]; } void setStore(u256 _n, u256 _v) { std::get<2>(addresses[myAddress])[_n] = _v; }