From 33ec3ca35d76207dd5e170472d693e64d186519e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Oct 2014 18:51:04 +0200 Subject: [PATCH] Pinging, stake disconnecting and better UI. --- alethzero/MainWin.cpp | 11 +++++++---- libdevcore/Common.cpp | 2 +- libp2p/Common.h | 2 +- libp2p/Host.cpp | 9 +++++++++ libp2p/Host.h | 6 ++++-- libp2p/Session.cpp | 6 ++++-- libp2p/Session.h | 7 ++++--- 7 files changed, 30 insertions(+), 13 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index e9dcf0ff6..3964f0e6f 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -750,6 +750,9 @@ void Main::refreshBalances() void Main::refreshNetwork() { auto ps = web3()->peers(); + + map clients; + ui->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)"); ui->peers->clear(); for (PeerInfo const& i: ps) @@ -757,7 +760,7 @@ void Main::refreshNetwork() .arg(QString::fromStdString(i.host)) .arg(i.port) .arg(chrono::duration_cast(i.lastPing).count()) - .arg(QString::fromStdString(i.clientVersion)) + .arg(clients[i.id] = QString::fromStdString(i.clientVersion)) .arg(QString::fromStdString(toString(i.caps))) .arg(QString::fromStdString(toString(i.notes))) .arg(i.socket) @@ -767,13 +770,13 @@ void Main::refreshNetwork() ui->nodes->clear(); for (p2p::Node const& i: ns) if (!i.dead) - ui->nodes->addItem(QString("[%1%3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") + ui->nodes->addItem(QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") .arg(QString::fromStdString(i.id.abridged())) .arg(QString::fromStdString(toString(i.address))) - .arg(i.id == web3()->id() ? " self" : i.isOffline() ? QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s" : " ----") + .arg(i.id == web3()->id() ? "self" : i.isOffline() ? i.secondsSinceLastAttempted() > -1 ? "retry-" + QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s" : "session-fail" : clients[i.id]) .arg(i.secondsSinceLastAttempted()) .arg(i.secondsSinceLastConnected()) - .arg(i.lastDisconnect == NoDisconnect ? QString("") : (" | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x")) + .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") .arg(i.rating) .arg((int)i.idOrigin) ); diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index b67e3e62c..41b75f5ec 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.7.2"; +char const* Version = "0.7.3"; } diff --git a/libp2p/Common.h b/libp2p/Common.h index 04154c9a0..7c2c61156 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -88,6 +88,7 @@ enum DisconnectReason ClientQuit, UnexpectedIdentity, LocalIdentity, + PingTimeout, UserReason = 0x10, NoDisconnect = 0xffff }; @@ -96,7 +97,6 @@ inline bool isPermanentProblem(DisconnectReason _r) { switch (_r) { - case DisconnectRequested: case DuplicatePeer: case IncompatibleProtocol: case NullIdentity: diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 85b0af81e..73808633a 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -655,6 +655,15 @@ void Host::doWork() m_hadNewNodes = false; } + if (chrono::steady_clock::now() - m_lastPing > chrono::seconds(30)) // ping every 30s. + { + for (auto p: m_peers) + if (auto pp = p.second.lock()) + if (chrono::steady_clock::now() - pp->m_lastReceived > chrono::seconds(30)) + pp->disconnect(PingTimeout); + pingAll(); + } + m_ioService.poll(); } diff --git a/libp2p/Host.h b/libp2p/Host.h index 52e4af6be..ca546390c 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -78,7 +78,7 @@ struct Node unsigned fallbackSeconds() const; bool shouldReconnect() const; - bool isOffline() const { return lastDisconnect == -1 || lastAttempted > lastConnected; } + bool isOffline() const { return lastAttempted > lastConnected; } bool operator<(Node const& _n) const { if (isOffline() != _n.isOffline()) @@ -121,7 +121,7 @@ class Host: public Worker { friend class Session; friend class HostCapabilityFace; - friend class Node; + friend struct Node; public: /// Start server, listening for connections on the given port. @@ -245,6 +245,8 @@ private: // Our capabilities. std::map> m_capabilities; ///< Each of the capabilities we support. + std::chrono::steady_clock::time_point m_lastPing; ///< Time we sent the last ping to all peers. + bool m_accepting = false; }; diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 79b84111a..20d50025d 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -42,7 +42,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, bi::tcp::endpoint const& _ma m_node(nullptr), m_manualEndpoint(_manual) { - m_connect = std::chrono::steady_clock::now(); + m_lastReceived = m_connect = std::chrono::steady_clock::now(); m_info = PeerInfo({NodeId(), "?", m_manualEndpoint.address().to_string(), m_manualEndpoint.port(), std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}); } @@ -54,7 +54,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, std::shared_ptr const& m_manualEndpoint(_n->address), m_force(_force) { - m_connect = std::chrono::steady_clock::now(); + m_lastReceived = m_connect = std::chrono::steady_clock::now(); m_info = PeerInfo({m_node->id, "?", _n->address.address().to_string(), _n->address.port(), std::chrono::steady_clock::duration(0), CapDescSet(), 0, map()}); } @@ -167,6 +167,8 @@ void Session::serviceNodesRequest() bool Session::interpret(RLP const& _r) { + m_lastReceived = chrono::steady_clock::now(); + clogS(NetRight) << _r; try // Generic try-catch block designed to capture RLP format errors - TODO: give decent diagnostics, make a bit more specific over what is caught. { diff --git a/libp2p/Session.h b/libp2p/Session.h index f76162cca..e8de1c398 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -39,7 +39,7 @@ namespace dev namespace p2p { -class Node; +struct Node; /** * @brief The Session class @@ -121,8 +121,9 @@ private: bool m_theyRequestedNodes = false; ///< Has the peer requested nodes from us without receiveing an answer from us? bool m_weRequestedNodes = false; ///< Have we requested nodes from the peer and not received an answer yet? - std::chrono::steady_clock::time_point m_ping; ///< Time point of last ping. - std::chrono::steady_clock::time_point m_connect; ///< Time point of connection. + std::chrono::steady_clock::time_point m_connect; ///< Time point of connection. + std::chrono::steady_clock::time_point m_ping; ///< Time point of last ping. + std::chrono::steady_clock::time_point m_lastReceived; ///< Time point of last message. std::map> m_capabilities; ///< The peer's capability set. RangeMask m_knownNodes; ///< Nodes we already know about as indices into Host's nodesList. These shouldn't be resent to peer.