@@ -62,15 +62,6 @@ func getGossipsubs(ctx context.Context, hs []host.Host, opts ...Option) []*PubSu
6262 return psubs
6363}
6464
65- func getGossipsubsOptFn (ctx context.Context , hs []host.Host , optFn func (int , host.Host ) []Option ) []* PubSub {
66- var psubs []* PubSub
67- for i , h := range hs {
68- opts := optFn (i , h )
69- psubs = append (psubs , getGossipsub (ctx , h , opts ... ))
70- }
71- return psubs
72- }
73-
7465func TestGossipSubParamsValidate (t * testing.T ) {
7566 params := DefaultGossipSubParams ()
7667 params .Dhi = 1
@@ -92,6 +83,15 @@ func TestGossipSubBootstrapParamsValidate(t *testing.T) {
9283 }
9384}
9485
86+ func getGossipsubsOptFn (ctx context.Context , hs []host.Host , optFn func (int , host.Host ) []Option ) []* PubSub {
87+ var psubs []* PubSub
88+ for i , h := range hs {
89+ opts := optFn (i , h )
90+ psubs = append (psubs , getGossipsub (ctx , h , opts ... ))
91+ }
92+ return psubs
93+ }
94+
9595func TestSparseGossipsub (t * testing.T ) {
9696 ctx , cancel := context .WithCancel (context .Background ())
9797 defer cancel ()
@@ -4685,3 +4685,112 @@ func TestPartialMessages(t *testing.T) {
46854685 }
46864686 }
46874687}
4688+
4689+ func TestSkipPublishingToPeersWithPartialMessageSupport (t * testing.T ) {
4690+ topicName := "test-topic"
4691+
4692+ // 3 hosts.
4693+ // hosts[0]: Publisher. Supports partial messages
4694+ // hosts[1]: Subscriber. Supports partial messages
4695+ // hosts[2]: Alternate publisher. Does not support partial messages. Only
4696+ // connected to hosts[0]
4697+ hosts := getDefaultHosts (t , 3 )
4698+
4699+ const hostsWithPartialMessageSupport = 2
4700+ partialExt := make ([]* partialmessages.PartialMessageExtension , hostsWithPartialMessageSupport )
4701+ // A list of maps from topic+groupID to partialMessage. One map per peer
4702+ partialMessageStore := make ([]map [string ]* minimalTestPartialMessage , hostsWithPartialMessageSupport )
4703+ for i := range hostsWithPartialMessageSupport {
4704+ partialMessageStore [i ] = make (map [string ]* minimalTestPartialMessage )
4705+ }
4706+
4707+ // Only hosts with partial message support
4708+ psubs := make ([]* PubSub , 0 , len (hosts )- 1 )
4709+
4710+ logger := slog .New (slog .NewTextHandler (os .Stderr , & slog.HandlerOptions {Level : slog .LevelDebug }))
4711+
4712+ for i := range partialExt {
4713+ partialExt [i ] = & partialmessages.PartialMessageExtension {
4714+ Logger : logger ,
4715+ ValidateRPC : func (from peer.ID , rpc * pb.PartialMessagesExtension ) error {
4716+ return nil
4717+ },
4718+ OnIncomingRPC : func (from peer.ID , topic string , groupID , iwant , ihave , partialMessageBytes []byte ) {
4719+ pm , ok := partialMessageStore [i ][topic + string (groupID )]
4720+ if ! ok {
4721+ pm = & minimalTestPartialMessage {
4722+ Group : groupID ,
4723+ }
4724+ partialMessageStore [i ][topic + string (groupID )] = pm
4725+ }
4726+ if publishOpts := pm .onIncomingRPC (from , topic , groupID , iwant , ihave , partialMessageBytes ); publishOpts != nil {
4727+ go psubs [i ].PublishPartialMessage (topic , pm , * publishOpts )
4728+ }
4729+ },
4730+ }
4731+ }
4732+
4733+ for i , h := range hosts [:2 ] {
4734+ psub := getGossipsub (context .Background (), h , WithPartialMessagesExtension (partialExt [i ]))
4735+ psubs = append (psubs , psub )
4736+ }
4737+
4738+ nonPartialPubsub := getGossipsub (context .Background (), hosts [2 ])
4739+
4740+ denseConnect (t , hosts [:2 ])
4741+ time .Sleep (2 * time .Second )
4742+
4743+ // Connect nonPartialPubsub to the publisher
4744+ connect (t , hosts [0 ], hosts [2 ])
4745+
4746+ var topics []* Topic
4747+ var subs []* Subscription
4748+ for _ , psub := range psubs {
4749+ topic , err := psub .Join (topicName , WithSkipPublishingToPartialMessageCapablePeers ())
4750+ if err != nil {
4751+ t .Fatal (err )
4752+ }
4753+ topics = append (topics , topic )
4754+ s , err := topic .Subscribe ()
4755+ if err != nil {
4756+ t .Fatal (err )
4757+ }
4758+ subs = append (subs , s )
4759+ }
4760+
4761+ topicForNonPartial , err := nonPartialPubsub .Join (topicName )
4762+ if err != nil {
4763+ t .Fatal (err )
4764+ }
4765+
4766+ // Wait for subscriptions to propagate
4767+ time .Sleep (time .Second )
4768+
4769+ topics [0 ].Publish (context .Background (), []byte ("Hello" ))
4770+
4771+ // Publish from another peer, the publisher (psub[0]) should not forward this to psub[1].
4772+ topicForNonPartial .Publish (context .Background (), []byte ("from non-partial" ))
4773+
4774+ recvdMessage := make (chan struct {}, 1 )
4775+ ctx , cancel := context .WithCancel (context .Background ())
4776+ defer cancel ()
4777+ go func () {
4778+ msg , err := subs [1 ].Next (ctx )
4779+ if err == context .Canceled {
4780+ return
4781+ }
4782+ if err != nil {
4783+ t .Log (err )
4784+ t .Fail ()
4785+ return
4786+ }
4787+ t .Log ("Received msg" , string (msg .Data ))
4788+ recvdMessage <- struct {}{}
4789+ }()
4790+
4791+ select {
4792+ case <- recvdMessage :
4793+ t .Fatal ("Received message" )
4794+ case <- time .After (2 * time .Second ):
4795+ }
4796+ }
0 commit comments