@@ -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
313313void 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
0 commit comments