From 2e972be64082be766e06ea9ef645e1137f8ad50f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Oct 2014 15:44:24 +0200 Subject: [PATCH] Efforts to make reconnect timing strategy more expansive and consistent. --- libp2p/Host.cpp | 39 +++++++++++++++++++++------------------ libp2p/Host.h | 5 +++-- libp2p/Session.cpp | 13 ++++++++----- libp2p/Session.h | 3 --- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 2c93e64e0..b3b8cdbc1 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -506,6 +506,7 @@ void Node::connect(Host* _h) if (ec) { clog(NetConnect) << "Connection refused to node" << id.abridged() << "@" << address << "(" << ec.message() << ")"; + lastDisconnect = TCPError; _h->m_ready += index; } else @@ -533,26 +534,33 @@ bool Host::havePeer(NodeId _id) const return !!m_peers.count(_id); } -unsigned cumulativeFallback(unsigned _failed, DisconnectReason _r) +unsigned Node::fallbackSeconds() const { - switch (_r) + switch (lastDisconnect) { case BadProtocol: - return 30 * (_failed + 1); + return 30 * (failedAttempts + 1); case UselessPeer: case TooManyPeers: case ClientQuit: - return 15 * (_failed + 1); + return 15 * (failedAttempts + 1); + case NoDisconnect: + return 0; default: - if (_failed < 5) - return _failed * 5; - else if (_failed < 15) - return 25 + (_failed - 5) * 10; + if (failedAttempts < 5) + return failedAttempts * 5; + else if (failedAttempts < 15) + return 25 + (failedAttempts - 5) * 10; else - return 25 + 100 + (_failed - 15) * 20; + return 25 + 100 + (failedAttempts - 15) * 20; } } +bool Node::shouldReconnect() const +{ + return chrono::system_clock::now() > lastAttempted + chrono::seconds(fallbackSeconds()); +} + void Host::growPeers() { RecursiveGuard l(x_peers); @@ -564,7 +572,7 @@ void Host::growPeers() toTry -= m_private; set ns; for (auto i: toTry) - if (chrono::system_clock::now() > m_nodes[m_nodesList[i]]->lastAttempted + chrono::seconds(cumulativeFallback(m_nodes[m_nodesList[i]]->failedAttempts, m_nodes[m_nodesList[i]]->lastDisconnect))) + if (m_nodes[m_nodesList[i]]->shouldReconnect()) ns.insert(*m_nodes[m_nodesList[i]]); if (ns.size()) @@ -577,18 +585,13 @@ void Host::growPeers() else { ensureAccepting(); - requestNodes(); + for (auto const& i: m_peers) + if (auto p = i.second.lock()) + p->ensureNodesRequested(); } } } -void Host::requestNodes() -{ - for (auto const& i: m_peers) - if (auto p = i.second.lock()) - p->ensureNodesRequested(); -} - void Host::prunePeers() { RecursiveGuard l(x_peers); diff --git a/libp2p/Host.h b/libp2p/Host.h index a7beb8c35..52e4af6be 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -75,6 +75,9 @@ struct Node int secondsSinceLastConnected() const { return lastConnected == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastConnected).count(); } int secondsSinceLastAttempted() const { return lastAttempted == std::chrono::system_clock::time_point() ? -1 : (int)std::chrono::duration_cast(std::chrono::system_clock::now() - lastAttempted).count(); } + unsigned fallbackSeconds() const; + bool shouldReconnect() const; + bool isOffline() const { return lastDisconnect == -1 || lastAttempted > lastConnected; } bool operator<(Node const& _n) const { @@ -200,8 +203,6 @@ private: std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint const& _a, Origin _o, bool _ready, NodeId _oldId = h256()); Nodes potentialPeers(RangeMask const& _known); - void requestNodes(); - std::string m_clientVersion; ///< Our version string. NetworkPreferences m_netPrefs; ///< Network settings. diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 7c0d291c4..79b84111a 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -249,12 +249,15 @@ bool Session::interpret(RLP const& _r) { string reason = "Unspecified"; auto r = (DisconnectReason)_r[1].toInt(); - if (_r[1].isInt()) + if (!_r[1].isInt()) + drop(BadProtocol); + else + { reason = reasonOf(r); - - clogS(NetMessageSummary) << "Disconnect (reason: " << reason << ")"; - drop(DisconnectRequested); - return true; + clogS(NetMessageSummary) << "Disconnect (reason: " << reason << ")"; + drop(DisconnectRequested); + } + break; } case PingPacket: { diff --git a/libp2p/Session.h b/libp2p/Session.h index 289abca26..f76162cca 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -93,9 +93,6 @@ private: /// Perform a read on the socket. void doRead(); - /// The - void writeImpl(bytes& _buffer); - /// Perform a single round of the write operation. This could end up calling itself asynchronously. void write();