From f799303ea588276976eeea05230986eda3410fe5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 2 Mar 2015 17:27:10 +0100 Subject: [PATCH] Gas fixes. Trie fixes. --- libdevcore/Exceptions.h | 1 + libdevcrypto/MemoryDB.h | 5 +++-- libdevcrypto/OverlayDB.cpp | 17 +++++++++-------- libdevcrypto/TrieDB.h | 8 ++++++-- libethereum/Client.cpp | 8 ++------ libevm/VM.cpp | 15 +++++++-------- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index e631a3b49..8c66cac49 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -46,6 +46,7 @@ struct BadRLP: virtual RLPException {}; struct NoNetworking: virtual Exception {}; struct NoUPnPDevice: virtual Exception {}; struct RootNotFound: virtual Exception {}; +struct BadRoot: virtual Exception {}; struct FileError: virtual Exception {}; struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; diff --git a/libdevcrypto/MemoryDB.h b/libdevcrypto/MemoryDB.h index ecda3b6ec..7d39ba73b 100644 --- a/libdevcrypto/MemoryDB.h +++ b/libdevcrypto/MemoryDB.h @@ -52,7 +52,8 @@ public: void purge(); bytes lookupAux(h256 _h) const { auto h = aux(_h); return m_aux.count(h) ? m_aux.at(h) : bytes(); } - void insertAux(h256 _h, bytesConstRef _v) { m_auxKey = aux(_h); m_aux[m_auxKey] = _v.toBytes(); } + void removeAux(h256 _h) { m_auxActive.erase(aux(_h)); } + void insertAux(h256 _h, bytesConstRef _v) { auto h = aux(_h); m_auxActive.insert(h); m_aux[h] = _v.toBytes(); } std::set keys() const; @@ -61,7 +62,7 @@ protected: std::map m_over; std::map m_refCount; - h256 m_auxKey; + std::set m_auxActive; std::map m_aux; mutable bool m_enforceRefs = false; diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp index d34dd1906..ffe996bb6 100644 --- a/libdevcrypto/OverlayDB.cpp +++ b/libdevcrypto/OverlayDB.cpp @@ -52,14 +52,15 @@ void OverlayDB::commit() if (m_refCount[i.first]) m_db->Put(m_writeOptions, ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.data(), i.second.size())); } - if (m_auxKey && m_aux.count(m_auxKey)) - { - m_db->Put(m_writeOptions, m_auxKey.ref(), bytesConstRef(&m_aux[m_auxKey])); - cdebug << "Committing aux: " << m_auxKey; - m_aux.erase(m_auxKey); - cdebug << "Discarding " << keysOf(m_aux); - } - m_auxKey = h256(); + for (auto const& i: m_auxActive) + if (m_aux.count(i)) + { + m_db->Put(m_writeOptions, i.ref(), bytesConstRef(&m_aux[i])); + cdebug << "Committing aux: " << i; + m_aux.erase(i); + } + cdebug << "Discarding " << keysOf(m_aux); + m_auxActive.clear(); m_aux.clear(); m_over.clear(); m_refCount.clear(); diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h index 583bfbf6e..1abf2d8c0 100644 --- a/libdevcrypto/TrieDB.h +++ b/libdevcrypto/TrieDB.h @@ -93,7 +93,7 @@ public: /// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty). bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); } - h256 root() const { assert(node(m_root).size()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. + h256 root() const { if (!node(m_root).size()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. void debugPrint() {} @@ -404,8 +404,12 @@ public: void setRoot(h256 _root) { + if (!m_secure.isNull()) + Super::db()->removeAux(m_secure.root()); m_secure.setRoot(_root); - Super::setRoot(h256(Super::db()->lookupAux(m_secure.root()))); + auto rb = Super::db()->lookupAux(m_secure.root()); + auto r = h256(rb); + Super::setRoot(r); } h256 root() const { return m_secure.root(); } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index b0b95c7bf..314594d2d 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -278,13 +278,9 @@ LocalisedLogEntries Client::checkWatch(unsigned _watchId) LocalisedLogEntries ret; try { -#if ETH_DEBUG - cdebug << "checkWatch" << _watchId; -#endif +// cdebug << "checkWatch" << _watchId; auto& w = m_watches.at(_watchId); -#if ETH_DEBUG - cdebug << "lastPoll updated to " << chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); -#endif +// cdebug << "lastPoll updated to " << chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); std::swap(ret, w.changes); w.lastPoll = chrono::system_clock::now(); } catch (...) {} diff --git a/libevm/VM.cpp b/libevm/VM.cpp index a52b0ec3e..6a6937f89 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -75,21 +75,20 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) { // INSTRUCTION... Instruction inst = (Instruction)_ext.getCode(m_curPC); + auto metric = c_metrics[(int)inst]; + int gasPriceTier = metric.gasPriceTier; + + if (gasPriceTier == InvalidTier) + BOOST_THROW_EXCEPTION(BadInstruction()); // FEES... - bigint runGas; + bigint runGas = c_tierStepGas[metric.gasPriceTier]; bigint newTempSize = m_temp.size(); bigint copySize = 0; // should work, but just seems to result in immediate errorless exit on initial execution. yeah. weird. //m_onFail = std::function(onOperation); - auto metric = c_metrics[(int)inst]; - int gasPriceTier = metric.gasPriceTier; - if (gasPriceTier == InvalidTier) - BOOST_THROW_EXCEPTION(BadInstruction()); - else - runGas = c_tierStepGas[metric.gasPriceTier]; require(metric.args); auto onOperation = [&]() @@ -186,7 +185,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) newTempSize = (newTempSize + 31) / 32 * 32; if (newTempSize > m_temp.size()) runGas += gasForMem(newTempSize) - gasForMem(m_temp.size()); - runGas += c_copyGas * (copySize + 31) / 32; + runGas += c_copyGas * ((copySize + 31) / 32); onOperation(); // if (_onOp)