diff --git a/TODO b/TODO index 39877c0de..b7205d6de 100644 --- a/TODO +++ b/TODO @@ -15,6 +15,9 @@ Network: - Make work with IPv6 - Consider node addresses +CLI client +- Implement CLI option "--help". + ### GAV diff --git a/eth/main.cpp b/eth/main.cpp index 56389f778..7c2295373 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -56,6 +56,9 @@ int main(int argc, char** argv) bool interactive = false; string dbPath; eth::uint mining = ~(eth::uint)0; + unsigned verbosity = 1; + NodeMode mode = NodeMode::Full; + unsigned peers = 5; // Our address. KeyPair us = KeyPair::create(); @@ -79,27 +82,44 @@ int main(int argc, char** argv) for (int i = 1; i < argc; ++i) { string arg = argv[i]; - if (arg == "-l" && i + 1 < argc) + if ((arg == "-l" || arg == "--listen" || arg == "--listen-port") && i + 1 < argc) listenPort = atoi(argv[++i]); - else if (arg == "-r" && i + 1 < argc) + else if ((arg == "-r" || arg == "--remote") && i + 1 < argc) remoteHost = argv[++i]; - else if (arg == "-p" && i + 1 < argc) + else if ((arg == "-p" || arg == "--port") && i + 1 < argc) remotePort = atoi(argv[++i]); - else if (arg == "-a" && i + 1 < argc) + else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) coinbase = h160(fromUserHex(argv[++i])); - else if (arg == "-s" && i + 1 < argc) + else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) us = KeyPair(h256(fromUserHex(argv[++i]))); - else if (arg == "-i") + else if (arg == "-i" || arg == "--interactive") interactive = true; - else if (arg == "-d" && i + 1 < argc) + else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) dbPath = argv[++i]; - else if (arg == "-m" && i + 1 < argc) + else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) if (string(argv[++i]) == "on") mining = ~(eth::uint)0; else if (string(argv[i]) == "off") mining = 0; else mining = atoi(argv[i]); + else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) + verbosity = atoi(argv[++i]); + else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) + peers = atoi(argv[++i]); + else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) + { + string m = argv[++i]; + if (m == "full") + mode = NodeMode::Full; + else if (m == "peer") + mode = NodeMode::PeerServer; + else + { + cerr << "Unknown mode: " << m << endl; + return -1; + } + } else remoteHost = argv[i]; } @@ -165,7 +185,7 @@ int main(int argc, char** argv) } else { - c.startNetwork(listenPort, remoteHost, remotePort); + c.startNetwork(listenPort, remoteHost, remotePort, verbosity, mode, peers); eth::uint n = c.blockChain().details().number; while (true) { diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index b29c82499..3ab46e611 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -50,11 +50,14 @@ Client::~Client() usleep(10000); } -void Client::startNetwork(short _listenPort, std::string const& _seedHost, short _port) +void Client::startNetwork(short _listenPort, std::string const& _seedHost, short _port, unsigned _verbosity, NodeMode _mode, unsigned _peers) { if (m_net) return; m_net = new PeerServer(m_clientVersion, m_bc, 0, _listenPort); + m_net->setMode(_mode); + m_net->setIdealPeerCount(_peers); + m_net->setVerbosity(_verbosity); if (_seedHost.size()) m_net->connect(_seedHost, _port); } diff --git a/libethereum/Client.h b/libethereum/Client.h index 8b523994a..ddd530e70 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -60,7 +60,7 @@ public: std::vector peers() { return m_net ? m_net->peers() : std::vector(); } unsigned peerCount() const { return m_net ? m_net->peerCount() : 0; } - void startNetwork(short _listenPort = 30303, std::string const& _seedHost = std::string(), short _port = 30303); + void startNetwork(short _listenPort = 30303, std::string const& _seedHost = std::string(), short _port = 30303, unsigned _verbosity = 0, NodeMode _mode = NodeMode::Full, unsigned _peers = 5); void connect(std::string const& _seedHost, short _port = 30303); void stopNetwork(); diff --git a/libethereum/PeerNetwork.cpp b/libethereum/PeerNetwork.cpp index 1dd6351b2..b1e2c4c76 100644 --- a/libethereum/PeerNetwork.cpp +++ b/libethereum/PeerNetwork.cpp @@ -54,15 +54,18 @@ bi::tcp::endpoint PeerSession::endpoint() const bool PeerSession::interpret(RLP const& _r) { - cout << ">>> " << _r << endl; + if (m_server->m_verbosity >= 4) + cout << ">>> " << _r << endl; switch (_r[0].toInt()) { case Hello: { - cout << std::setw(2) << m_socket.native_handle() << " | Hello" << endl; m_protocolVersion = _r[1].toInt(); m_networkId = _r[2].toInt(); auto clientVersion = _r[3].toString(); + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | Hello: " << clientVersion << endl; + m_listenPort = _r.itemCount() > 4 ? _r[4].toInt() : -1; if (m_protocolVersion != 0 || m_networkId != m_reqNetworkId) { @@ -77,8 +80,6 @@ bool PeerSession::interpret(RLP const& _r) return false; } - cout << std::setw(2) << m_socket.native_handle() << " | Client version: " << clientVersion << endl; - // Grab their block chain off them. { unsigned count = std::min(256, m_server->m_chain->details(m_server->m_latestBlockSent).number); @@ -94,6 +95,15 @@ bool PeerSession::interpret(RLP const& _r) break; } case Disconnect: + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | Disconnect" << endl; + if (m_server->m_verbosity >= 1) + { + if (m_socket.is_open()) + cout << "Closing " << m_socket.remote_endpoint() << endl; + else + cout << "Remote closed on " << m_socket.native_handle() << endl; + } m_socket.close(); return false; case Ping: @@ -109,25 +119,29 @@ bool PeerSession::interpret(RLP const& _r) break; case GetPeers: { - cout << std::setw(2) << m_socket.native_handle() << " | GetPeers" << endl; + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | GetPeers" << endl; std::vector peers = m_server->potentialPeers(); RLPStream s; prep(s).appendList(peers.size() + 1); s << (uint)Peers; for (auto i: peers) { - cout << " Sending peer " << i << endl; + if (m_server->m_verbosity >= 3) + cout << " Sending peer " << i << endl; s.appendList(2) << i.address().to_v4().to_bytes() << i.port(); } sealAndSend(s); break; } case Peers: - cout << std::setw(2) << m_socket.native_handle() << " | Peers (" << dec << (_r.itemCount() - 1) << " entries)" << endl; + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | Peers (" << dec << (_r.itemCount() - 1) << " entries)" << endl; for (unsigned i = 1; i < _r.itemCount(); ++i) { auto ep = bi::tcp::endpoint(bi::address_v4(_r[i][0].toArray()), _r[i][1].toInt()); - cout << "Checking: " << ep << endl; + if (m_server->m_verbosity >= 6) + cout << "Checking: " << ep << endl; // check that we're not already connected to addr: for (auto i: m_server->m_addresses) if (ep.address() == i && ep.port() == m_server->listenPort()) @@ -137,14 +151,16 @@ bool PeerSession::interpret(RLP const& _r) if (p->m_socket.is_open() && p->endpoint() == ep) goto CONTINUE; m_server->m_incomingPeers.push_back(ep); - cout << "New peer: " << ep << endl; + if (m_server->m_verbosity >= 3) + cout << "New peer: " << ep << endl; CONTINUE:; } break; case Transactions: if (m_server->m_mode == NodeMode::PeerServer) break; - cout << std::setw(2) << m_socket.native_handle() << " | Transactions (" << dec << (_r.itemCount() - 1) << " entries)" << endl; + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | Transactions (" << dec << (_r.itemCount() - 1) << " entries)" << endl; m_rating += _r.itemCount() - 1; for (unsigned i = 1; i < _r.itemCount(); ++i) { @@ -155,7 +171,8 @@ bool PeerSession::interpret(RLP const& _r) case Blocks: if (m_server->m_mode == NodeMode::PeerServer) break; - cout << std::setw(2) << m_socket.native_handle() << " | Blocks (" << dec << (_r.itemCount() - 1) << " entries)" << endl; + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | Blocks (" << dec << (_r.itemCount() - 1) << " entries)" << endl; m_rating += _r.itemCount() - 1; for (unsigned i = 1; i < _r.itemCount(); ++i) { @@ -186,7 +203,8 @@ bool PeerSession::interpret(RLP const& _r) break; // return 2048 block max. uint baseCount = (uint)min(_r[_r.itemCount() - 1].toInt(), 256); - cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << baseCount << " max, from " << parents.front() << " to " << parents.back() << ")" << endl; + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | GetChain (" << baseCount << " max, from " << parents.front() << " to " << parents.back() << ")" << endl; for (auto parent: parents) { auto h = m_server->m_chain->currentHash(); @@ -230,7 +248,8 @@ bool PeerSession::interpret(RLP const& _r) if (parent == parents.back()) { // out of parents... - cout << std::setw(2) << m_socket.native_handle() << " | GetChain failed; not in chain" << endl; + if (m_server->m_verbosity >= 6) + cout << std::setw(2) << m_socket.native_handle() << " | GetChain failed; not in chain" << endl; // No good - must have been on a different branch. s.clear(); prep(s).appendList(2) << (uint)NotInChain << parents.back(); @@ -251,7 +270,8 @@ bool PeerSession::interpret(RLP const& _r) if (m_server->m_mode == NodeMode::PeerServer) break; h256 noGood = _r[1].toHash(); - cout << std::setw(2) << m_socket.native_handle() << " | NotInChain (" << noGood << ")" << endl; + if (m_server->m_verbosity >= 2) + cout << std::setw(2) << m_socket.native_handle() << " | NotInChain (" << noGood << ")" << endl; if (noGood != m_server->m_chain->genesisHash()) { unsigned count = std::min(256, m_server->m_chain->details(noGood).number); @@ -285,9 +305,10 @@ RLPStream& PeerSession::prep(RLPStream& _s) return _s.appendRaw(bytes(8, 0)); } -void PeerSession::seal(bytes& _b) +void PeerServer::seal(bytes& _b) { - cout << "<<< " << RLP(bytesConstRef(&_b).cropped(8)) << endl; + if (m_verbosity >= 5) + cout << "<<< " << RLP(bytesConstRef(&_b).cropped(8)) << endl; _b[0] = 0x22; _b[1] = 0x40; _b[2] = 0x08; @@ -303,7 +324,7 @@ void PeerSession::sealAndSend(RLPStream& _s) { bytes b; _s.swapOut(b); - seal(b); + m_server->seal(b); sendDestroy(b); } @@ -337,6 +358,11 @@ void PeerSession::send(bytesConstRef _msg) void PeerSession::dropped() { + if (m_server->m_verbosity >= 1) + { + if (m_socket.is_open()) + cout << "Closing " << m_socket.remote_endpoint() << endl; + } m_socket.close(); for (auto i = m_server->m_peers.begin(); i != m_server->m_peers.end(); ++i) if (i->lock().get() == this) @@ -359,7 +385,16 @@ void PeerSession::disconnect() m_disconnect = chrono::steady_clock::now(); } else + { + if (m_server->m_verbosity >= 1) + { + if (m_socket.is_open()) + cout << "Closing " << m_socket.remote_endpoint() << endl; + else + cout << "Remote closed on" << m_socket.native_handle() << endl; + } m_socket.close(); + } } } @@ -392,7 +427,8 @@ void PeerSession::doRead() { if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91) { - cout << "*** Out of alignment: skipping: " << hex << showbase << (int)m_incoming[0] << endl; + if (m_server->m_verbosity) + cerr << std::setw(2) << m_socket.native_handle() << " | Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << endl; memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1); m_incoming.resize(m_incoming.size() - 1); } @@ -416,7 +452,8 @@ void PeerSession::doRead() } catch (std::exception const& _e) { - cout << std::setw(2) << m_socket.native_handle() << " | ERROR: " << _e.what() << endl; + if (m_server->m_verbosity) + cerr << std::setw(2) << m_socket.native_handle() << " | ERROR: " << _e.what() << endl; dropped(); } } @@ -433,7 +470,7 @@ PeerServer::PeerServer(std::string const& _clientVersion, BlockChain const& _ch, m_requiredNetworkId(_networkId) { populateAddresses(); - doAccept(); + ensureAccepting(); } PeerServer::PeerServer(std::string const& _clientVersion, uint _networkId): @@ -475,7 +512,8 @@ void PeerServer::populateAddresses() m_addresses.push_back(ep.address().to_v4()); if (ifa->ifa_name != string("lo")) m_peerAddresses.push_back(ep.address().to_v4()); - cout << "Address: " << host << " = " << m_addresses.back() << (ifa->ifa_name != string("lo") ? " [PEER]" : " [LOCAL]") << endl; + if (m_verbosity >= 1) + cout << "Address: " << host << " = " << m_addresses.back() << (ifa->ifa_name != string("lo") ? " [PEER]" : " [LOCAL]") << endl; } } @@ -493,39 +531,57 @@ std::vector PeerServer::potentialPeers() return ret; } -void PeerServer::doAccept() +void PeerServer::ensureAccepting() { - cout << "Listening on " << m_acceptor.local_endpoint() << endl; - m_acceptor.async_accept(m_socket, [&](boost::system::error_code ec) + if (m_accepting == false) { - if (!ec) + if (m_verbosity >= 1) + cout << "Listening on port " << m_acceptor.local_endpoint().port() << endl; + m_accepting = true; + m_acceptor.async_accept(m_socket, [&](boost::system::error_code ec) { - cout << "Accepted connection from " << m_socket.remote_endpoint() << std::endl; - auto p = std::make_shared(this, std::move(m_socket), m_requiredNetworkId); - m_peers.push_back(p); - p->start(); - } - doAccept(); - }); + if (!ec) + try + { + if (m_verbosity >= 1) + cout << "Accepted connection from " << m_socket.remote_endpoint() << std::endl; + auto p = std::make_shared(this, std::move(m_socket), m_requiredNetworkId); + m_peers.push_back(p); + p->start(); + } + catch (std::exception const& _e) + { + if (m_verbosity) + cerr << "*** ERROR: " << _e.what() << endl; + } + + m_accepting = false; + if (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount) + ensureAccepting(); + }); + } } bool PeerServer::connect(string const& _addr, uint _port) { bi::tcp::resolver resolver(m_ioService); - cout << "Attempting connection to " << _addr << ":" << dec << _port << endl; + if (m_verbosity >= 1) + cout << "Attempting connection to " << _addr << ":" << dec << _port << endl; try { bi::tcp::socket s(m_ioService); boost::asio::connect(s, resolver.resolve({ _addr, toString(_port) })); auto p = make_shared(this, std::move(s), m_requiredNetworkId); m_peers.push_back(p); - cout << "Connected." << endl; + if (m_verbosity >= 1) + cout << "Connected." << endl; p->start(); return true; } catch (exception& _e) { - cout << "Connection refused (" << _e.what() << ")" << endl; + if (m_verbosity >= 1) + cout << "Connection refused (" << _e.what() << ")" << endl; return false; } } @@ -533,20 +589,23 @@ bool PeerServer::connect(string const& _addr, uint _port) bool PeerServer::connect(bi::tcp::endpoint _ep) { bi::tcp::resolver resolver(m_ioService); - cout << "Attempting connection to " << _ep << endl; + if (m_verbosity >= 1) + cout << "Attempting connection to " << _ep << endl; try { bi::tcp::socket s(m_ioService); boost::asio::connect(s, resolver.resolve(_ep)); auto p = make_shared(this, std::move(s), m_requiredNetworkId); m_peers.push_back(p); - cout << "Connected." << endl; + if (m_verbosity >= 1) + cout << "Connected." << endl; p->start(); return true; } catch (exception& _e) { - cout << "Connection refused (" << _e.what() << ")" << endl; + if (m_verbosity >= 1) + cout << "Connection refused (" << _e.what() << ")" << endl; return false; } } @@ -555,34 +614,46 @@ bool PeerServer::process(BlockChain& _bc) { bool ret = false; m_ioService.poll(); - for (auto i = m_peers.begin(); i != m_peers.end();) - { - auto p = i->lock(); - if (p && p->m_socket.is_open() && - (p->m_disconnect == chrono::steady_clock::time_point::max() || chrono::steady_clock::now() - p->m_disconnect < chrono::seconds(1))) // kill old peers that should be disconnected. - ++i; - else + + auto n = chrono::steady_clock::now(); + bool fullProcess = (n > m_lastFullProcess + chrono::seconds(1)); + if (fullProcess) + m_lastFullProcess = n; + + if (fullProcess) + for (auto i = m_peers.begin(); i != m_peers.end();) { - i = m_peers.erase(i); - ret = true; + auto p = i->lock(); + if (p && p->m_socket.is_open() && + (p->m_disconnect == chrono::steady_clock::time_point::max() || chrono::steady_clock::now() - p->m_disconnect < chrono::seconds(1))) // kill old peers that should be disconnected. + ++i; + else + { + i = m_peers.erase(i); + ret = true; + } } - } return ret; } bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) { bool ret = false; + if (m_latestBlockSent == h256()) { // First time - just initialise. m_latestBlockSent = _bc.currentHash(); for (auto const& i: _tq.transactions()) m_transactionsSent.insert(i.first); - m_lastPeersRequest = chrono::steady_clock::now(); + m_lastPeersRequest = chrono::steady_clock::time_point::min(); + m_lastFullProcess = chrono::steady_clock::time_point::min(); ret = true; } + auto n = chrono::steady_clock::now(); + bool fullProcess = (n > m_lastFullProcess + chrono::seconds(1)); + if (process(_bc)) ret = true; @@ -594,31 +665,33 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) m_incomingTransactions.clear(); // Send any new transactions. - for (auto j: m_peers) - if (auto p = j.lock()) - { - bytes b; - uint n = 0; - for (auto const& i: _tq.transactions()) - if (!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first)) + if (fullProcess) + for (auto j: m_peers) + if (auto p = j.lock()) + { + bytes b; + uint n = 0; + for (auto const& i: _tq.transactions()) + if (!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first)) + { + b += i.second; + ++n; + m_transactionsSent.insert(i.first); + } + if (n) { - b += i.second; - ++n; - m_transactionsSent.insert(i.first); + RLPStream ts; + PeerSession::prep(ts); + ts.appendList(2) << Transactions; + ts.appendList(n).appendRaw(b).swapOut(b); + seal(b); + p->send(&b); } - if (n) - { - RLPStream ts; - PeerSession::prep(ts); - ts.appendList(2) << Transactions; - ts.appendList(n).appendRaw(b).swapOut(b); - PeerSession::seal(b); - p->send(&b); + p->m_knownTransactions.clear(); } - p->m_knownTransactions.clear(); - } // Send any new blocks. + if (fullProcess) { auto h = _bc.currentHash(); if (h != m_latestBlockSent) @@ -629,7 +702,7 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) ts.appendList(2) << Blocks; bytes b; ts.appendList(1).appendRaw(_bc.block(_bc.currentHash())).swapOut(b); - PeerSession::seal(b); + seal(b); for (auto j: m_peers) if (auto p = j.lock()) { @@ -641,32 +714,33 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) m_latestBlockSent = h; } - for (bool accepted = 1; accepted;) - { - accepted = 0; - if (m_incomingBlocks.size()) - for (auto it = prev(m_incomingBlocks.end());; --it) - { - try - { - _bc.import(*it, _o); - it = m_incomingBlocks.erase(it); - ++accepted; - ret = true; - } - catch (UnknownParent) - { - // Don't (yet) know its parent. Leave it for later. - } - catch (...) + if (fullProcess) + for (bool accepted = 1; accepted;) + { + accepted = 0; + if (m_incomingBlocks.size()) + for (auto it = prev(m_incomingBlocks.end());; --it) { - // Some other error - erase it. - it = m_incomingBlocks.erase(it); - } + try + { + _bc.import(*it, _o); + it = m_incomingBlocks.erase(it); + ++accepted; + ret = true; + } + catch (UnknownParent) + { + // Don't (yet) know its parent. Leave it for later. + } + catch (...) + { + // Some other error - erase it. + it = m_incomingBlocks.erase(it); + } - if (it == m_incomingBlocks.begin()) - break; - } + if (it == m_incomingBlocks.begin()) + break; + } } // platform for consensus of social contract. @@ -674,45 +748,53 @@ bool PeerServer::process(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) // guarantees that everyone else respect the rules of the system. (i.e. obeys laws). // Connect to additional peers - while (m_peers.size() < m_idealPeerCount) + if (fullProcess) { - if (m_incomingPeers.empty()) + while (m_peers.size() < m_idealPeerCount) { - if (chrono::steady_clock::now() - m_lastPeersRequest > chrono::seconds(10)) + if (m_incomingPeers.empty()) { - RLPStream s; - bytes b; - (PeerSession::prep(s).appendList(1) << GetPeers).swapOut(b); - PeerSession::seal(b); - for (auto const& i: m_peers) - if (auto p = i.lock()) - p->send(&b); - m_lastPeersRequest = chrono::steady_clock::now(); + if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10)) + { + RLPStream s; + bytes b; + (PeerSession::prep(s).appendList(1) << GetPeers).swapOut(b); + seal(b); + for (auto const& i: m_peers) + if (auto p = i.lock()) + p->send(&b); + m_lastPeersRequest = chrono::steady_clock::now(); + } + + + if (!m_accepting) + ensureAccepting(); + + break; } - break; + connect(m_incomingPeers.back()); + m_incomingPeers.pop_back(); + } + while (m_peers.size() > m_idealPeerCount) + { + // look for worst peer to kick off + // first work out how many are old enough to kick off. + shared_ptr worst; + unsigned agedPeers = 0; + for (auto i: m_peers) + if (auto p = i.lock()) + if (chrono::steady_clock::now() > p->m_connect + chrono::seconds(10)) + { + ++agedPeers; + if ((!worst || p->m_rating < worst->m_rating || (p->m_rating == worst->m_rating && p->m_connect > worst->m_connect))) // keep younger ones. + worst = p; + } + if (!worst || agedPeers <= m_idealPeerCount) + break; + worst->dropped(); // should really disconnect, but that's no good. } - connect(m_incomingPeers.back()); - m_incomingPeers.pop_back(); } - while (m_peers.size() > m_idealPeerCount) - { - // look for worst peer to kick off - // first work out how many are old enough to kick off. - shared_ptr worst; - unsigned agedPeers = 0; - for (auto i: m_peers) - if (auto p = i.lock()) - if (chrono::steady_clock::now() - p->m_connect > chrono::seconds(10)) - { - ++agedPeers; - if ((!worst || p->m_rating < worst->m_rating || (p->m_rating == worst->m_rating && p->m_connect > worst->m_connect))) // keep younger ones. - worst = p; - } - if (!worst || agedPeers <= m_idealPeerCount) - break; - worst->dropped(); // should really disconnect, but that's no good. - } return ret; } diff --git a/libethereum/PeerNetwork.h b/libethereum/PeerNetwork.h index 2ab134794..a52359de8 100644 --- a/libethereum/PeerNetwork.h +++ b/libethereum/PeerNetwork.h @@ -83,7 +83,6 @@ private: bool interpret(RLP const& _r); static RLPStream& prep(RLPStream& _s); - static void seal(bytes& _b); void sealAndSend(RLPStream& _s); void sendDestroy(bytes& _msg); void send(bytesConstRef _msg); @@ -140,6 +139,7 @@ public: void setIdealPeerCount(unsigned _n) { m_idealPeerCount = _n; } void setMode(NodeMode _m) { m_mode = _m; } + void setVerbosity(unsigned _i) { m_verbosity = _i; } /// Get peer information. std::vector peers() const; @@ -154,13 +154,25 @@ public: short listenPort() const { return m_acceptor.local_endpoint().port(); } private: + void seal(bytes& _b); void populateAddresses(); - void doAccept(); + void ensureAccepting(); std::vector potentialPeers(); std::string m_clientVersion; NodeMode m_mode = NodeMode::Full; + /** + * 0: Quiet - just errors on stderr. + * 1: Accepting/connecting/connected & one-off info. + * 2: Messages summary. + * 3: Messages detail. + * 4: Received raw. + * 5: Sent raw. + * 6: Debug details. + */ + unsigned m_verbosity = 4; + BlockChain const* m_chain = nullptr; ba::io_service m_ioService; bi::tcp::acceptor m_acceptor; @@ -179,8 +191,12 @@ private: std::chrono::steady_clock::time_point m_lastPeersRequest; unsigned m_idealPeerCount = 5; + std::chrono::steady_clock::time_point m_lastFullProcess; + std::vector m_addresses; std::vector m_peerAddresses; + + bool m_accepting = false; };