github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/types/vote_test.go (about)

     1  package types
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/gogo/protobuf/proto"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/ari-anchor/sei-tendermint/crypto"
    13  	"github.com/ari-anchor/sei-tendermint/crypto/ed25519"
    14  	"github.com/ari-anchor/sei-tendermint/internal/libs/protoio"
    15  	tmtime "github.com/ari-anchor/sei-tendermint/libs/time"
    16  	tmproto "github.com/ari-anchor/sei-tendermint/proto/tendermint/types"
    17  )
    18  
    19  func examplePrevote(t *testing.T) *Vote {
    20  	t.Helper()
    21  	return exampleVote(t, byte(tmproto.PrevoteType))
    22  }
    23  
    24  func examplePrecommit(t testing.TB) *Vote {
    25  	t.Helper()
    26  	vote := exampleVote(t, byte(tmproto.PrecommitType))
    27  	vote.ExtensionSignature = []byte("signature")
    28  	return vote
    29  }
    30  
    31  func exampleVote(tb testing.TB, t byte) *Vote {
    32  	tb.Helper()
    33  	var stamp, err = time.Parse(TimeFormat, "2017-12-25T03:00:01.234Z")
    34  	require.NoError(tb, err)
    35  
    36  	return &Vote{
    37  		Type:      tmproto.SignedMsgType(t),
    38  		Height:    12345,
    39  		Round:     2,
    40  		Timestamp: stamp,
    41  		BlockID: BlockID{
    42  			Hash: crypto.Checksum([]byte("blockID_hash")),
    43  			PartSetHeader: PartSetHeader{
    44  				Total: 1000000,
    45  				Hash:  crypto.Checksum([]byte("blockID_part_set_header_hash")),
    46  			},
    47  		},
    48  		ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
    49  		ValidatorIndex:   56789,
    50  	}
    51  }
    52  
    53  func TestVoteSignable(t *testing.T) {
    54  	vote := examplePrecommit(t)
    55  	v := vote.ToProto()
    56  	signBytes := VoteSignBytes("test_chain_id", v)
    57  	pb := CanonicalizeVote("test_chain_id", v)
    58  	expected, err := protoio.MarshalDelimited(&pb)
    59  	require.NoError(t, err)
    60  
    61  	require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Vote.")
    62  }
    63  
    64  func TestVoteSignBytesTestVectors(t *testing.T) {
    65  
    66  	tests := []struct {
    67  		chainID string
    68  		vote    *Vote
    69  		want    []byte
    70  	}{
    71  		0: {
    72  			"", &Vote{},
    73  			// NOTE: Height and Round are skipped here. This case needs to be considered while parsing.
    74  			[]byte{0xd, 0x2a, 0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
    75  		},
    76  		// with proper (fixed size) height and round (PreCommit):
    77  		1: {
    78  			"", &Vote{Height: 1, Round: 1, Type: tmproto.PrecommitType},
    79  			[]byte{
    80  				0x21,                                   // length
    81  				0x8,                                    // (field_number << 3) | wire_type
    82  				0x2,                                    // PrecommitType
    83  				0x11,                                   // (field_number << 3) | wire_type
    84  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
    85  				0x19,                                   // (field_number << 3) | wire_type
    86  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
    87  				0x2a, // (field_number << 3) | wire_type
    88  				// remaining fields (timestamp):
    89  				0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
    90  		},
    91  		// with proper (fixed size) height and round (PreVote):
    92  		2: {
    93  			"", &Vote{Height: 1, Round: 1, Type: tmproto.PrevoteType},
    94  			[]byte{
    95  				0x21,                                   // length
    96  				0x8,                                    // (field_number << 3) | wire_type
    97  				0x1,                                    // PrevoteType
    98  				0x11,                                   // (field_number << 3) | wire_type
    99  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
   100  				0x19,                                   // (field_number << 3) | wire_type
   101  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
   102  				0x2a, // (field_number << 3) | wire_type
   103  				// remaining fields (timestamp):
   104  				0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
   105  		},
   106  		3: {
   107  			"", &Vote{Height: 1, Round: 1},
   108  			[]byte{
   109  				0x1f,                                   // length
   110  				0x11,                                   // (field_number << 3) | wire_type
   111  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
   112  				0x19,                                   // (field_number << 3) | wire_type
   113  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
   114  				// remaining fields (timestamp):
   115  				0x2a,
   116  				0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1},
   117  		},
   118  		// containing non-empty chain_id:
   119  		4: {
   120  			"test_chain_id", &Vote{Height: 1, Round: 1},
   121  			[]byte{
   122  				0x2e,                                   // length
   123  				0x11,                                   // (field_number << 3) | wire_type
   124  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
   125  				0x19,                                   // (field_number << 3) | wire_type
   126  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
   127  				// remaining fields:
   128  				0x2a,                                                                // (field_number << 3) | wire_type
   129  				0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1, // timestamp
   130  				// (field_number << 3) | wire_type
   131  				0x32,
   132  				0xd, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64}, // chainID
   133  		},
   134  		// containing vote extension
   135  		5: {
   136  			"test_chain_id", &Vote{
   137  				Height:    1,
   138  				Round:     1,
   139  				Extension: []byte("extension"),
   140  			},
   141  			[]byte{
   142  				0x2e,                                   // length
   143  				0x11,                                   // (field_number << 3) | wire_type
   144  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // height
   145  				0x19,                                   // (field_number << 3) | wire_type
   146  				0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // round
   147  				// remaning fields:
   148  				0x2a,                                                                // (field_number << 3) | wire_type
   149  				0xb, 0x8, 0x80, 0x92, 0xb8, 0xc3, 0x98, 0xfe, 0xff, 0xff, 0xff, 0x1, // timestamp
   150  				// (field_number << 3) | wire_type
   151  				0x32,
   152  				0xd, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, // chainID
   153  			}, // chainID
   154  		},
   155  	}
   156  	for i, tc := range tests {
   157  		v := tc.vote.ToProto()
   158  		got := VoteSignBytes(tc.chainID, v)
   159  		assert.Equal(t, len(tc.want), len(got), "test case #%v: got unexpected sign bytes length for Vote.", i)
   160  		assert.Equal(t, tc.want, got, "test case #%v: got unexpected sign bytes for Vote.", i)
   161  	}
   162  }
   163  
   164  func TestVoteProposalNotEq(t *testing.T) {
   165  	cv := CanonicalizeVote("", &tmproto.Vote{Height: 1, Round: 1})
   166  	p := CanonicalizeProposal("", &tmproto.Proposal{Height: 1, Round: 1})
   167  	vb, err := proto.Marshal(&cv)
   168  	require.NoError(t, err)
   169  	pb, err := proto.Marshal(&p)
   170  	require.NoError(t, err)
   171  	require.NotEqual(t, vb, pb)
   172  }
   173  
   174  func TestVoteVerifySignature(t *testing.T) {
   175  	ctx, cancel := context.WithCancel(context.Background())
   176  	defer cancel()
   177  
   178  	privVal := NewMockPV()
   179  	pubkey, err := privVal.GetPubKey(ctx)
   180  	require.NoError(t, err)
   181  
   182  	vote := examplePrecommit(t)
   183  	v := vote.ToProto()
   184  	signBytes := VoteSignBytes("test_chain_id", v)
   185  
   186  	// sign it
   187  	err = privVal.SignVote(ctx, "test_chain_id", v)
   188  	require.NoError(t, err)
   189  
   190  	// verify the same vote
   191  	valid := pubkey.VerifySignature(VoteSignBytes("test_chain_id", v), v.Signature)
   192  	require.True(t, valid)
   193  
   194  	// serialize, deserialize and verify again....
   195  	precommit := new(tmproto.Vote)
   196  	bs, err := proto.Marshal(v)
   197  	require.NoError(t, err)
   198  	err = proto.Unmarshal(bs, precommit)
   199  	require.NoError(t, err)
   200  
   201  	// verify the transmitted vote
   202  	newSignBytes := VoteSignBytes("test_chain_id", precommit)
   203  	require.Equal(t, string(signBytes), string(newSignBytes))
   204  	valid = pubkey.VerifySignature(newSignBytes, precommit.Signature)
   205  	require.True(t, valid)
   206  }
   207  
   208  // TestVoteExtension tests that the vote verification behaves correctly in each case
   209  // of vote extension being set on the vote.
   210  func TestVoteExtension(t *testing.T) {
   211  	ctx, cancel := context.WithCancel(context.Background())
   212  	defer cancel()
   213  
   214  	testCases := []struct {
   215  		name             string
   216  		extension        []byte
   217  		includeSignature bool
   218  		expectError      bool
   219  	}{
   220  		{
   221  			name:             "all fields present",
   222  			extension:        []byte("extension"),
   223  			includeSignature: true,
   224  			expectError:      false,
   225  		},
   226  		{
   227  			name:             "no extension signature",
   228  			extension:        []byte("extension"),
   229  			includeSignature: false,
   230  			expectError:      true,
   231  		},
   232  		{
   233  			name:             "empty extension",
   234  			includeSignature: true,
   235  			expectError:      false,
   236  		},
   237  		{
   238  			name:             "no extension and no signature",
   239  			includeSignature: false,
   240  			expectError:      true,
   241  		},
   242  	}
   243  
   244  	for _, tc := range testCases {
   245  		t.Run(tc.name, func(t *testing.T) {
   246  			height, round := int64(1), int32(0)
   247  			privVal := NewMockPV()
   248  			pk, err := privVal.GetPubKey(ctx)
   249  			require.NoError(t, err)
   250  			blk := Block{}
   251  			ps, err := blk.MakePartSet(BlockPartSizeBytes)
   252  			require.NoError(t, err)
   253  			vote := &Vote{
   254  				ValidatorAddress: pk.Address(),
   255  				ValidatorIndex:   0,
   256  				Height:           height,
   257  				Round:            round,
   258  				Timestamp:        tmtime.Now(),
   259  				Type:             tmproto.PrecommitType,
   260  				BlockID:          BlockID{blk.Hash(), ps.Header()},
   261  			}
   262  
   263  			v := vote.ToProto()
   264  			err = privVal.SignVote(ctx, "test_chain_id", v)
   265  			require.NoError(t, err)
   266  			vote.Signature = v.Signature
   267  			if tc.includeSignature {
   268  				vote.ExtensionSignature = v.ExtensionSignature
   269  			}
   270  			err = vote.VerifyExtension("test_chain_id", pk)
   271  			if tc.expectError {
   272  				require.Error(t, err)
   273  			} else {
   274  				require.NoError(t, err)
   275  			}
   276  		})
   277  	}
   278  }
   279  
   280  func TestIsVoteTypeValid(t *testing.T) {
   281  	tc := []struct {
   282  		name string
   283  		in   tmproto.SignedMsgType
   284  		out  bool
   285  	}{
   286  		{"Prevote", tmproto.PrevoteType, true},
   287  		{"Precommit", tmproto.PrecommitType, true},
   288  		{"InvalidType", tmproto.SignedMsgType(0x3), false},
   289  	}
   290  
   291  	for _, tt := range tc {
   292  		tt := tt
   293  		t.Run(tt.name, func(st *testing.T) {
   294  			if rs := IsVoteTypeValid(tt.in); rs != tt.out {
   295  				t.Errorf("got unexpected Vote type. Expected:\n%v\nGot:\n%v", rs, tt.out)
   296  			}
   297  		})
   298  	}
   299  }
   300  
   301  func TestVoteVerify(t *testing.T) {
   302  	ctx, cancel := context.WithCancel(context.Background())
   303  	defer cancel()
   304  
   305  	privVal := NewMockPV()
   306  	pubkey, err := privVal.GetPubKey(ctx)
   307  	require.NoError(t, err)
   308  
   309  	vote := examplePrevote(t)
   310  	vote.ValidatorAddress = pubkey.Address()
   311  
   312  	err = vote.Verify("test_chain_id", ed25519.GenPrivKey().PubKey())
   313  	if assert.Error(t, err) {
   314  		assert.Equal(t, ErrVoteInvalidValidatorAddress, err)
   315  	}
   316  
   317  	err = vote.Verify("test_chain_id", pubkey)
   318  	if assert.Error(t, err) {
   319  		assert.Equal(t, ErrVoteInvalidSignature, err)
   320  	}
   321  }
   322  
   323  func TestVoteString(t *testing.T) {
   324  	str := examplePrecommit(t).String()
   325  	expected := `Vote{index=56789:6AF1F4111082EFB388211BC72C55BCD61E9AC3D5 12345/02/SIGNED_MSG_TYPE_PRECOMMIT(Precommit) 8B01023386C3 000000000000 000000000000 @ 2017-12-25T03:00:01.234Z}` //nolint:lll //ignore line length for tests
   326  	if str != expected {
   327  		t.Errorf("got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str)
   328  	}
   329  
   330  	str2 := examplePrevote(t).String()
   331  	expected = `Vote{index=56789:6AF1F4111082EFB388211BC72C55BCD61E9AC3D5 12345/02/SIGNED_MSG_TYPE_PREVOTE(Prevote) 8B01023386C3 000000000000 000000000000 @ 2017-12-25T03:00:01.234Z}` //nolint:lll //ignore line length for tests
   332  	if str2 != expected {
   333  		t.Errorf("got unexpected string for Vote. Expected:\n%v\nGot:\n%v", expected, str2)
   334  	}
   335  }
   336  
   337  func signVote(ctx context.Context, t *testing.T, pv PrivValidator, chainID string, vote *Vote) {
   338  	t.Helper()
   339  
   340  	v := vote.ToProto()
   341  	require.NoError(t, pv.SignVote(ctx, chainID, v))
   342  	vote.Signature = v.Signature
   343  	vote.ExtensionSignature = v.ExtensionSignature
   344  }
   345  
   346  func TestValidVotes(t *testing.T) {
   347  	ctx, cancel := context.WithCancel(context.Background())
   348  	defer cancel()
   349  	privVal := NewMockPV()
   350  
   351  	testCases := []struct {
   352  		name         string
   353  		vote         *Vote
   354  		malleateVote func(*Vote)
   355  	}{
   356  		{"good prevote", examplePrevote(t), func(v *Vote) {}},
   357  		{"good precommit without vote extension", examplePrecommit(t), func(v *Vote) { v.Extension = nil }},
   358  		{"good precommit with vote extension", examplePrecommit(t), func(v *Vote) { v.Extension = []byte("extension") }},
   359  	}
   360  	for _, tc := range testCases {
   361  		signVote(ctx, t, privVal, "test_chain_id", tc.vote)
   362  		tc.malleateVote(tc.vote)
   363  		require.NoError(t, tc.vote.ValidateBasic(), "ValidateBasic for %s", tc.name)
   364  		require.NoError(t, tc.vote.EnsureExtension(), "EnsureExtension for %s", tc.name)
   365  	}
   366  }
   367  
   368  func TestInvalidVotes(t *testing.T) {
   369  	ctx, cancel := context.WithCancel(context.Background())
   370  	defer cancel()
   371  	privVal := NewMockPV()
   372  
   373  	testCases := []struct {
   374  		name         string
   375  		malleateVote func(*Vote)
   376  	}{
   377  		{"negative height", func(v *Vote) { v.Height = -1 }},
   378  		{"negative round", func(v *Vote) { v.Round = -1 }},
   379  		{"invalid block ID", func(v *Vote) { v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }},
   380  		{"invalid address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }},
   381  		{"invalid validator index", func(v *Vote) { v.ValidatorIndex = -1 }},
   382  		{"invalid signature", func(v *Vote) { v.Signature = nil }},
   383  		{"oversized signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }},
   384  	}
   385  	for _, tc := range testCases {
   386  		prevote := examplePrevote(t)
   387  		signVote(ctx, t, privVal, "test_chain_id", prevote)
   388  		tc.malleateVote(prevote)
   389  		require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s in invalid prevote", tc.name)
   390  		require.NoError(t, prevote.EnsureExtension(), "EnsureExtension for %s in invalid prevote", tc.name)
   391  
   392  		precommit := examplePrecommit(t)
   393  		signVote(ctx, t, privVal, "test_chain_id", precommit)
   394  		tc.malleateVote(precommit)
   395  		require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s in invalid precommit", tc.name)
   396  		require.NoError(t, precommit.EnsureExtension(), "EnsureExtension for %s in invalid precommit", tc.name)
   397  	}
   398  }
   399  
   400  func TestInvalidPrevotes(t *testing.T) {
   401  	ctx, cancel := context.WithCancel(context.Background())
   402  	defer cancel()
   403  	privVal := NewMockPV()
   404  
   405  	testCases := []struct {
   406  		name         string
   407  		malleateVote func(*Vote)
   408  	}{
   409  		{"vote extension present", func(v *Vote) { v.Extension = []byte("extension") }},
   410  		{"vote extension signature present", func(v *Vote) { v.ExtensionSignature = []byte("signature") }},
   411  	}
   412  	for _, tc := range testCases {
   413  		prevote := examplePrevote(t)
   414  		signVote(ctx, t, privVal, "test_chain_id", prevote)
   415  		tc.malleateVote(prevote)
   416  		require.Error(t, prevote.ValidateBasic(), "ValidateBasic for %s", tc.name)
   417  		require.NoError(t, prevote.EnsureExtension(), "EnsureExtension for %s", tc.name)
   418  	}
   419  }
   420  
   421  func TestInvalidPrecommitExtensions(t *testing.T) {
   422  	ctx, cancel := context.WithCancel(context.Background())
   423  	defer cancel()
   424  	privVal := NewMockPV()
   425  
   426  	testCases := []struct {
   427  		name         string
   428  		malleateVote func(*Vote)
   429  	}{
   430  		{"vote extension present without signature", func(v *Vote) {
   431  			v.Extension = []byte("extension")
   432  			v.ExtensionSignature = nil
   433  		}},
   434  		{"oversized vote extension signature", func(v *Vote) { v.ExtensionSignature = make([]byte, MaxSignatureSize+1) }},
   435  	}
   436  	for _, tc := range testCases {
   437  		precommit := examplePrecommit(t)
   438  		signVote(ctx, t, privVal, "test_chain_id", precommit)
   439  		tc.malleateVote(precommit)
   440  		// ValidateBasic ensures that vote extensions, if present, are well formed
   441  		require.Error(t, precommit.ValidateBasic(), "ValidateBasic for %s", tc.name)
   442  	}
   443  }
   444  
   445  func TestEnsureVoteExtension(t *testing.T) {
   446  	ctx, cancel := context.WithCancel(context.Background())
   447  	defer cancel()
   448  	privVal := NewMockPV()
   449  
   450  	testCases := []struct {
   451  		name         string
   452  		malleateVote func(*Vote)
   453  		expectError  bool
   454  	}{
   455  		{"vote extension signature absent", func(v *Vote) {
   456  			v.Extension = nil
   457  			v.ExtensionSignature = nil
   458  		}, true},
   459  		{"vote extension signature present", func(v *Vote) {
   460  			v.ExtensionSignature = []byte("extension signature")
   461  		}, false},
   462  	}
   463  	for _, tc := range testCases {
   464  		precommit := examplePrecommit(t)
   465  		signVote(ctx, t, privVal, "test_chain_id", precommit)
   466  		tc.malleateVote(precommit)
   467  		if tc.expectError {
   468  			require.Error(t, precommit.EnsureExtension(), "EnsureExtension for %s", tc.name)
   469  		} else {
   470  			require.NoError(t, precommit.EnsureExtension(), "EnsureExtension for %s", tc.name)
   471  		}
   472  	}
   473  }
   474  
   475  func TestVoteProtobuf(t *testing.T) {
   476  	ctx, cancel := context.WithCancel(context.Background())
   477  	defer cancel()
   478  
   479  	privVal := NewMockPV()
   480  	vote := examplePrecommit(t)
   481  	v := vote.ToProto()
   482  	err := privVal.SignVote(ctx, "test_chain_id", v)
   483  	vote.Signature = v.Signature
   484  	require.NoError(t, err)
   485  
   486  	testCases := []struct {
   487  		msg                 string
   488  		vote                *Vote
   489  		convertsOk          bool
   490  		passesValidateBasic bool
   491  	}{
   492  		{"success", vote, true, true},
   493  		{"fail vote validate basic", &Vote{}, true, false},
   494  	}
   495  	for _, tc := range testCases {
   496  		protoProposal := tc.vote.ToProto()
   497  
   498  		v, err := VoteFromProto(protoProposal)
   499  		if tc.convertsOk {
   500  			require.NoError(t, err)
   501  		} else {
   502  			require.Error(t, err)
   503  		}
   504  
   505  		err = v.ValidateBasic()
   506  		if tc.passesValidateBasic {
   507  			require.NoError(t, err)
   508  			require.Equal(t, tc.vote, v, tc.msg)
   509  		} else {
   510  			require.Error(t, err)
   511  		}
   512  	}
   513  }
   514  
   515  var sink interface{}
   516  
   517  func getSampleCommit(ctx context.Context, t testing.TB) *Commit {
   518  	t.Helper()
   519  
   520  	lastID := makeBlockIDRandom()
   521  	voteSet, _, vals := randVoteSet(ctx, t, 2, 1, tmproto.PrecommitType, 10, 1)
   522  	commit, err := makeExtCommit(ctx, lastID, 2, 1, voteSet, vals, time.Now())
   523  
   524  	require.NoError(t, err)
   525  
   526  	return commit.ToCommit()
   527  }
   528  
   529  func BenchmarkVoteSignBytes(b *testing.B) {
   530  	protoVote := examplePrecommit(b).ToProto()
   531  
   532  	b.ReportAllocs()
   533  	b.ResetTimer()
   534  
   535  	for i := 0; i < b.N; i++ {
   536  		sink = VoteSignBytes("test_chain_id", protoVote)
   537  	}
   538  
   539  	if sink == nil {
   540  		b.Fatal("Benchmark did not run")
   541  	}
   542  
   543  	// Reset the sink.
   544  	sink = (interface{})(nil)
   545  }
   546  
   547  func BenchmarkCommitVoteSignBytes(b *testing.B) {
   548  	ctx, cancel := context.WithCancel(context.Background())
   549  	defer cancel()
   550  
   551  	sampleCommit := getSampleCommit(ctx, b)
   552  
   553  	b.ReportAllocs()
   554  	b.ResetTimer()
   555  
   556  	for i := 0; i < b.N; i++ {
   557  		for index := range sampleCommit.Signatures {
   558  			sink = sampleCommit.VoteSignBytes("test_chain_id", int32(index))
   559  		}
   560  	}
   561  
   562  	if sink == nil {
   563  		b.Fatal("Benchmark did not run")
   564  	}
   565  
   566  	// Reset the sink.
   567  	sink = (interface{})(nil)
   568  }