github.com/evdatsion/aphelion-dpos-bft@v0.32.1/types/proposal_test.go (about) 1 package types 2 3 import ( 4 "math" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 "github.com/evdatsion/aphelion-dpos-bft/crypto/tmhash" 11 ) 12 13 var testProposal *Proposal 14 15 func init() { 16 var stamp, err = time.Parse(TimeFormat, "2018-02-11T07:09:22.765Z") 17 if err != nil { 18 panic(err) 19 } 20 testProposal = &Proposal{ 21 Height: 12345, 22 Round: 23456, 23 BlockID: BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}}, 24 POLRound: -1, 25 Timestamp: stamp, 26 } 27 } 28 29 func TestProposalSignable(t *testing.T) { 30 chainID := "test_chain_id" 31 signBytes := testProposal.SignBytes(chainID) 32 33 expected, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeProposal(chainID, testProposal)) 34 require.NoError(t, err) 35 require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Proposal") 36 } 37 38 func TestProposalString(t *testing.T) { 39 str := testProposal.String() 40 expected := `Proposal{12345/23456 (010203:111:626C6F636B70, -1) 000000000000 @ 2018-02-11T07:09:22.765Z}` 41 if str != expected { 42 t.Errorf("Got unexpected string for Proposal. Expected:\n%v\nGot:\n%v", expected, str) 43 } 44 } 45 46 func TestProposalVerifySignature(t *testing.T) { 47 privVal := NewMockPV() 48 pubKey := privVal.GetPubKey() 49 50 prop := NewProposal( 51 4, 2, 2, 52 BlockID{[]byte{1, 2, 3}, PartSetHeader{777, []byte("proper")}}) 53 signBytes := prop.SignBytes("test_chain_id") 54 55 // sign it 56 err := privVal.SignProposal("test_chain_id", prop) 57 require.NoError(t, err) 58 59 // verify the same proposal 60 valid := pubKey.VerifyBytes(signBytes, prop.Signature) 61 require.True(t, valid) 62 63 // serialize, deserialize and verify again.... 64 newProp := new(Proposal) 65 bs, err := cdc.MarshalBinaryLengthPrefixed(prop) 66 require.NoError(t, err) 67 err = cdc.UnmarshalBinaryLengthPrefixed(bs, &newProp) 68 require.NoError(t, err) 69 70 // verify the transmitted proposal 71 newSignBytes := newProp.SignBytes("test_chain_id") 72 require.Equal(t, string(signBytes), string(newSignBytes)) 73 valid = pubKey.VerifyBytes(newSignBytes, newProp.Signature) 74 require.True(t, valid) 75 } 76 77 func BenchmarkProposalWriteSignBytes(b *testing.B) { 78 for i := 0; i < b.N; i++ { 79 testProposal.SignBytes("test_chain_id") 80 } 81 } 82 83 func BenchmarkProposalSign(b *testing.B) { 84 privVal := NewMockPV() 85 for i := 0; i < b.N; i++ { 86 err := privVal.SignProposal("test_chain_id", testProposal) 87 if err != nil { 88 b.Error(err) 89 } 90 } 91 } 92 93 func BenchmarkProposalVerifySignature(b *testing.B) { 94 privVal := NewMockPV() 95 err := privVal.SignProposal("test_chain_id", testProposal) 96 require.Nil(b, err) 97 pubKey := privVal.GetPubKey() 98 99 for i := 0; i < b.N; i++ { 100 pubKey.VerifyBytes(testProposal.SignBytes("test_chain_id"), testProposal.Signature) 101 } 102 } 103 104 func TestProposalValidateBasic(t *testing.T) { 105 106 privVal := NewMockPV() 107 testCases := []struct { 108 testName string 109 malleateProposal func(*Proposal) 110 expectErr bool 111 }{ 112 {"Good Proposal", func(p *Proposal) {}, false}, 113 {"Invalid Type", func(p *Proposal) { p.Type = PrecommitType }, true}, 114 {"Invalid Height", func(p *Proposal) { p.Height = -1 }, true}, 115 {"Invalid Round", func(p *Proposal) { p.Round = -1 }, true}, 116 {"Invalid POLRound", func(p *Proposal) { p.POLRound = -2 }, true}, 117 {"Invalid BlockId", func(p *Proposal) { 118 p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} 119 }, true}, 120 {"Invalid Signature", func(p *Proposal) { 121 p.Signature = make([]byte, 0) 122 }, true}, 123 {"Too big Signature", func(p *Proposal) { 124 p.Signature = make([]byte, MaxSignatureSize+1) 125 }, true}, 126 } 127 blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt64, tmhash.Sum([]byte("partshash"))) 128 129 for _, tc := range testCases { 130 t.Run(tc.testName, func(t *testing.T) { 131 prop := NewProposal( 132 4, 2, 2, 133 blockID) 134 err := privVal.SignProposal("test_chain_id", prop) 135 require.NoError(t, err) 136 tc.malleateProposal(prop) 137 assert.Equal(t, tc.expectErr, prop.ValidateBasic() != nil, "Validate Basic had an unexpected result") 138 }) 139 } 140 }