diff --git a/libethereum/PeerNetwork.cpp b/libethereum/PeerNetwork.cpp index 850440dac..3299710e2 100644 --- a/libethereum/PeerNetwork.cpp +++ b/libethereum/PeerNetwork.cpp @@ -24,6 +24,15 @@ using namespace std; using namespace eth; +PeerSession::PeerSession(bi::tcp::socket _socket, uint _rNId): m_socket(std::move(_socket)), m_reqNetworkId(_rNId) +{ +} + +PeerSession::~PeerSession() +{ + disconnect(); +} + bool PeerSession::interpret(RLP const& _r) { switch (_r[0].toInt()) @@ -39,22 +48,34 @@ bool PeerSession::interpret(RLP const& _r) } cout << std::setw(2) << m_socket.native_handle() << " | Client version: " << m_clientVersion << endl; break; + case Disconnect: + m_socket.close(); + return false; + case Ping: + { + RLPStream s; + sealAndSend(prep(s).appendList(1) << Pong); + break; + } + case Pong: + cout << "Latency: " << chrono::duration_cast(std::chrono::steady_clock::now() - m_ping).count() << " ms" << endl; + break; + default: + break; } return true; } -PeerSession::PeerSession(bi::tcp::socket _socket, uint _rNId): m_socket(std::move(_socket)), m_reqNetworkId(_rNId) +void PeerSession::ping() { + RLPStream s; + sealAndSend(prep(s).appendList(1) << Ping); + m_ping = std::chrono::steady_clock::now(); } -PeerSession::~PeerSession() -{ - disconnect(); -} - -void PeerSession::prep(RLPStream& _s) +RLPStream& PeerSession::prep(RLPStream& _s) { - _s.appendRaw(bytes(8, 0)); + return _s.appendRaw(bytes(8, 0)); } void PeerSession::sealAndSend(RLPStream& _s) @@ -89,6 +110,7 @@ void PeerSession::disconnect() s.appendList(1) << Disconnect; sealAndSend(s); sleep(1); + m_socket.close(); } void PeerSession::start() @@ -108,7 +130,6 @@ void PeerSession::doRead() { if (!ec) { - std::cout << "Got data" << std::endl; m_incoming.resize(m_incoming.size() + length); memcpy(m_incoming.data() + m_incoming.size() - length, m_data.data(), length); while (m_incoming.size() > 8) @@ -128,7 +149,6 @@ void PeerSession::doRead() break; } } - //doWrite(length); doRead(); }); } @@ -185,6 +205,19 @@ bool PeerServer::connect(string const& _addr, uint _port) } } +void PeerServer::process() +{ + m_ioService.poll(); + // TODO: Gather all transactions, blocks & peers. +} + +void PeerServer::pingAll() +{ + for (auto& i: m_peers) + if (auto j = i.lock()) + j->ping(); +} + void PeerServer::sync(BlockChain& _bc, TransactionQueue const& _tq) { /* diff --git a/libethereum/PeerNetwork.h b/libethereum/PeerNetwork.h index 083277695..3057cfd90 100644 --- a/libethereum/PeerNetwork.h +++ b/libethereum/PeerNetwork.h @@ -57,40 +57,48 @@ public: ~PeerSession(); void start(); - - bool interpret(RLP const& _r); - void disconnect(); + void ping(); + private: void doRead(); void doWrite(std::size_t length); + bool interpret(RLP const& _r); - void prep(RLPStream& _s); + RLPStream& prep(RLPStream& _s); void sealAndSend(RLPStream& _s); void send(bytes& _msg); bi::tcp::socket m_socket; - std::array m_data; + std::array m_data; bytes m_incoming; std::string m_clientVersion; uint m_protocolVersion; uint m_networkId; uint m_reqNetworkId; + + std::vector m_incomingTransactions; + std::vector m_incomingBlocks; + std::vector m_incomingPeers; + + std::chrono::steady_clock::time_point m_ping; }; class PeerServer { public: + /// Start server, listening for connections on the given port. PeerServer(uint _networkId, short _port); + /// Start server, but don't listen. PeerServer(uint _networkId); /// Conduct I/O, polling, syncing, whatever. /// Ideally all time-consuming I/O is done in a background thread, but you get this call every 100ms or so anyway. - void run() { m_ioService.run(); } - void process() { m_ioService.poll(); } + void process(); + /// Connect to a peer explicitly. bool connect(std::string const& _addr = "127.0.0.1", uint _port = 30303); /// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network. @@ -102,6 +110,8 @@ public: /// Remove incoming transaction from the queue. Make sure you've finished with the data from any previous incomingTransaction() calls. void popIncomingTransaction() {} + void pingAll(); + private: void doAccept(); diff --git a/test/peer.cpp b/test/peer.cpp index 6a32c00e3..64998fd50 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -49,10 +49,12 @@ int peerTest(int argc, char** argv) if (!remoteHost.empty()) pn.connect(remoteHost, remotePort); - while (true) + for (int i = 0; ; ++i) { usleep(100000); pn.process(); + if (!(i % 10)) + pn.pingAll(); } return 0;