From 3a3647c9f0f77d04a27c4005bc24f3c74aeaac7f Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 20 May 2015 21:54:35 +0200 Subject: [PATCH 1/4] Guard use of m_writeQueue operator[]. --- libp2p/Session.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 8f395158b..1c037e783 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -319,10 +319,14 @@ void Session::send(bytes&& _msg) void Session::write() { - const bytes& bytes = m_writeQueue[0]; - m_io->writeSingleFramePacket(&bytes, m_writeQueue[0]); + bytes *out; + DEV_GUARDED(x_writeQueue) + { + m_io->writeSingleFramePacket(&m_writeQueue[0], m_writeQueue[0]); + out = &m_writeQueue[0]; + } auto self(shared_from_this()); - ba::async_write(m_socket, ba::buffer(bytes), [this, self](boost::system::error_code ec, std::size_t /*length*/) + ba::async_write(m_socket, ba::buffer(*out), [this, self](boost::system::error_code ec, std::size_t /*length*/) { ThreadContext tc(info().id.abridged()); ThreadContext tc2(info().clientVersion); From 012ffd4adc9cead57b021445cfa3d8267da5b951 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 21 May 2015 02:02:57 +0200 Subject: [PATCH 2/4] retain session when interacting with capability --- libethereum/EthereumHost.cpp | 35 +++++++++++++++++++++-------------- libethereum/EthereumHost.h | 2 +- libp2p/HostCapability.cpp | 4 ++-- libp2p/HostCapability.h | 2 +- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index d62d6716f..43af332c6 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -189,7 +189,7 @@ void EthereumHost::maintainTransactions() for (auto const& i: ts) { bool unsent = !m_transactionsSent.count(i.first); - for (auto const& p: randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }).second) + for (auto const& p: get<1>(randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); }))) peerTransactions[p].push_back(i.first); } for (auto const& t: ts) @@ -218,25 +218,32 @@ void EthereumHost::maintainTransactions() } } -pair>, vector>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) +tuple>, vector>, list>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) { - pair>, vector>> ret; - ret.second.reserve(peerSessions().size()); - for (auto const& j: peerSessions()) + vector> chosen; + vector> allowed; + list> sessions; + + auto ps = peerSessions(); + allowed.reserve(ps.size()); + for (auto const& j: ps) { auto pp = j.first->cap(); if (_allow(pp.get())) - ret.second.push_back(pp); + { + allowed.push_back(move(pp)); + sessions.push_back(move(j.first)); + } } - ret.second.reserve((peerSessions().size() * _percent + 99) / 100); - for (unsigned i = (peerSessions().size() * _percent + 99) / 100; i-- && ret.second.size();) + chosen.reserve((ps.size() * _percent + 99) / 100); + for (unsigned i = (ps.size() * _percent + 99) / 100; i-- && allowed.size();) { - unsigned n = rand() % ret.second.size(); - ret.first.push_back(std::move(ret.second[n])); - ret.second.erase(ret.second.begin() + n); + unsigned n = rand() % allowed.size(); + chosen.push_back(std::move(allowed[n])); + allowed.erase(allowed.begin() + n); } - return ret; + return make_tuple(chosen, allowed, sessions); } void EthereumHost::maintainBlocks(h256 const& _currentHash) @@ -254,7 +261,7 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true)); auto s = randomSelection(25, [&](EthereumPeer* p){ DEV_GUARDED(p->x_knownBlocks) return !p->m_knownBlocks.count(_currentHash); return false; }); - for (shared_ptr const& p: s.first) + for (shared_ptr const& p: get<0>(s)) for (auto const& b: blocks) { RLPStream ts; @@ -264,7 +271,7 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) p->sealAndSend(ts); p->m_knownBlocks.clear(); } - for (shared_ptr const& p: s.second) + for (shared_ptr const& p: get<1>(s)) { RLPStream ts; p->prep(ts, NewBlockHashesPacket, blocks.size()); diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index 95c7f147a..e8f7a0bad 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -80,7 +80,7 @@ public: void noteNewBlocks() { m_newBlocks = true; } private: - std::pair>, std::vector>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); + std::tuple>, std::vector>, std::list>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); /// Session is tell us that we may need (re-)syncing with the peer. void noteNeedsSyncing(EthereumPeer* _who); diff --git a/libp2p/HostCapability.cpp b/libp2p/HostCapability.cpp index b2acdcd1b..5f097875e 100644 --- a/libp2p/HostCapability.cpp +++ b/libp2p/HostCapability.cpp @@ -27,10 +27,10 @@ using namespace std; using namespace dev; using namespace dev::p2p; -std::vector,std::shared_ptr>> HostCapabilityFace::peerSessions() const +std::vector, std::shared_ptr>> HostCapabilityFace::peerSessions() const { RecursiveGuard l(m_host->x_sessions); - std::vector,std::shared_ptr>> ret; + std::vector, std::shared_ptr>> ret; for (auto const& i: m_host->m_sessions) if (std::shared_ptr s = i.second.lock()) if (s->m_capabilities.count(capDesc())) diff --git a/libp2p/HostCapability.h b/libp2p/HostCapability.h index 93086b1c9..668bcb929 100644 --- a/libp2p/HostCapability.h +++ b/libp2p/HostCapability.h @@ -45,7 +45,7 @@ public: Host* host() const { return m_host; } - std::vector,std::shared_ptr>> peerSessions() const; + std::vector, std::shared_ptr>> peerSessions() const; protected: virtual std::string name() const = 0; From b649409cbf5d798f0a4a4c05c4500332a91a8575 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 28 May 2015 22:13:30 +0200 Subject: [PATCH 3/4] Code review optimization. --- libethereum/EthereumHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 43af332c6..cea9339f2 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -224,7 +224,7 @@ tuple>, vector>, list> allowed; list> sessions; - auto ps = peerSessions(); + auto const& ps = peerSessions(); allowed.reserve(ps.size()); for (auto const& j: ps) { From 7b8a4cebd891fa9ff067802f593afcdf221ea586 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 3 Jun 2015 12:00:59 +0200 Subject: [PATCH 4/4] Better code. --- libethereum/EthereumHost.cpp | 6 +++--- libethereum/EthereumHost.h | 2 +- libp2p/Session.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index cea9339f2..533304fa6 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -218,11 +218,11 @@ void EthereumHost::maintainTransactions() } } -tuple>, vector>, list>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) +tuple>, vector>, vector>> EthereumHost::randomSelection(unsigned _percent, std::function const& _allow) { vector> chosen; vector> allowed; - list> sessions; + vector> sessions; auto const& ps = peerSessions(); allowed.reserve(ps.size()); @@ -243,7 +243,7 @@ tuple>, vector>, list>, std::vector>, std::list>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); + std::tuple>, std::vector>, std::vector>> randomSelection(unsigned _percent = 25, std::function const& _allow = [](EthereumPeer const*){ return true; }); /// Session is tell us that we may need (re-)syncing with the peer. void noteNeedsSyncing(EthereumPeer* _who); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 1c037e783..2a16007ca 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -319,7 +319,7 @@ void Session::send(bytes&& _msg) void Session::write() { - bytes *out; + bytes const* out; DEV_GUARDED(x_writeQueue) { m_io->writeSingleFramePacket(&m_writeQueue[0], m_writeQueue[0]);