Browse Source

Grow peers uses latest mechanisms.

cl-refactor
Gav Wood 10 years ago
parent
commit
7c0ca05bb8
  1. 2
      libdevcore/RangeMask.h
  2. 68
      libp2p/Host.cpp
  3. 27
      libp2p/Host.h

2
libdevcore/RangeMask.h

@ -181,7 +181,7 @@ public:
}
std::pair<T, T> const& all() const { return m_all; }
void extendAll(T _max) { m_all.second = _max + 1; }
void extendAll(T _i) { m_all = std::make_pair(std::min(m_all.first, _i), std::max(m_all.second, _i + 1)); }
class const_iterator
{

68
libp2p/Host.cpp

@ -396,6 +396,7 @@ Nodes Host::potentialPeers(RangeMask<unsigned> const& _known)
{
RecursiveGuard l(x_peers);
Nodes ret;
for (auto i: m_ready - (m_private + _known))
ret.push_back(*m_nodes[m_nodesList[i]]);
return ret;
@ -530,40 +531,59 @@ bool Host::havePeer(NodeId _id) const
return !!m_peers.count(_id);
}
unsigned cumulativeFallback(unsigned _failed)
{
if (_failed < 5)
return _failed * 5;
else if (_failed < 15)
return 25 + (_failed - 5) * 10;
else
return 25 + 100 + (_failed - 15) * 20;
}
void Host::growPeers()
{
RecursiveGuard l(x_peers);
while (m_peers.size() < m_idealPeerCount)
int morePeers = (int)m_idealPeerCount - m_peers.size();
if (morePeers > 0)
{
// TODO: Make work with m_ready/m_private using all the Node information.
if (m_freePeers.empty())
{
if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10))
auto toTry = m_ready;
if (m_netPrefs.localNetworking)
toTry -= m_private;
set<Node> 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)))
ns.insert(*m_nodes[m_nodesList[i]]);
if (ns.size())
for (Node const& i: ns)
{
RLPStream s;
bytes b;
Session::prep(s, GetPeersPacket).swapOut(b);
seal(b);
for (auto const& i: m_peers)
if (auto p = i.second.lock())
if (p->isOpen())
p->send(&b);
m_lastPeersRequest = chrono::steady_clock::now();
m_nodes[i.id]->connect(this);
if (!--morePeers)
return;
}
if (!m_accepting)
ensureAccepting();
break;
else
{
ensureAccepting();
if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10))
requestPeers();
}
auto x = time(0) % m_freePeers.size();
if (!m_peers.count(m_freePeers[x]))
connect(m_nodes[m_freePeers[x]]->address);
m_freePeers.erase(m_freePeers.begin() + x);
}
}
void Host::requestPeers()
{
RLPStream s;
bytes b;
Session::prep(s, GetPeersPacket).swapOut(b);
seal(b);
for (auto const& i: m_peers)
if (auto p = i.second.lock())
if (p->isOpen())
p->send(&b);
m_lastPeersRequest = chrono::steady_clock::now();
}
void Host::prunePeers()
{
RecursiveGuard l(x_peers);

27
libp2p/Host.h

@ -69,7 +69,27 @@ struct Node
unsigned failedAttempts = 0;
int lastDisconnect = -1; ///< Reason for disconnect that happened last.
Origin idOrigin = Origin::Unknown; ///< Thirdparty
Origin idOrigin = Origin::Unknown; ///< Thirdparty
bool offline() const { return lastDisconnect == -1 || lastAttempted > lastConnected; }
bool operator<(Node const& _n) const
{
if (offline() != _n.offline())
return offline();
else if (offline())
if (lastAttempted == _n.lastAttempted)
return failedAttempts < _n.failedAttempts;
else
return lastAttempted < _n.lastAttempted;
else
if (score == _n.score)
if (rating == _n.rating)
return failedAttempts < _n.failedAttempts;
else
return rating < _n.rating;
else
return score < _n.score;
}
void connect(Host* _h);
};
@ -174,6 +194,8 @@ private:
std::shared_ptr<Node> noteNode(NodeId _id, bi::tcp::endpoint const& _a, Origin _o, bool _ready, NodeId _oldId = h256());
Nodes potentialPeers(RangeMask<unsigned> const& _known);
void requestPeers();
std::string m_clientVersion; ///< Our version string.
NetworkPreferences m_netPrefs; ///< Network settings.
@ -205,8 +227,7 @@ private:
RangeMask<unsigned> m_ready; ///< Indices into m_nodesList over to which nodes we are not currently connected, connecting or otherwise ignoring.
RangeMask<unsigned> m_private; ///< Indices into m_nodesList over to which nodes are private.
std::vector<NodeId> m_freePeers;// TODO: Kill
std::chrono::steady_clock::time_point m_lastPeersRequest;// TODO: Kill
std::chrono::steady_clock::time_point m_lastPeersRequest; ///< Last time we asked for some peers - don't want to do this too often. TODO: peers should be pushed, not polled.
unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to.

Loading…
Cancel
Save