diff --git a/TODO b/TODO index 31047dbc8..ea09bbc3d 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,6 @@ Crypto stuff: Network: - *** Exponential backoff on bad connection. -- *** Randomly select peers from incoming peers. - NotInChain will be very bad for new peers - it'll run through until the genesis. - Check how many it has first. - Crypto on network - use id as public key? @@ -19,8 +18,10 @@ Network: - Solid communications? - Strategy for peer suggestion? - - +THREAD-SAFETY +- BlockChain +- TransactionQueue +- State CLI client - Implement CLI option "--help". diff --git a/libethereum/PeerNetwork.cpp b/libethereum/PeerNetwork.cpp index 934b821e4..1e1410c43 100644 --- a/libethereum/PeerNetwork.cpp +++ b/libethereum/PeerNetwork.cpp @@ -244,9 +244,9 @@ bool PeerSession::interpret(RLP const& _r) goto CONTINUE; } for (auto i: m_server->m_incomingPeers) - if (i.second == ep) + if (i.second.first == ep) goto CONTINUE; - m_server->m_incomingPeers[id] = ep; + m_server->m_incomingPeers[id] = make_pair(ep, 0); clogS(NetMessageDetail) << "New peer: " << ep << "(" << id << ")"; CONTINUE:; } @@ -780,6 +780,15 @@ void PeerServer::connect(bi::tcp::endpoint const& _ep) if (ec) { clog(NetNote) << "Connection refused to " << _ep << " (" << ec.message() << ")"; + for (auto i = m_incomingPeers.begin(); i != m_incomingPeers.end(); ++i) + if (i->second.first == _ep && i->second.second < 3) + { + m_freePeers.push_back(i->first); + goto OK; + } + // for-else + clog(NetNote) << "Giving up."; + OK:; } else { @@ -924,7 +933,7 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) // Connect to additional peers while (m_peers.size() < m_idealPeerCount) { - if (m_incomingPeers.empty()) + if (m_freePeers.empty()) { if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10)) { @@ -945,8 +954,11 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) break; } - connect(m_incomingPeers.begin()->second); - m_incomingPeers.erase(m_incomingPeers.begin()); + + auto x = time(0) % m_freePeers.size(); + m_incomingPeers[m_freePeers[x]].second++; + connect(m_incomingPeers[m_freePeers[time(0) % m_freePeers.size()]].first); + m_freePeers.erase(m_freePeers.begin() + x); } } @@ -1015,6 +1027,11 @@ void PeerServer::restorePeers(bytesConstRef _b) { for (auto i: RLP(_b)) { - m_incomingPeers.insert(make_pair((Public)i[2], bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()))); + auto k = (Public)i[2]; + if (!m_incomingPeers.count(k)) + { + m_incomingPeers.insert(make_pair(k, make_pair(bi::tcp::endpoint(bi::address_v4(i[0].toArray()), i[1].toInt()), 0))); + m_freePeers.push_back(k); + } } } diff --git a/libethereum/PeerNetwork.h b/libethereum/PeerNetwork.h index f9ef49a40..e50d238a4 100644 --- a/libethereum/PeerNetwork.h +++ b/libethereum/PeerNetwork.h @@ -217,7 +217,8 @@ private: std::vector m_incomingTransactions; std::vector m_incomingBlocks; std::vector m_unknownParentBlocks; - std::map m_incomingPeers; + std::vector m_freePeers; + std::map> m_incomingPeers; h256 m_latestBlockSent; std::set m_transactionsSent;