@@ -79,7 +79,7 @@ struct TestNodeTable: public NodeTable
7979 auto entry = make_shared<NodeEntry>(m_hostNodeID, n.first ,
8080 NodeIPEndpoint (ourIp, n.second , n.second ),
8181 RLPXDatagramFace::secondsSinceEpoch (), RLPXDatagramFace::secondsSinceEpoch ());
82- noteActiveNode (move (entry), bi::udp::endpoint (ourIp, n. second ) );
82+ noteActiveNode (move (entry));
8383 }
8484 else
8585 break ;
@@ -100,7 +100,7 @@ struct TestNodeTable: public NodeTable
100100 NodeIPEndpoint (ourIp, testNode->second , testNode->second ),
101101 RLPXDatagramFace::secondsSinceEpoch (), RLPXDatagramFace::secondsSinceEpoch ()));
102102 auto distance = node->distance ;
103- noteActiveNode (move (node), bi::udp::endpoint (ourIp, testNode-> second ) );
103+ noteActiveNode (move (node));
104104
105105 {
106106 Guard stateGuard (x_state);
@@ -138,7 +138,7 @@ struct TestNodeTable: public NodeTable
138138 auto entry = make_shared<NodeEntry>(m_hostNodeID, testNode->first ,
139139 NodeIPEndpoint (ourIp, testNode->second , testNode->second ),
140140 RLPXDatagramFace::secondsSinceEpoch (), RLPXDatagramFace::secondsSinceEpoch ());
141- noteActiveNode (move (entry), bi::udp::endpoint (ourIp, testNode-> second ) );
141+ noteActiveNode (move (entry));
142142
143143 ++testNode;
144144 }
@@ -500,7 +500,7 @@ BOOST_AUTO_TEST_CASE(noteActiveNodeUpdatesKnownNode)
500500 auto & nodeTable = nodeTableHost.nodeTable ;
501501 auto knownNode = nodeTable->bucketFirstNode (bucketIndex);
502502
503- nodeTable->noteActiveNode (knownNode, knownNode-> endpoint () );
503+ nodeTable->noteActiveNode (knownNode);
504504
505505 // check that node was moved to the back of the bucket
506506 BOOST_CHECK_NE (nodeTable->bucketFirstNode (bucketIndex), knownNode);
@@ -550,32 +550,6 @@ BOOST_AUTO_TEST_CASE(noteActiveNodeEvictsTheNodeWhenBucketIsFull)
550550 BOOST_CHECK_EQUAL (evicted->replacementNodeEntry ->id (), newNodeId);
551551}
552552
553- BOOST_AUTO_TEST_CASE (noteActiveNodeReplacesNodeInFullBucketWhenEndpointChanged)
554- {
555- TestNodeTableHost nodeTableHost (512 );
556- int const bucketIndex = nodeTableHost.populateUntilBucketSize (16 );
557- BOOST_REQUIRE (bucketIndex >= 0 );
558-
559- auto & nodeTable = nodeTableHost.nodeTable ;
560- auto leastRecentlySeenNode = nodeTable->bucketFirstNode (bucketIndex);
561-
562- // addNode will replace the node in the m_allNodes map, because it's the same id with enother
563- // endpoint
564- auto const port = randomPortNumber ();
565- NodeIPEndpoint newEndpoint{bi::address::from_string (c_localhostIp), port, port };
566- nodeTable->noteActiveNode (leastRecentlySeenNode, newEndpoint);
567-
568- // the bucket is still max size
569- BOOST_CHECK_EQUAL (nodeTable->bucketSize (bucketIndex), 16 );
570- // least recently seen node removed
571- BOOST_CHECK_NE (nodeTable->bucketFirstNode (bucketIndex)->id (), leastRecentlySeenNode->id ());
572- // but added as most recently seen with new endpoint
573- auto mostRecentNodeEntry = nodeTable->bucketLastNode (bucketIndex);
574- BOOST_CHECK_EQUAL (mostRecentNodeEntry->id (), leastRecentlySeenNode->id ());
575- BOOST_CHECK_EQUAL (mostRecentNodeEntry->endpoint ().address (), newEndpoint.address ());
576- BOOST_CHECK_EQUAL (mostRecentNodeEntry->endpoint ().udpPort (), newEndpoint.udpPort ());
577- }
578-
579553BOOST_AUTO_TEST_CASE (unexpectedPong)
580554{
581555 // NodeTable receiving PONG
@@ -1173,6 +1147,140 @@ BOOST_AUTO_TEST_CASE(addNodePingsNodeOnlyOnce)
11731147 BOOST_REQUIRE_EQUAL (sentPing->pingHash , sentPing2->pingHash );
11741148}
11751149
1150+ class PacketsWithChangedEndpointFixture : public TestOutputHelperFixture
1151+ {
1152+ public:
1153+ PacketsWithChangedEndpointFixture ()
1154+ {
1155+ nodeTableHost.start ();
1156+ nodeSocketHost1.start ();
1157+ nodePort1 = nodeSocketHost1.port ;
1158+ nodeSocketHost2.start ();
1159+ nodePort2 = nodeSocketHost2.port ;
1160+
1161+ nodeEndpoint1 =
1162+ NodeIPEndpoint{bi::address::from_string (c_localhostIp), nodePort1, nodePort1};
1163+ nodeEndpoint2 =
1164+ NodeIPEndpoint{bi::address::from_string (c_localhostIp), nodePort2, nodePort2};
1165+
1166+ // add a node to node table, initiating PING
1167+ nodeTable->addNode (Node{nodePubKey, nodeEndpoint1});
1168+
1169+ // handle received PING
1170+ auto pingDataReceived = nodeSocketHost1.packetsReceived .pop (chrono::seconds (5 ));
1171+ auto pingDatagram =
1172+ DiscoveryDatagram::interpretUDP (bi::udp::endpoint{}, dev::ref (pingDataReceived));
1173+ BOOST_REQUIRE_EQUAL (pingDatagram->typeName (), " Ping" );
1174+ auto ping = dynamic_cast <PingNode const &>(*pingDatagram);
1175+
1176+ // send PONG
1177+ Pong pong{nodeTable->m_hostNodeEndpoint };
1178+ pong.echo = ping.echo ;
1179+ pong.sign (nodeKeyPair.secret ());
1180+ nodeSocketHost1.socket ->send (pong);
1181+
1182+ // wait for PONG to be received and handled
1183+ nodeTable->packetsReceived .pop (chrono::seconds (5 ));
1184+
1185+ nodeEntry = nodeTable->nodeEntry (nodePubKey);
1186+ }
1187+
1188+ TestNodeTableHost nodeTableHost{0 };
1189+ shared_ptr<TestNodeTable>& nodeTable = nodeTableHost.nodeTable;
1190+
1191+ // socket representing initial peer node
1192+ TestUDPSocketHost nodeSocketHost1;
1193+ uint16_t nodePort1 = 0 ;
1194+
1195+ // socket representing peer with changed endpoint
1196+ TestUDPSocketHost nodeSocketHost2;
1197+ uint16_t nodePort2 = 0 ;
1198+
1199+ NodeIPEndpoint nodeEndpoint1;
1200+ NodeIPEndpoint nodeEndpoint2;
1201+ KeyPair nodeKeyPair = KeyPair::create();
1202+ NodeID nodePubKey = nodeKeyPair.pub();
1203+
1204+ shared_ptr<NodeEntry> nodeEntry;
1205+ };
1206+
1207+ BOOST_FIXTURE_TEST_SUITE (packetsWithChangedEndpointSuite, PacketsWithChangedEndpointFixture)
1208+
1209+ BOOST_AUTO_TEST_CASE(addNode)
1210+ {
1211+ // this should initiate Ping to endpoint 2
1212+ nodeTable->addNode (Node{nodePubKey, nodeEndpoint2});
1213+
1214+ // handle received PING
1215+ auto pingDataReceived = nodeSocketHost2.packetsReceived .pop ();
1216+ auto pingDatagram =
1217+ DiscoveryDatagram::interpretUDP (bi::udp::endpoint{}, dev::ref (pingDataReceived));
1218+ BOOST_REQUIRE_EQUAL (pingDatagram->typeName (), " Ping" );
1219+ auto ping = dynamic_cast <PingNode const &>(*pingDatagram);
1220+
1221+ // send PONG
1222+ Pong pong{nodeTable->m_hostNodeEndpoint };
1223+ pong.echo = ping.echo ;
1224+ pong.sign (nodeKeyPair.secret ());
1225+ nodeSocketHost2.socket ->send (pong);
1226+
1227+ // wait for PONG to be received and handled
1228+ auto pongDataReceived = nodeTable->packetsReceived .pop (chrono::seconds (5 ));
1229+ auto pongDatagram =
1230+ DiscoveryDatagram::interpretUDP (bi::udp::endpoint{}, dev::ref (pongDataReceived));
1231+ BOOST_REQUIRE_EQUAL (pongDatagram->typeName (), " Pong" );
1232+
1233+ BOOST_REQUIRE_EQUAL (nodeEntry->endpoint (), nodeEndpoint2);
1234+ }
1235+
1236+ BOOST_AUTO_TEST_CASE (findNode)
1237+ {
1238+ // Create and send the FindNode packet through endpoint 2
1239+ FindNode findNode{nodeTable->m_hostNodeEndpoint , KeyPair::create ().pub () /* target */ };
1240+ findNode.sign (nodeKeyPair.secret ());
1241+ nodeSocketHost2.socket ->send (findNode);
1242+
1243+ // Wait for FindNode to be received
1244+ auto findNodeDataReceived = nodeTable->packetsReceived .pop (chrono::seconds (5 ));
1245+ auto findNodeDatagram =
1246+ DiscoveryDatagram::interpretUDP (bi::udp::endpoint{}, dev::ref (findNodeDataReceived));
1247+ BOOST_REQUIRE_EQUAL (findNodeDatagram->typeName (), " FindNode" );
1248+
1249+ // Verify that no neighbours response is received
1250+ BOOST_CHECK_THROW (nodeSocketHost2.packetsReceived .pop (chrono::seconds (5 )), WaitTimeout);
1251+ }
1252+
1253+ BOOST_AUTO_TEST_CASE (neighbours)
1254+ {
1255+ // Wait for FindNode arriving to endpoint 1
1256+ auto findNodeDataReceived = nodeSocketHost1.packetsReceived .pop (chrono::seconds (10 ));
1257+ auto findNodeDatagram =
1258+ DiscoveryDatagram::interpretUDP (bi::udp::endpoint{}, dev::ref (findNodeDataReceived));
1259+ BOOST_REQUIRE_EQUAL (findNodeDatagram->typeName (), " FindNode" );
1260+ auto findNode = dynamic_cast <FindNode const &>(*findNodeDatagram);
1261+
1262+ // send Neighbours through endpoint 2
1263+ NodeIPEndpoint neighbourEndpoint{boost::asio::ip::address::from_string (" 200.200.200.200" ),
1264+ c_defaultListenPort, c_defaultListenPort};
1265+ vector<shared_ptr<NodeEntry>> nearest{
1266+ make_shared<NodeEntry>(nodeTable->m_hostNodeID , KeyPair::create ().pub (), neighbourEndpoint,
1267+ RLPXDatagramFace::secondsSinceEpoch (), 0 /* pongSentTime */ )};
1268+ Neighbours neighbours{nodeTable->m_hostNodeEndpoint , nearest};
1269+ neighbours.sign (nodeKeyPair.secret ());
1270+ nodeSocketHost2.socket ->send (neighbours);
1271+
1272+ // Wait for Neighbours to be received
1273+ auto neighboursDataReceived = nodeTable->packetsReceived .pop (chrono::seconds (5 ));
1274+ auto neighboursDatagram =
1275+ DiscoveryDatagram::interpretUDP (bi::udp::endpoint{}, dev::ref (neighboursDataReceived));
1276+ BOOST_REQUIRE_EQUAL (neighboursDatagram->typeName (), " Neighbours" );
1277+
1278+ // no Ping is sent to neighbour
1279+ auto sentPing = nodeTable->nodeValidation (neighbourEndpoint);
1280+ BOOST_REQUIRE (!sentPing.is_initialized ());
1281+ }
1282+
1283+ BOOST_AUTO_TEST_SUITE_END ()
11761284BOOST_AUTO_TEST_SUITE_END()
11771285
11781286BOOST_FIXTURE_TEST_SUITE(netTypes, TestOutputHelperFixture)
0 commit comments