From 43bf0f01c7d1c1406c4cbe4bfb3899a4e09204b7 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 26 Nov 2014 19:38:09 +0100 Subject: [PATCH 01/12] require ioservice to use multiple threads. thread-safe connecting to nodes. --- libp2p/Host.cpp | 20 ++++++++++++++++---- libp2p/Host.h | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 6e151d34d..dc655f7a4 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -199,7 +200,7 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_clientVersion(_clientVersion), m_netPrefs(_n), m_ifAddresses(getInterfaceAddresses()), - m_ioService(new ba::io_service), + m_ioService(new ba::io_service(2)), m_acceptor(new bi::tcp::acceptor(*m_ioService)), m_socket(new bi::tcp::socket(*m_ioService)), m_key(KeyPair::create()) @@ -536,7 +537,16 @@ void Host::connect(std::shared_ptr const& _n) // if there's no ioService, it means we've had quit() called - bomb out - we're not allowed in here. if (!m_ioService) return; - + + // prevent concurrently connecting to a node; tood: better abstraction + Node *nptr = _n.get(); + { + lock_guard l(x_pendingNodeConnsMutex); + if (m_pendingNodeConns.count(nptr)) + return; + m_pendingNodeConns.insert(nptr); + } + clog(NetConnect) << "Attempting connection to node" << _n->id.abridged() << "@" << _n->address << "from" << id().abridged(); _n->lastAttempted = std::chrono::system_clock::now(); _n->failedAttempts++; @@ -559,6 +569,8 @@ void Host::connect(std::shared_ptr const& _n) p->start(); } delete s; + lock_guard l(x_pendingNodeConnsMutex); + m_pendingNodeConns.erase(nptr); }); } @@ -685,7 +697,7 @@ PeerInfos Host::peers(bool _updatePing) const ret.push_back(j->m_info); return ret; } - + void Host::run(boost::system::error_code const& error) { static unsigned s_lasttick = 0; @@ -701,7 +713,7 @@ void Host::run(boost::system::error_code const& error) // network running if (m_run) { - if (s_lasttick >= c_timerInterval * 50) + if (s_lasttick >= c_timerInterval * 10) { growPeers(); prunePeers(); diff --git a/libp2p/Host.h b/libp2p/Host.h index c82ecf84c..e19d81b94 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -241,6 +241,9 @@ private: std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. + + std::set m_pendingNodeConns; /// Used only by connect(Node&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). + std::mutex x_pendingNodeConnsMutex; bi::tcp::endpoint m_public; ///< Our public listening endpoint. KeyPair m_key; ///< Our unique ID. From cacc761ce9257769faf5bb864e9bf351be9d791f Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 27 Nov 2014 12:17:43 +0100 Subject: [PATCH 02/12] pr fixes --- libp2p/Host.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index dc655f7a4..73690ee94 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -228,7 +228,7 @@ void Host::stop() { { // prevent m_run from being set to false at same time as set to true by start() - lock_guard l(x_runtimer); + Guard l(x_runtimer); // once m_run is false the scheduler will shutdown network and stopWorking() m_run = false; } @@ -538,10 +538,10 @@ void Host::connect(std::shared_ptr const& _n) if (!m_ioService) return; - // prevent concurrently connecting to a node; tood: better abstraction + // prevent concurrently connecting to a node; todo: better abstraction Node *nptr = _n.get(); { - lock_guard l(x_pendingNodeConnsMutex); + Guard l(x_pendingNodeConnsMutex); if (m_pendingNodeConns.count(nptr)) return; m_pendingNodeConns.insert(nptr); @@ -569,7 +569,7 @@ void Host::connect(std::shared_ptr const& _n) p->start(); } delete s; - lock_guard l(x_pendingNodeConnsMutex); + Guard l(x_pendingNodeConnsMutex); m_pendingNodeConns.erase(nptr); }); } @@ -806,7 +806,7 @@ void Host::startedWorking() // prevent m_run from being set to true at same time as set to false by stop() // don't release mutex until m_timer is set so in case stop() is called at same // time, stop will wait on m_timer and graceful network shutdown. - lock_guard l(x_runtimer); + Guard l(x_runtimer); // reset io service and create deadline timer m_timer.reset(new boost::asio::deadline_timer(*m_ioService)); m_run = true; From 8005012f6c4cb135964da8868e56a487e2ba944b Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 3 Dec 2014 13:03:41 +0100 Subject: [PATCH 03/12] fix naming --- libp2p/Host.cpp | 18 +++++++++--------- libp2p/Host.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 73690ee94..85225ab7f 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -228,7 +228,7 @@ void Host::stop() { { // prevent m_run from being set to false at same time as set to true by start() - Guard l(x_runtimer); + Guard l(x_runTimer); // once m_run is false the scheduler will shutdown network and stopWorking() m_run = false; } @@ -541,7 +541,7 @@ void Host::connect(std::shared_ptr const& _n) // prevent concurrently connecting to a node; todo: better abstraction Node *nptr = _n.get(); { - Guard l(x_pendingNodeConnsMutex); + Guard l(x_pendingNodeConns); if (m_pendingNodeConns.count(nptr)) return; m_pendingNodeConns.insert(nptr); @@ -569,7 +569,7 @@ void Host::connect(std::shared_ptr const& _n) p->start(); } delete s; - Guard l(x_pendingNodeConnsMutex); + Guard l(x_pendingNodeConns); m_pendingNodeConns.erase(nptr); }); } @@ -700,8 +700,8 @@ PeerInfos Host::peers(bool _updatePing) const void Host::run(boost::system::error_code const& error) { - static unsigned s_lasttick = 0; - s_lasttick += c_timerInterval; + static unsigned s_lastTick = 0; + s_lastTick += c_timerInterval; if (error || !m_ioService) { @@ -713,11 +713,11 @@ void Host::run(boost::system::error_code const& error) // network running if (m_run) { - if (s_lasttick >= c_timerInterval * 10) + if (s_lastTick >= c_timerInterval * 10) { growPeers(); prunePeers(); - s_lasttick = 0; + s_lastTick = 0; } if (m_hadNewNodes) @@ -783,7 +783,7 @@ void Host::run(boost::system::error_code const& error) m_socket->close(); // m_run is false, so we're stopping; kill timer - s_lasttick = 0; + s_lastTick = 0; // causes parent thread's stop() to continue which calls stopWorking() m_timer.reset(); @@ -806,7 +806,7 @@ void Host::startedWorking() // prevent m_run from being set to true at same time as set to false by stop() // don't release mutex until m_timer is set so in case stop() is called at same // time, stop will wait on m_timer and graceful network shutdown. - Guard l(x_runtimer); + Guard l(x_runTimer); // reset io service and create deadline timer m_timer.reset(new boost::asio::deadline_timer(*m_ioService)); m_run = true; diff --git a/libp2p/Host.h b/libp2p/Host.h index e19d81b94..9ee2c1b4a 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -224,7 +224,7 @@ private: Nodes potentialPeers(RangeMask const& _known); bool m_run = false; ///< Whether network is running. - std::mutex x_runtimer; ///< Start/stop mutex. + std::mutex x_runTimer; ///< Start/stop mutex. std::string m_clientVersion; ///< Our version string. @@ -243,7 +243,7 @@ private: static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. std::set m_pendingNodeConns; /// Used only by connect(Node&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). - std::mutex x_pendingNodeConnsMutex; + Mutex x_pendingNodeConns; bi::tcp::endpoint m_public; ///< Our public listening endpoint. KeyPair m_key; ///< Our unique ID. From a769ac51023eee79e73fb9db928b2c75fa0debd3 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 3 Dec 2014 19:49:38 +0100 Subject: [PATCH 04/12] expire whisper messages --- libwhisper/WhisperHost.cpp | 2 +- libwhisper/WhisperPeer.cpp | 35 ++++++++++++----------------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp index 9b26e3260..769b39057 100644 --- a/libwhisper/WhisperHost.cpp +++ b/libwhisper/WhisperHost.cpp @@ -118,7 +118,6 @@ unsigned WhisperHost::installWatch(shh::TopicFilter const& _f) h256s WhisperHost::watchMessages(unsigned _watchId) { - cleanup(); h256s ret; auto wit = m_watches.find(_watchId); if (wit == m_watches.end()) @@ -160,6 +159,7 @@ void WhisperHost::doWork() { for (auto& i: peers()) i->cap()->sendMessages(); + cleanup(); } void WhisperHost::cleanup() diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp index c3a28e3c3..98bf0bc61 100644 --- a/libwhisper/WhisperPeer.cpp +++ b/libwhisper/WhisperPeer.cpp @@ -82,33 +82,22 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r) void WhisperPeer::sendMessages() { - RLPStream amalg; - unsigned n = 0; - + if (m_unseen.size()) { - Guard l(x_unseen); - while (m_unseen.size()) + RLPStream amalg; + unsigned msgCount = m_unseen.size(); { - auto p = *m_unseen.begin(); - m_unseen.erase(m_unseen.begin()); - host()->streamMessage(p.second, amalg); - n++; + Guard l(x_unseen); + while (m_unseen.size()) + { + auto p = *m_unseen.begin(); + m_unseen.erase(m_unseen.begin()); + host()->streamMessage(p.second, amalg); + } } - } - - // the message subsystem should really just keep pumping out messages while m_unseen.size() and there's bandwidth for them. - auto diff = chrono::duration_cast(chrono::system_clock::now() - m_timer); - if (n || diff.count() > 0) - { - RLPStream s; - prep(s, MessagesPacket, n).appendRaw(amalg.out(), n); - sealAndSend(s); - m_timer = chrono::system_clock::now(); - } - - { + RLPStream s; - prep(s, MessagesPacket, n).appendRaw(amalg.out(), n); + prep(s, MessagesPacket, msgCount).appendRaw(amalg.out(), msgCount); sealAndSend(s); } } From b10eddc85e60052ad104da5987eca85b4ae4fc9d Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 3 Dec 2014 20:12:25 +0100 Subject: [PATCH 05/12] static to member in Host::run() --- libp2p/Host.cpp | 9 ++++----- libp2p/Host.h | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 546d54c00..7d08910aa 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -700,8 +700,7 @@ PeerInfos Host::peers(bool _updatePing) const void Host::run(boost::system::error_code const& error) { - static unsigned s_lastTick = 0; - s_lastTick += c_timerInterval; + m_lastTick += c_timerInterval; if (error || !m_ioService) { @@ -713,11 +712,11 @@ void Host::run(boost::system::error_code const& error) // network running if (m_run) { - if (s_lastTick >= c_timerInterval * 10) + if (m_lastTick >= c_timerInterval * 10) { growPeers(); prunePeers(); - s_lastTick = 0; + m_lastTick = 0; } if (m_hadNewNodes) @@ -783,7 +782,7 @@ void Host::run(boost::system::error_code const& error) m_socket->close(); // m_run is false, so we're stopping; kill timer - s_lastTick = 0; + m_lastTick = 0; // causes parent thread's stop() to continue which calls stopWorking() m_timer.reset(); diff --git a/libp2p/Host.h b/libp2p/Host.h index 9ee2c1b4a..644afeb69 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -241,6 +241,7 @@ private: std::unique_ptr m_timer; ///< Timer which, when network is running, calls scheduler() every c_timerInterval ms. static const unsigned c_timerInterval = 100; ///< Interval which m_timer is run when network is connected. + unsigned m_lastTick = 0; ///< Used by run() for scheduling; must not be mutated outside of run(). std::set m_pendingNodeConns; /// Used only by connect(Node&) to limit concurrently connecting to same node. See connect(shared_ptrconst&). Mutex x_pendingNodeConns; From 8a4a4b8b56e9e134737b54f0865fc5587f006a38 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 3 Dec 2014 20:14:57 +0100 Subject: [PATCH 06/12] thread-safety fix --- libwhisper/WhisperPeer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp index 98bf0bc61..0951a3726 100644 --- a/libwhisper/WhisperPeer.cpp +++ b/libwhisper/WhisperPeer.cpp @@ -85,9 +85,10 @@ void WhisperPeer::sendMessages() if (m_unseen.size()) { RLPStream amalg; - unsigned msgCount = m_unseen.size(); + unsigned msgCount; { Guard l(x_unseen); + msgCount = m_unseen.size(); while (m_unseen.size()) { auto p = *m_unseen.begin(); From 638a784c92659a7e061fc82c27f3a98c97c5d6cf Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 4 Dec 2014 10:13:31 +0100 Subject: [PATCH 07/12] ide working on macos! --- mix/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index da214fd29..0252b5226 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -61,7 +61,7 @@ target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore dev if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + COMMAND /usr/local/opt/qt5/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required From 5ccf4ca52c9c38e478de8176f18d3b406e58e34b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 4 Dec 2014 14:04:48 +0100 Subject: [PATCH 08/12] Protocol bump. --- libethcore/CommonEth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 744e85a27..e68839ed5 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -33,7 +33,7 @@ namespace dev namespace eth { -const unsigned c_protocolVersion = 46; +const unsigned c_protocolVersion = 47; const unsigned c_databaseVersion = 5; static const vector> g_units = From c96e1d0c36c7b1a627a3b99591fc0e40ddc39bf5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 5 Dec 2014 09:37:10 +0100 Subject: [PATCH 09/12] Logs from subcalls are folded in. --- libevm/ExtVMFace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 9e6601d0a..7f7ae7a50 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -88,6 +88,7 @@ struct SubState { suicides += _s.suicides; refunds += _s.refunds; + logs += _s.logs; return *this; } }; From 4cf9f82bc7344207555f4e9f52a4352ba5b6424d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 5 Dec 2014 09:43:29 +0100 Subject: [PATCH 10/12] Windows fix & used code removed --- libevm/ExtVMFace.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 7f7ae7a50..4a175ff4e 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -36,20 +36,12 @@ namespace dev namespace eth { -template inline std::set toSet(std::vector const& _ts) -{ - std::set ret; - for (auto const& t: _ts) - ret.insert(t); - return ret; -} - using LogBloom = h512; struct LogEntry { LogEntry() {} - LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = (h256s)_r[1]; data = _r[2].toBytes(); } + LogEntry(RLP const& _r) { address = (Address)_r[0]; topics = _r[1].toVector(); data = _r[2].toBytes(); } LogEntry(Address const& _address, h256s const& _ts, bytes&& _d): address(_address), topics(_ts), data(std::move(_d)) {} void streamRLP(RLPStream& _s) const { _s.appendList(3) << address << topics << data; } From 45499094ef6fb2822da6494cc898c49f90eacbd0 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 5 Dec 2014 09:52:34 +0100 Subject: [PATCH 11/12] PV48. --- libethcore/CommonEth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index e68839ed5..5f9332ad8 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -33,7 +33,7 @@ namespace dev namespace eth { -const unsigned c_protocolVersion = 47; +const unsigned c_protocolVersion = 48; const unsigned c_databaseVersion = 5; static const vector> g_units = From 7de687fece7631adca5a78f27d0222c5f911caed Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 5 Dec 2014 10:47:05 +0100 Subject: [PATCH 12/12] Block-level receipts dump. --- alethzero/MainWin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 4a32f66b2..2a66a6d69 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1285,6 +1285,7 @@ void Main::on_blocks_currentItemChanged() s << "
" << sha3(i.data()).abridged();// << ": " << i[1].toHash() << " [" << i[2].toInt() << " used]"; s << "
Post: " << info.stateRoot << ""; s << "
Dump: " << toHex(block[0].data()) << ""; + s << "
Receipts-Hex: " << toHex(ethereum()->blockChain().receipts(h).rlp()) << "
"; } else {