Skip to content
This repository was archived by the owner on Oct 28, 2021. It is now read-only.

Commit 9dcc4da

Browse files
committed
Split ping() into synchronous ping() and asynchronous schedulePing()
1 parent 6537567 commit 9dcc4da

File tree

2 files changed

+39
-26
lines changed

2 files changed

+39
-26
lines changed

libp2p/NodeTable.cpp

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ bool NodeTable::addNode(Node const& _node)
8484
return false;
8585

8686
if (!entry->hasValidEndpointProof())
87-
ping(*entry);
87+
schedulePing(*entry);
8888

8989
return true;
9090
}
@@ -105,7 +105,7 @@ bool NodeTable::addKnownNode(
105105
if (entry->hasValidEndpointProof())
106106
noteActiveNode(entry->id, entry->endpoint);
107107
else
108-
ping(*entry);
108+
schedulePing(*entry);
109109

110110
return true;
111111
}
@@ -312,32 +312,30 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeID _target)
312312

313313
void NodeTable::ping(NodeEntry const& _nodeEntry, boost::optional<NodeID> const& _replacementNodeID)
314314
{
315-
m_timers.schedule(0, [this, _nodeEntry, _replacementNodeID](
316-
boost::system::error_code const& _ec) {
315+
// don't sent Ping if one is already sent
316+
if (contains(m_sentPings, _nodeEntry.id))
317+
return;
318+
319+
NodeIPEndpoint src;
320+
src = m_hostNodeEndpoint;
321+
PingNode p(src, _nodeEntry.endpoint);
322+
p.ts = nextRequestExpirationTime();
323+
auto const pingHash = p.sign(m_secret);
324+
LOG(m_logger) << p.typeName() << " to " << _nodeEntry.id << "@" << p.destination;
325+
m_socket->send(p);
326+
327+
m_sentPings[_nodeEntry.id] = {chrono::steady_clock::now(), pingHash, _replacementNodeID};
328+
if (m_nodeEventHandler && _replacementNodeID)
329+
m_nodeEventHandler->appendEvent(_nodeEntry.id, NodeEntryScheduledForEviction);
330+
}
331+
332+
void NodeTable::schedulePing(NodeEntry const& _nodeEntry)
333+
{
334+
m_timers.schedule(0, [this, _nodeEntry](boost::system::error_code const& _ec) {
317335
if (_ec || m_timers.isStopped())
318336
return;
319337

320-
// don't sent Ping if one is already sent
321-
auto sentPing = m_sentPings.find(_nodeEntry.id);
322-
if (sentPing != m_sentPings.end())
323-
{
324-
// we don't need replacement if we're not going to ping
325-
if (_replacementNodeID && sentPing->second.replacementNodeID != _replacementNodeID)
326-
DEV_GUARDED(x_nodes) { m_allNodes.erase(*_replacementNodeID); }
327-
return;
328-
}
329-
330-
NodeIPEndpoint src;
331-
src = m_hostNodeEndpoint;
332-
PingNode p(src, _nodeEntry.endpoint);
333-
p.ts = nextRequestExpirationTime();
334-
auto const pingHash = p.sign(m_secret);
335-
LOG(m_logger) << p.typeName() << " to " << _nodeEntry.id << "@" << p.destination;
336-
m_socket->send(p);
337-
338-
m_sentPings[_nodeEntry.id] = {chrono::steady_clock::now(), pingHash, _replacementNodeID};
339-
if (m_nodeEventHandler && _replacementNodeID)
340-
m_nodeEventHandler->appendEvent(_nodeEntry.id, NodeEntryScheduledForEviction);
338+
ping(_nodeEntry, {});
341339
});
342340
}
343341

@@ -346,6 +344,14 @@ void NodeTable::evict(NodeEntry const& _leastSeen, NodeEntry const& _new)
346344
if (!m_socket->isOpen())
347345
return;
348346

347+
// if eviction for _leastSeen already started, just forget about _new
348+
auto sentPing = m_sentPings.find(_leastSeen.id);
349+
if (sentPing != m_sentPings.end() && sentPing->second.replacementNodeID != _new.id)
350+
{
351+
DEV_GUARDED(x_nodes) { m_allNodes.erase(_new.id); }
352+
return;
353+
}
354+
349355
LOG(m_logger) << "Evicting node " << static_cast<Node const&>(_leastSeen);
350356
ping(_leastSeen, _new.id);
351357
}
@@ -488,7 +494,10 @@ void NodeTable::onPacketReceived(
488494
auto const& optionalReplacementID = sentPing->second.replacementNodeID;
489495
if (optionalReplacementID)
490496
if (auto replacementNode = nodeEntry(*optionalReplacementID))
497+
{
498+
m_sentPings.erase(replacementNode->id);
491499
dropNode(move(replacementNode));
500+
}
492501

493502
m_sentPings.erase(sentPing);
494503

libp2p/NodeTable.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,13 @@ class NodeTable : UDPSocketEvents
205205

206206
/// Used to ping a node to initiate the endpoint proof. Used when contacting neighbours if they
207207
/// don't have a valid endpoint proof (see doDiscover), refreshing buckets and as part of
208-
/// eviction process (see evict). Not synchronous - the ping operation is queued via a timer
208+
/// eviction process (see evict). Synchronous, has to be called only from the network thread.
209209
void ping(NodeEntry const& _nodeEntry, boost::optional<NodeID> const& _replacementNodeID = {});
210210

211+
/// Schedules ping() method to be called from the network thread.
212+
/// Not synchronous - the ping operation is queued via a timer.
213+
void schedulePing(NodeEntry const& _nodeEntry);
214+
211215
/// Used by asynchronous operations to return NodeEntry which is active and managed by node table.
212216
std::shared_ptr<NodeEntry> nodeEntry(NodeID _id);
213217

0 commit comments

Comments
 (0)