@@ -24,6 +24,7 @@ import (
2424 "encoding/json"
2525 "fmt"
2626 "io"
27+ "maps"
2728 "math/rand"
2829 "net"
2930 "net/http"
@@ -4773,3 +4774,125 @@ func TestPeerComparisonInBroadcast(t *testing.T) {
47734774 require .Equal (t , 1 , len (testPeer .sendBufferBulk ))
47744775 require .Equal (t , 0 , len (exceptPeer .sendBufferBulk ))
47754776}
4777+
4778+ func TestMaybeSendMessagesOfInterestLegacyPeer (t * testing.T ) {
4779+ partitiontest .PartitionTest (t )
4780+ t .Parallel ()
4781+
4782+ makePeer := func (wn * WebsocketNetwork , features peerFeatureFlag ) (* wsPeer , chan sendMessage ) {
4783+ ch := make (chan sendMessage , 1 )
4784+ return & wsPeer {
4785+ wsPeerCore : makePeerCore (wn .ctx , wn , wn .log , nil , "test-addr" , nil , "" ),
4786+ features : features ,
4787+ sendBufferHighPrio : ch ,
4788+ sendBufferBulk : make (chan sendMessage , 1 ),
4789+ closing : make (chan struct {}),
4790+ processed : make (chan struct {}, 1 ),
4791+ }, ch
4792+ }
4793+
4794+ newTestNetwork := func (tags map [protocol.Tag ]bool ) * WebsocketNetwork {
4795+ wn := & WebsocketNetwork {
4796+ log : logging .TestingLog (t ),
4797+ }
4798+ wn .ctx = context .Background ()
4799+ cloned := maps .Clone (tags )
4800+ wn .messagesOfInterest = cloned
4801+ wn .messagesOfInterestEnc = marshallMessageOfInterestMap (cloned )
4802+ wn .messagesOfInterestGeneration .Store (1 )
4803+ return wn
4804+ }
4805+
4806+ t .Run ("filters VP for peers without stateful support" , func (t * testing.T ) {
4807+ wn := newTestNetwork (map [protocol.Tag ]bool {
4808+ protocol .AgreementVoteTag : true ,
4809+ protocol .VotePackedTag : true ,
4810+ })
4811+
4812+ peer , ch := makePeer (wn , pfCompressedProposal | pfCompressedVoteVpack )
4813+ wn .maybeSendMessagesOfInterest (peer , nil )
4814+
4815+ select {
4816+ case msg := <- ch :
4817+ require .Equal (t , protocol .MsgOfInterestTag , protocol .Tag (msg .data [:2 ]))
4818+
4819+ decoded , err := unmarshallMessageOfInterest (msg .data [2 :])
4820+ require .NoError (t , err )
4821+
4822+ require .Contains (t , decoded , protocol .AgreementVoteTag )
4823+ require .True (t , decoded [protocol .AgreementVoteTag ])
4824+ _ , hasVP := decoded [protocol .VotePackedTag ]
4825+ require .False (t , hasVP , "VP tag should be filtered for legacy peers" )
4826+ default :
4827+ t .Fatal ("expected MOI message for legacy peer" )
4828+ }
4829+ })
4830+
4831+ t .Run ("retains VP for peers with stateful support" , func (t * testing.T ) {
4832+ wn := newTestNetwork (map [protocol.Tag ]bool {
4833+ protocol .AgreementVoteTag : true ,
4834+ protocol .VotePackedTag : true ,
4835+ })
4836+
4837+ peer , ch := makePeer (wn , pfCompressedProposal | pfCompressedVoteVpack | pfCompressedVoteVpackStateful256 )
4838+
4839+ wn .maybeSendMessagesOfInterest (peer , nil )
4840+
4841+ select {
4842+ case msg := <- ch :
4843+ require .Equal (t , protocol .MsgOfInterestTag , protocol .Tag (msg .data [:2 ]))
4844+
4845+ decoded , err := unmarshallMessageOfInterest (msg .data [2 :])
4846+ require .NoError (t , err )
4847+
4848+ require .Contains (t , decoded , protocol .AgreementVoteTag )
4849+ require .True (t , decoded [protocol .AgreementVoteTag ])
4850+ require .Contains (t , decoded , protocol .VotePackedTag )
4851+ require .True (t , decoded [protocol .VotePackedTag ], "expected VP tag for peer with stateful support" )
4852+ default :
4853+ t .Fatal ("expected MOI message for stateful peer" )
4854+ }
4855+ })
4856+
4857+ t .Run ("gracefully handles configuration without VP tag" , func (t * testing.T ) {
4858+ wn := newTestNetwork (map [protocol.Tag ]bool {
4859+ protocol .AgreementVoteTag : true ,
4860+ })
4861+
4862+ peer , ch := makePeer (wn , pfCompressedProposal | pfCompressedVoteVpack )
4863+ wn .maybeSendMessagesOfInterest (peer , nil )
4864+
4865+ select {
4866+ case msg := <- ch :
4867+ require .Equal (t , protocol .MsgOfInterestTag , protocol .Tag (msg .data [:2 ]))
4868+
4869+ decoded , err := unmarshallMessageOfInterest (msg .data [2 :])
4870+ require .NoError (t , err )
4871+
4872+ require .Contains (t , decoded , protocol .AgreementVoteTag )
4873+ require .True (t , decoded [protocol .AgreementVoteTag ])
4874+ _ , hasVP := decoded [protocol .VotePackedTag ]
4875+ require .False (t , hasVP )
4876+ default :
4877+ t .Fatal ("expected MOI message when VP is absent from configuration" )
4878+ }
4879+ })
4880+
4881+ t .Run ("skips sending when peer generation matches" , func (t * testing.T ) {
4882+ wn := newTestNetwork (map [protocol.Tag ]bool {
4883+ protocol .AgreementVoteTag : true ,
4884+ protocol .VotePackedTag : true ,
4885+ })
4886+
4887+ peer , ch := makePeer (wn , pfCompressedProposal | pfCompressedVoteVpack )
4888+ peer .messagesOfInterestGeneration .Store (wn .messagesOfInterestGeneration .Load ())
4889+
4890+ wn .maybeSendMessagesOfInterest (peer , nil )
4891+
4892+ select {
4893+ case <- ch :
4894+ t .Fatal ("did not expect MOI message when generations already match" )
4895+ default :
4896+ }
4897+ })
4898+ }
0 commit comments