@@ -97,7 +97,7 @@ bool NodeTable::addNode(Node const& _node)
9797 return false ;
9898
9999 if (!entry->hasValidEndpointProof ())
100- ping (*entry);
100+ schedulePing (*entry);
101101
102102 return true ;
103103}
@@ -118,7 +118,7 @@ bool NodeTable::addKnownNode(
118118 if (entry->hasValidEndpointProof ())
119119 noteActiveNode (entry->id , entry->endpoint );
120120 else
121- ping (*entry);
121+ schedulePing (*entry);
122122
123123 return true ;
124124}
@@ -326,32 +326,30 @@ vector<shared_ptr<NodeEntry>> NodeTable::nearestNodeEntries(NodeID _target)
326326
327327void NodeTable::ping (NodeEntry const & _nodeEntry, boost::optional<NodeID> const & _replacementNodeID)
328328{
329- m_timers.schedule (0 , [this , _nodeEntry, _replacementNodeID](
330- boost::system::error_code const & _ec) {
329+ // don't sent Ping if one is already sent
330+ if (contains (m_sentPings, _nodeEntry.id ))
331+ return ;
332+
333+ NodeIPEndpoint src;
334+ src = m_hostNodeEndpoint;
335+ PingNode p (src, _nodeEntry.endpoint );
336+ p.ts = nextRequestExpirationTime ();
337+ auto const pingHash = p.sign (m_secret);
338+ LOG (m_logger) << p.typeName () << " to " << _nodeEntry.id << " @" << p.destination ;
339+ m_socket->send (p);
340+
341+ m_sentPings[_nodeEntry.id ] = {chrono::steady_clock::now (), pingHash, _replacementNodeID};
342+ if (m_nodeEventHandler && _replacementNodeID)
343+ m_nodeEventHandler->appendEvent (_nodeEntry.id , NodeEntryScheduledForEviction);
344+ }
345+
346+ void NodeTable::schedulePing (NodeEntry const & _nodeEntry)
347+ {
348+ m_timers.schedule (0 , [this , _nodeEntry](boost::system::error_code const & _ec) {
331349 if (_ec || m_timers.isStopped ())
332350 return ;
333351
334- // don't sent Ping if one is already sent
335- auto sentPing = m_sentPings.find (_nodeEntry.id );
336- if (sentPing != m_sentPings.end ())
337- {
338- // we don't need replacement if we're not going to ping
339- if (_replacementNodeID && sentPing->second .replacementNodeID != _replacementNodeID)
340- DEV_GUARDED (x_nodes) { m_allNodes.erase (*_replacementNodeID); }
341- return ;
342- }
343-
344- NodeIPEndpoint src;
345- src = m_hostNodeEndpoint;
346- PingNode p (src, _nodeEntry.endpoint );
347- p.ts = nextRequestExpirationTime ();
348- auto const pingHash = p.sign (m_secret);
349- LOG (m_logger) << p.typeName () << " to " << _nodeEntry.id << " @" << p.destination ;
350- m_socket->send (p);
351-
352- m_sentPings[_nodeEntry.id ] = {chrono::steady_clock::now (), pingHash, _replacementNodeID};
353- if (m_nodeEventHandler && _replacementNodeID)
354- m_nodeEventHandler->appendEvent (_nodeEntry.id , NodeEntryScheduledForEviction);
352+ ping (_nodeEntry, {});
355353 });
356354}
357355
@@ -360,6 +358,14 @@ void NodeTable::evict(NodeEntry const& _leastSeen, NodeEntry const& _new)
360358 if (!m_socket->isOpen ())
361359 return ;
362360
361+ // if eviction for _leastSeen already started, just forget about _new
362+ auto sentPing = m_sentPings.find (_leastSeen.id );
363+ if (sentPing != m_sentPings.end () && sentPing->second .replacementNodeID != _new.id )
364+ {
365+ DEV_GUARDED (x_nodes) { m_allNodes.erase (_new.id ); }
366+ return ;
367+ }
368+
363369 LOG (m_logger) << " Evicting node " << static_cast <Node const &>(_leastSeen);
364370 ping (_leastSeen, _new.id );
365371}
@@ -502,7 +508,10 @@ void NodeTable::onPacketReceived(
502508 auto const & optionalReplacementID = sentPing->second .replacementNodeID ;
503509 if (optionalReplacementID)
504510 if (auto replacementNode = nodeEntry (*optionalReplacementID))
511+ {
512+ m_sentPings.erase (replacementNode->id );
505513 dropNode (move (replacementNode));
514+ }
506515
507516 m_sentPings.erase (sentPing);
508517
0 commit comments