diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index a6ef485df..5d4f9770e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -263,7 +263,7 @@ unsigned Main::installWatch(LogFilter const& _tf, WatchHandler const& _f) unsigned Main::installWatch(dev::h256 _tf, WatchHandler const& _f) { - auto ret = ethereum()->installWatch(_tf); + auto ret = ethereum()->installWatch(_tf, Reaping::Manual); m_handlers[ret] = _f; return ret; } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index f46d0d3c9..9d7ecb605 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -249,13 +249,13 @@ void Client::clearPending() noteChanged(changeds); } -unsigned Client::installWatch(h256 _h) +unsigned Client::installWatch(h256 _h, Reaping _r) { unsigned ret; { Guard l(m_filterLock); ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; - m_watches[ret] = ClientWatch(_h); + m_watches[ret] = ClientWatch(_h, _r); cwatch << "+++" << ret << _h.abridged(); } auto ch = logs(ret); @@ -268,7 +268,7 @@ unsigned Client::installWatch(h256 _h) return ret; } -unsigned Client::installWatch(LogFilter const& _f) +unsigned Client::installWatch(LogFilter const& _f, Reaping _r) { h256 h = _f.sha3(); { @@ -279,7 +279,7 @@ unsigned Client::installWatch(LogFilter const& _f) m_filters.insert(make_pair(h, _f)); } } - return installWatch(h); + return installWatch(h, _r); } bool Client::uninstallWatch(unsigned _i) @@ -692,7 +692,7 @@ void Client::doWork() { Guard l(m_filterLock); for (auto key: keysOf(m_watches)) - if (chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20)) + if (m_watches[key].lastPoll != chrono::system_clock::time_point::max() && chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20)) { toUninstall.push_back(key); cnote << "GC: Uninstall" << key << "(" << chrono::duration_cast(chrono::system_clock::now() - m_watches[key].lastPoll).count() << "s old)"; diff --git a/libethereum/Client.h b/libethereum/Client.h index 04798ecdb..02d8ef6f8 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -92,7 +92,7 @@ static const LocalisedLogEntry InitialChange(SpecialLogEntry, 0); struct ClientWatch { ClientWatch(): lastPoll(std::chrono::system_clock::now()) {} - explicit ClientWatch(h256 _id): id(_id), lastPoll(std::chrono::system_clock::now()) {} + explicit ClientWatch(h256 _id, Reaping _r): id(_id), lastPoll(_r == Reaping::Automatic ? std::chrono::system_clock::now() : std::chrono::system_clock::time_point::max()) {} h256 id; LocalisedLogEntries changes = LocalisedLogEntries{ InitialChange }; @@ -246,8 +246,8 @@ public: virtual bytes codeAt(Address _a, int _block) const; virtual std::map storageAt(Address _a, int _block) const; - virtual unsigned installWatch(LogFilter const& _filter) override; - virtual unsigned installWatch(h256 _filterId) override; + virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override; + virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) override; virtual bool uninstallWatch(unsigned _watchId) override; virtual LocalisedLogEntries peekWatch(unsigned _watchId) const; virtual LocalisedLogEntries checkWatch(unsigned _watchId); diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 728cb5030..abf7c0a2d 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -39,6 +39,12 @@ namespace eth using TransactionHashes = h256s; +enum class Reaping +{ + Automatic, + Manual +}; + /** * @brief Main API hub for interfacing with Ethereum. */ @@ -92,8 +98,8 @@ public: virtual LocalisedLogEntries logs(LogFilter const& _filter) const = 0; /// Install, uninstall and query watches. - virtual unsigned installWatch(LogFilter const& _filter) = 0; - virtual unsigned installWatch(h256 _filterId) = 0; + virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) = 0; + virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) = 0; virtual bool uninstallWatch(unsigned _watchId) = 0; LocalisedLogEntries peekWatchSafe(unsigned _watchId) const { try { return peekWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } } LocalisedLogEntries checkWatchSafe(unsigned _watchId) { try { return checkWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } }