@@ -91,7 +91,7 @@ class GossipV1_1Tests : GossipTestsBase() {
9191
9292 val api = createPubsubApi(test.gossipRouter)
9393 val apiMessages = mutableListOf<MessageApi >()
94- api.subscribe(Subscriber { apiMessages + = it }, io.libp2p.core.pubsub. Topic (" topic2" ))
94+ api.subscribe(Subscriber { apiMessages + = it }, Topic (" topic2" ))
9595
9696 val msg1 = Rpc .RPC .newBuilder()
9797 .addPublish(newProtoMessage(" topic2" , 0L , " Hello-1" .toByteArray()))
@@ -131,7 +131,7 @@ class GossipV1_1Tests : GossipTestsBase() {
131131
132132 val api = createPubsubApi(test.gossipRouter)
133133 val apiMessages = mutableListOf<MessageApi >()
134- api.subscribe(Subscriber { apiMessages + = it }, io.libp2p.core.pubsub. Topic (" topic1" ))
134+ api.subscribe(Subscriber { apiMessages + = it }, Topic (" topic1" ))
135135
136136 val msg1 = Rpc .RPC .newBuilder()
137137 .addPublish(newProtoMessage(" topic1" , 0L , " Hello-1" .toByteArray()))
@@ -653,7 +653,7 @@ class GossipV1_1Tests : GossipTestsBase() {
653653 3 ,
654654 3 ,
655655 DLazy = 3 ,
656- floodPublishMaxMessageSizeThreshold = 0 ,
656+ floodPublishMaxMessageSizeThreshold = NEVER_FLOOD_PUBLISH ,
657657 gossipFactor = 0.5
658658 )
659659 val peerScoreParams = GossipPeerScoreParams (
@@ -936,7 +936,7 @@ class GossipV1_1Tests : GossipTestsBase() {
936936 receivedMessages + = it
937937 validationResult
938938 }
939- api.subscribe(slowValidator, io.libp2p.core.pubsub. Topic (" topic1" ))
939+ api.subscribe(slowValidator, Topic (" topic1" ))
940940 test.mockRouters.forEach { it.subscribe(" topic1" ) }
941941
942942 val gossiper = test.mockRouters[0 ]
@@ -1307,6 +1307,106 @@ class GossipV1_1Tests : GossipTestsBase() {
13071307 assertTrue(peersReceivedMessage.containsAll(goodScoredPeers))
13081308 }
13091309
1310+ @Test
1311+ fun `should always flood publish to subscribed direct peers` () {
1312+ val message = newMessage(" topic1" , 0L , " Hello-0" .toByteArray())
1313+ val appScore = mutableMapOf<PeerId , Double >().withDefault { 0.0 }
1314+ val directPeers = mutableSetOf<PeerId >()
1315+ val coreParams = GossipParams (3 , 3 , 3 , floodPublishMaxMessageSizeThreshold = ALWAYS_FLOOD_PUBLISH )
1316+ val peerScoreParams = GossipPeerScoreParams (
1317+ appSpecificScore = { appScore.getValue(it) },
1318+ appSpecificWeight = 1.0 ,
1319+ isDirect = { directPeers.contains(it) }
1320+ )
1321+ val scoreParams = GossipScoreParams (
1322+ peerScoreParams = peerScoreParams,
1323+ graylistThreshold = - 15.0 ,
1324+ publishThreshold = - 10.0 ,
1325+ )
1326+ val test = ManyRoutersTest (mockRouterCount = 10 , params = coreParams, scoreParams = scoreParams)
1327+ test.connectAll()
1328+
1329+ test.gossipRouter.subscribe(" topic1" )
1330+ test.routers.slice(0 .. 5 ).forEach {
1331+ it.router.subscribe(" topic1" )
1332+ }
1333+
1334+ test.routers.slice(1 .. 6 ).forEach {
1335+ directPeers.add(it.peerId)
1336+ }
1337+
1338+ // now only peers from 1 to 5 are direct peers subscribed to the topic
1339+
1340+ test.fuzz.timeController.addTime(2 .seconds)
1341+
1342+ // let's down score all peers
1343+ test.routers.forEach {
1344+ appScore[it.peerId] = - 20.0
1345+ }
1346+ test.gossipRouter.publish(message)
1347+
1348+ test.fuzz.timeController.addTime(50 .millis)
1349+
1350+ val publishedCount = test.mockRouters.flatMap { it.inboundMessages }.count { it.publishCount > 0 }
1351+
1352+ // only subscribed direct peers should receive the message
1353+ assertEquals(5 , publishedCount)
1354+ }
1355+
1356+ @Test
1357+ fun `should always publish to subscribed direct peers` () {
1358+ val message = newMessage(" topic1" , 0L , " Hello-0" .toByteArray())
1359+ val appScore = mutableMapOf<PeerId , Double >().withDefault { 0.0 }
1360+ val directPeers = mutableSetOf<PeerId >()
1361+ val coreParams = GossipParams (3 , 3 , 3 , floodPublishMaxMessageSizeThreshold = NEVER_FLOOD_PUBLISH )
1362+ val peerScoreParams = GossipPeerScoreParams (
1363+ appSpecificScore = { appScore.getValue(it) },
1364+ appSpecificWeight = 1.0 ,
1365+ isDirect = { directPeers.contains(it) }
1366+ )
1367+ val scoreParams = GossipScoreParams (
1368+ peerScoreParams = peerScoreParams,
1369+ graylistThreshold = - 15.0 ,
1370+ publishThreshold = - 10.0 ,
1371+ )
1372+ val test = ManyRoutersTest (mockRouterCount = 10 , params = coreParams, scoreParams = scoreParams)
1373+ test.connectAll()
1374+
1375+ test.gossipRouter.subscribe(" topic1" )
1376+
1377+ test.routers.slice(0 .. 5 ).forEach {
1378+ it.router.subscribe(" topic1" )
1379+ }
1380+ test.routers.slice(1 .. 6 ).forEach {
1381+ directPeers.add(it.peerId)
1382+ }
1383+
1384+ // now only peers from 1 to 5 are direct peers subscribed to the topic
1385+ val subscribedDirectPeers = test.routers.slice(1 .. 5 ).map { it.peerId }
1386+
1387+ test.fuzz.timeController.addTime(2 .seconds)
1388+
1389+ // let's down score all direct peers
1390+ directPeers.forEach {
1391+ appScore[it] = - 20.0
1392+ }
1393+
1394+ val topicMeshRouters = test.gossipRouter.mesh[" topic1" ]!! .toList()
1395+
1396+ // the mesh is strictly smaller than the number of subscribed direct peers
1397+ assertTrue(topicMeshRouters.size < subscribedDirectPeers.size)
1398+
1399+ val expectedPublishedCount = topicMeshRouters.map { it.peerId }.plus(subscribedDirectPeers).distinct().size
1400+
1401+ test.gossipRouter.publish(message)
1402+
1403+ test.fuzz.timeController.addTime(50 .millis)
1404+
1405+ val publishedCount = test.mockRouters.flatMap { it.inboundMessages }.count { it.publishCount > 0 }
1406+
1407+ assertEquals(expectedPublishedCount, publishedCount)
1408+ }
1409+
13101410 private fun createGraftMessage (topic : String ): Rpc .RPC {
13111411 return Rpc .RPC .newBuilder().setControl(
13121412 Rpc .ControlMessage .newBuilder().addGraft(
0 commit comments