@@ -593,3 +593,87 @@ func (br *ByzantineReactor) Receive(e p2p.Envelope) {
593593}
594594
595595func (* ByzantineReactor ) InitPeer (peer p2p.Peer ) p2p.Peer { return peer }
596+
597+ // Large/oversized proposals should be rejected.
598+ func TestRejectOversizedProposals (t * testing.T ) {
599+ ctx , cancel := context .WithCancel (context .Background ())
600+ defer cancel ()
601+
602+ n := 2
603+ css , cleanup := randConsensusNet (t , n , "consensus_reactor_test" , newMockTickerFunc (false ), newKVStore )
604+ defer cleanup ()
605+
606+ switches := make ([]* p2p.Switch , n )
607+ p2pLogger := consensusLogger ().With ("module" , "p2p" )
608+ for i := 0 ; i < n ; i ++ {
609+ switches [i ] = p2p .MakeSwitch (
610+ config .P2P ,
611+ i ,
612+ func (_ int , sw * p2p.Switch ) * p2p.Switch {
613+ return sw
614+ })
615+ switches [i ].SetLogger (p2pLogger .With ("validator" , i ))
616+ }
617+
618+ reactors := make ([]p2p.Reactor , n )
619+ for i := 0 ; i < n ; i ++ {
620+ conR := NewReactor (css [i ], false )
621+ defer func () { require .NoError (t , conR .Stop ()) }()
622+
623+ conR .SetLogger (consensusLogger ().With ("validator" , i ))
624+ reactors [i ] = conR
625+ }
626+
627+ p2p .MakeConnectedSwitches (config .P2P , n , func (i int , _ * p2p.Switch ) * p2p.Switch {
628+ switches [i ].AddReactor ("CONSENSUS" , reactors [i ])
629+ return switches [i ]
630+ }, p2p .Connect2Switches )
631+
632+ peers := switches [0 ].Peers ().Copy ()
633+ require .NotEmpty (t , peers )
634+ targetPeer := peers [0 ]
635+
636+ height := int64 (1 )
637+ round := int32 (0 )
638+ cs := css [0 ]
639+
640+ block , err := cs .createProposalBlock (ctx )
641+ require .NoError (t , err )
642+
643+ blockParts , err := block .MakePartSet (types .BlockPartSizeBytes )
644+ require .NoError (t , err )
645+
646+ // create oversized proposal
647+ propBlockID := types.BlockID {Hash : block .Hash (), PartSetHeader : blockParts .Header ()}
648+ propBlockID .PartSetHeader .Total = 4294967295
649+
650+ proposal := types .NewProposal (height , round , - 1 , propBlockID , block .Header .Time )
651+ p := proposal .ToProto ()
652+ if err := cs .privValidator .SignProposal (cs .state .ChainID , p ); err != nil {
653+ t .Error (err )
654+ }
655+ proposal .Signature = p .Signature
656+
657+ success := targetPeer .Send (p2p.Envelope {
658+ ChannelID : DataChannel ,
659+ Message : & cmtcons.Proposal {Proposal : * proposal .ToProto ()},
660+ })
661+ require .True (t , success )
662+
663+ select {
664+ case e := <- css [1 ].peerMsgQueue :
665+ // if we receive a message here, the peer incorrectly accepted the
666+ // oversized proposal
667+ if _ , receivedProposal := e .Msg .(* ProposalMessage ); receivedProposal {
668+ assert .Fail (t , "peer incorrectly accepted oversized proposal" )
669+ return
670+ }
671+ // invalid state, we received some other unexpected message type, fail
672+ // the test
673+ assert .Fail (t , "received unexpected message type on peer msg queue, expected *ProposalMessage" )
674+ case <- ctx .Done ():
675+ case <- time .After (500 * time .Millisecond ):
676+ // timeout after 500ms if nothing has happened and assume peer rejected
677+ // the proposal
678+ }
679+ }
0 commit comments